SAY-5 30b7814aaf pkg/tools/batcher: stop scheduler panicking when b.data is closed externally
scheduler()'s defer unconditionally calls close(b.data). If the channel
was closed by the caller (or an upstream producer) instead of via the
normal Close()-sends-nil path, the receive on b.data returns ok == false,
scheduler returns, and the deferred close(b.data) then fires on an
already-closed channel:

    panic: close of closed channel

reliably reproducible under the #3653 steps (manually closing b.data
while Start() is running).

Track whether we observed the external-close via a local
`externallyClosed` flag set in the `ok == false` branch. The defer
only closes b.data when that flag is false, i.e. when the scheduler
exited through the nil-message or ticker paths and still owns the
channel. No behaviour change on the graceful Close() path.

Fixes #3653
2026-04-20 03:08:42 -07:00
..