-
Notifications
You must be signed in to change notification settings - Fork 0
Simplify polling logic in ConnectionActor #164
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,7 +7,7 @@ | |
|
|
||
| use std::future::Future; | ||
|
|
||
| use futures::StreamExt; | ||
| use tokio::{ | ||
| sync::mpsc, | ||
| time::{Duration, Instant}, | ||
|
|
@@ -163,33 +163,11 @@ | |
| state: &mut ActorState, | ||
| out: &mut Vec<F>, | ||
| ) -> Result<(), WireframeError<E>> { | ||
| let high_available = self.high_rx.is_some(); | ||
| let low_available = self.low_rx.is_some(); | ||
| let resp_available = self.response.is_some(); | ||
|
|
||
| tokio::select! { | ||
| biased; | ||
|
|
||
| () = Self::wait_shutdown(self.shutdown.clone()), if state.is_active() => { | ||
| self.process_shutdown(state); | ||
| } | ||
|
|
||
| res = Self::poll_optional(self.high_rx.as_mut(), Self::recv_push), if high_available => { | ||
| self.process_high(res, state, out); | ||
| } | ||
|
|
||
| res = Self::poll_optional(self.low_rx.as_mut(), Self::recv_push), if low_available => { | ||
| self.process_low(res, state, out); | ||
| } | ||
|
|
||
| // `tokio::select!` is biased so the shutdown branch runs before | ||
| // this one. `process_shutdown` removes the response stream, making | ||
| // `resp_available` false on the next loop iteration. The explicit | ||
| // `!state.is_shutting_down()` check avoids polling the stream after | ||
| // shutdown has begun. | ||
| res = Self::poll_optional(self.response.as_mut(), |s| s.next()), if resp_available && !state.is_shutting_down() => { | ||
| self.process_response(res, state, out)?; | ||
| } | ||
| match self.next_event(state).await { | ||
| PollEvent::Shutdown => self.process_shutdown(state), | ||
| PollEvent::High(res) => self.process_high(res, state, out), | ||
| PollEvent::Low(res) => self.process_low(res, state, out), | ||
| PollEvent::Response(res) => self.process_response(res, state, out)?, | ||
| } | ||
|
|
||
| Ok(()) | ||
|
|
@@ -364,6 +342,37 @@ | |
| } | ||
| } | ||
| } | ||
|
|
||
| /// Determine which event should be processed next. | ||
| async fn next_event(&mut self, state: &ActorState) -> PollEvent<F, E> { | ||
| let high_available = self.high_rx.is_some(); | ||
| let low_available = self.low_rx.is_some(); | ||
| let resp_available = self.response.is_some() && !state.is_shutting_down(); | ||
|
|
||
| tokio::select! { | ||
| biased; | ||
|
|
||
| () = Self::wait_shutdown(self.shutdown.clone()), if state.is_active() => PollEvent::Shutdown, | ||
|
|
||
| res = Self::poll_receiver(self.high_rx.as_mut()), if high_available => PollEvent::High(res), | ||
|
|
||
| res = Self::poll_receiver(self.low_rx.as_mut()), if low_available => PollEvent::Low(res), | ||
|
|
||
| res = Self::poll_response(self.response.as_mut()), if resp_available => PollEvent::Response(res), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// Outcome of polling the various sources. | ||
| enum PollEvent<F, E> { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: Consider deriving standard traits for PollEvent for easier debugging and usage. Adding derives like Debug, PartialEq, or Clone (if applicable) can improve logging, testing, and code manipulation. Consider including them unless there are specific constraints. Suggested implementation: #[derive(Debug, PartialEq, Clone)]
/// Outcome of polling the various sources.
enum PollEvent<F, E> {enum PollEvent<F, E>
where
F: Debug + PartialEq + Clone,
E: Debug + PartialEq + Clone,
{ |
||
| /// Shutdown signal triggered. | ||
| Shutdown, | ||
| /// Result of polling the high-priority queue. | ||
| High(Option<F>), | ||
| /// Result of polling the low-priority queue. | ||
| Low(Option<F>), | ||
| /// Result of polling the response stream. | ||
| Response(Option<Result<F, WireframeError<E>>>), | ||
| } | ||
|
|
||
| /// Internal run state for the connection actor. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: Consider documenting or clarifying the bias order in next_event's select.
Since the order of branches in 'tokio::select! { biased; ... }' affects event prioritization, please clarify if prioritizing the shutdown signal is intentional. Documenting this will help maintainers understand the impact on shutdown responsiveness and event throughput.