fix(dashboard): wait for interrupt_reply before closing ZMQ control channel
The interrupt button on the task manager dashboard was silently dropping
the interrupt_request message. interrupt_service() called
control_channel.stop() (which closes the socket with linger=0)
immediately after send(). Since ZMQ's connect() is non-blocking, the
TCP connection may not yet be established at close time — especially
cross-container — causing linger=0 to discard the queued message.
Fix by starting channels before sending, waiting for the kernel's interrupt_reply (confirming delivery), then stopping channels in a finally block so close(linger=0) runs on an already-drained socket.
Closes #355 (closed)
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
Closes #355 (closed)