@@ -200,6 +200,10 @@ fn should_convert_discarded_error(error: &Error) -> bool {
200200 )
201201}
202202
203+ fn processing_drained ( active_job_count : usize , active_fetchers : usize ) -> bool {
204+ active_job_count == 0 && active_fetchers == 0
205+ }
206+
203207/// Shared context for all worker loops within a single Worker instance.
204208///
205209/// Pre-computes keys and holds all shared state needed by the processing loops,
@@ -683,11 +687,13 @@ impl Worker {
683687 // Wait for active jobs to drain
684688 let deadline = tokio:: time:: Instant :: now ( ) + Duration :: from_millis ( timeout_ms) ;
685689 loop {
686- if self . active_jobs . read ( ) . await . is_empty ( ) {
690+ let active_job_count = self . active_jobs . read ( ) . await . len ( ) ;
691+ let active_fetchers = self . active_fetchers . load ( Ordering :: Relaxed ) ;
692+ if processing_drained ( active_job_count, active_fetchers) {
687693 break ;
688694 }
689695 if tokio:: time:: Instant :: now ( ) >= deadline {
690- warn ! ( "close timeout reached with active jobs remaining" ) ;
696+ warn ! ( "close timeout reached with active work remaining" ) ;
691697 break ;
692698 }
693699 tokio:: time:: sleep ( Duration :: from_millis ( 100 ) ) . await ;
@@ -2376,7 +2382,7 @@ impl Drop for Worker {
23762382
23772383#[ cfg( test) ]
23782384mod tests {
2379- use super :: should_convert_discarded_error;
2385+ use super :: { processing_drained , should_convert_discarded_error} ;
23802386 use crate :: error:: Error ;
23812387
23822388 #[ test]
@@ -2400,4 +2406,11 @@ mod tests {
24002406 "fatal" . to_string( )
24012407 ) ) ) ;
24022408 }
2409+
2410+ #[ test]
2411+ fn processing_is_not_drained_while_fetcher_is_chaining_next_job ( ) {
2412+ assert ! ( !processing_drained( 0 , 1 ) ) ;
2413+ assert ! ( !processing_drained( 1 , 0 ) ) ;
2414+ assert ! ( processing_drained( 0 , 0 ) ) ;
2415+ }
24032416}
0 commit comments