jsconsumer: make Runner.Stop concurrency-safe and a completion boundary

main

Commit

nodo1mo ago

Stop mutated the unsynchronized cc field, and the context-cancel stop Start arms runs on its own goroutine — an explicit Stop racing it was a data race. It also returned as soon as delivery was halted, so a caller tearing down stores/publishers/the connection after Stop could yank them out from under an in-flight handler.

Stop now fires ConsumeContext.Stop through a sync.Once and then blocks on the Closed() channel (captured while the subscription is live, the entiredb natsx pattern), which nats.go closes only when the consume loop has fully wound down including the in-flight callback — restoring the cancel -> join -> drain shutdown ordering (COR-923). Documented: Stop must not be called from inside the handler.

Pinned by TestStopWaitsForInFlightHandler and TestStopConcurrentWithCancel under -race.

Entire-Checkpoint: 71b20e115766

Checkpoints

Unify NATS Consumer Backoff and Tracing

Claude CodeFable 5
View session
Checkpoint 1