File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -160,7 +160,23 @@ pub fn spawn_io_tasks(
160160 match res {
161161 Ok ( frame) => {
162162 trace!( "Sending outbound frame" ) ;
163- if let Err ( e) = writer. write_frame( frame. into( ) ) . await {
163+ // Cancellation is acceptable here because fallback/shutdown
164+ // drops this connection instead of reusing the Noise state.
165+ let write_result = tokio:: select! {
166+ biased;
167+ _ = cancellation_token. cancelled( ) => {
168+ trace!( "Received shutdown signal during write" ) ;
169+ inbound_tx_clone. close( ) ;
170+ break ;
171+ }
172+ _ = fallback. cancelled( ) , if fallback. is_enabled( ) => {
173+ trace!( "Received fallback signal during write" ) ;
174+ inbound_tx_clone. close( ) ;
175+ break ;
176+ }
177+ result = writer. write_frame( frame. into( ) ) => result,
178+ } ;
179+ if let Err ( e) = write_result {
164180 error!( error=?e, "Writer error" ) ;
165181 outbound_rx. close( ) ;
166182 break ;
Original file line number Diff line number Diff line change @@ -126,7 +126,21 @@ pub fn spawn_io_tasks(
126126 match res {
127127 Ok ( frame) => {
128128 trace!( "Sending outbound frame" ) ;
129- if let Err ( e) = writer. write_frame( frame. into( ) ) . await {
129+ let write_result = tokio:: select! {
130+ biased;
131+ _ = cancellation_token. cancelled( ) => {
132+ trace!( "Received app shutdown signal during write" ) ;
133+ inbound_tx_clone. close( ) ;
134+ break ;
135+ }
136+ _ = fallback_token. cancelled( ) => {
137+ trace!( "Received fallback signal during write" ) ;
138+ inbound_tx_clone. close( ) ;
139+ break ;
140+ }
141+ result = writer. write_frame( frame. into( ) ) => result,
142+ } ;
143+ if let Err ( e) = write_result {
130144 error!( error=?e, "Writer error" ) ;
131145 outbound_rx. close( ) ;
132146 break ;
Original file line number Diff line number Diff line change @@ -65,14 +65,21 @@ impl FallbackCoordinator {
6565 tracing:: debug!( "FallbackCoordinator: triggering fallback" ) ;
6666 self . signal . cancel ( ) ;
6767
68- if self . pending_tasks . load ( Ordering :: Acquire ) == 0 {
69- return ; // all tasks already done
70- }
68+ loop {
69+ let notified = self . notify . notified ( ) ;
70+
71+ if self . pending_tasks . load ( Ordering :: Acquire ) == 0 {
72+ tracing:: debug!(
73+ "FallbackCoordinator: finished waiting for components to complete cleanup"
74+ ) ;
75+ return ; // all tasks already done
76+ }
7177
72- // there's still some tasks running,
73- // wait for the last task to notify us
74- self . notify . notified ( ) . await ;
75- tracing:: debug!( "FallbackCoordinator: finished waiting for components to complete cleanup" ) ;
78+ // There's still some tasks running, wait for the next completion
79+ // signal. Creating the Notified future before checking the counter
80+ // avoids losing the final wakeup if a task exits concurrently.
81+ notified. await ;
82+ }
7683 }
7784}
7885
You can’t perform that action at this time.
0 commit comments