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 @@ -245,16 +245,26 @@ func (r *runnableGroup) reconcile() {
245
245
246
246
// Start the runnable.
247
247
if err := rn .Start (r .ctx ); err != nil {
248
- // Send error with context awareness to prevent blocking during shutdown
249
- select {
250
- case r .errChan <- err :
251
- // Error sent successfully
252
- case <- r .ctx .Done ():
253
- // Context cancelled (shutdown), drop error to prevent blocking forever
254
- // This prevents goroutine leaks when error drain go routine has exited after timeout
255
- if ! errors .Is (err , context .Canceled ) { // don't log context.Canceled errors as they are expected during shutdown
256
- r .logger .Info ("error dropped during shutdown to prevent goroutine leak" , "error" , err )
248
+ // Check if we're during the shutdown process.
249
+ r .stop .RLock ()
250
+ isStopped := r .stopped
251
+ r .stop .RUnlock ()
252
+
253
+ if isStopped {
254
+ // During shutdown, try to send error first (error drain goroutine might still be running)
255
+ // but drop if it would block to prevent goroutine leaks
256
+ select {
257
+ case r .errChan <- err :
258
+ // Error sent successfully (error drain goroutine is still running)
259
+ default :
260
+ // Error drain goroutine has exited, drop error to prevent goroutine leak
261
+ if ! errors .Is (err , context .Canceled ) { // don't log context.Canceled errors as they are expected during shutdown
262
+ r .logger .Info ("error dropped during shutdown to prevent goroutine leak" , "error" , err )
263
+ }
257
264
}
265
+ } else {
266
+ // During normal operation, always try to send errors (may block briefly)
267
+ r .errChan <- err
258
268
}
259
269
}
260
270
}(runnable )
You can’t perform that action at this time.
0 commit comments