File tree Expand file tree Collapse file tree 1 file changed +19
-9
lines changed Expand file tree Collapse file tree 1 file changed +19
-9
lines changed Original file line number Diff line number Diff line change @@ -244,16 +244,26 @@ func (r *runnableGroup) reconcile() {
244244
245245 // Start the runnable.
246246 if err := rn .Start (r .ctx ); err != nil {
247- // Send error with context awareness to prevent blocking during shutdown
248- select {
249- case r .errChan <- err :
250- // Error sent successfully
251- case <- r .ctx .Done ():
252- // Context cancelled (shutdown), drop error to prevent blocking forever
253- // This prevents goroutine leaks when error drain go routine has exited after timeout
254- if ! errors .Is (err , context .Canceled ) { // don't log context.Canceled errors as they are expected during shutdown
255- r .logger .Info ("error dropped during shutdown to prevent goroutine leak" , "error" , err )
247+ // Check if we're during the shutdown process.
248+ r .stop .RLock ()
249+ isStopped := r .stopped
250+ r .stop .RUnlock ()
251+
252+ if isStopped {
253+ // During shutdown, try to send error first (error drain goroutine might still be running)
254+ // but drop if it would block to prevent goroutine leaks
255+ select {
256+ case r .errChan <- err :
257+ // Error sent successfully (error drain goroutine is still running)
258+ default :
259+ // Error drain goroutine has exited, drop error to prevent goroutine leak
260+ if ! errors .Is (err , context .Canceled ) { // don't log context.Canceled errors as they are expected during shutdown
261+ r .logger .Info ("error dropped during shutdown to prevent goroutine leak" , "error" , err )
262+ }
256263 }
264+ } else {
265+ // During normal operation, always try to send errors (may block briefly)
266+ r .errChan <- err
257267 }
258268 }
259269 }(runnable )
You can’t perform that action at this time.
0 commit comments