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() {
244
244
245
245
// Start the runnable.
246
246
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
+ }
256
263
}
264
+ } else {
265
+ // During normal operation, always try to send errors (may block briefly)
266
+ r .errChan <- err
257
267
}
258
268
}
259
269
}(runnable )
You can’t perform that action at this time.
0 commit comments