b0100e738adbc055c6d11246abefc982d42acf4a
WorkerClient.ShutdownAsync marked the client Closing and then queued the WorkerShutdown envelope on the caller's token alone; the shutdown-timeout CTS was only created afterwards. The outbound channel is bounded, and a worker that has stopped reading the pipe parks the write loop in a pipe write it can only leave through _stopCts while the channel behind it fills with commands and their cancels. Once Closing, the heartbeat watchdog skips every tick, so nothing cancelled _stopCts and the enqueue waited for the caller's token - the lease sweep's stopping token, which fires at host stop and never before - with GatewaySession.CloseAsync holding its close lock throughout. Create the linked timeout CTS before the enqueue and run the enqueue, the loop waits and the process-exit wait on it, so the whole call is bounded by the shutdown timeout. A stalled queue now surfaces as the existing ShutdownTimeout fault, which cancels the loops, kills the worker process tree and hands GatewaySession its kill fallback. Test: WorkerClientTests.ShutdownAsync_WhenOutboundQueueIsFullBehindStalledPipeWrite_TimesOutAndKillsWorker stalls the gateway-side stream (a worker that stopped reading), fills the outbound channel with abandoned commands and their cancels, and asserts that ShutdownAsync throws ShutdownTimeout inside the test bound and kills the fake worker. It hung past the bound before the fix.
Description
No description provided
Languages
C#
48.4%
Java
40.1%
Python
3.2%
Rust
3%
Go
2.6%
Other
2.7%