The release/0.1 build (CircleCI 12) failed in SinkAndScheduleTest.testQueueAndAdapter:74 (expected RESOLVED, got OPEN), although the same commit passed on develop.
Root cause (product, not only the test):QbitAlertsSink.stop() called flush() and then interrupted the drain thread. When the drain thread had already polled a signal and was still writing it, flush() saw an empty queue and stop() returned before that write finished. The interrupt could also land in the middle of the write. A signal submitted just before shutdown (here, a resolve) could be lost.
Fix:stop() sets a stopping flag that ends the drain loop, joins the thread (up to 10 s; it interrupts only if the thread doesn't finish), then flushes whatever is still queued. The drain poll drops from 1 s to 200 ms so stop() returns promptly. A restart resets the flag.
Test:testStopWaitsForInFlightSignals raises then resolves 25 alerts, calling stop() between them, and asserts all 25 are RESOLVED. It fails on the old code (3 of 4 runs) and passes on the fix (3 of 3). The full mvn verify passes with all gates.
The release/0.1 build ([CircleCI 12](https://circleci.com/gh/QRun-IO/qbit-alerts/12)) failed in `SinkAndScheduleTest.testQueueAndAdapter:74` (expected RESOLVED, got OPEN), although the same commit passed on develop.
**Root cause (product, not only the test):** `QbitAlertsSink.stop()` called `flush()` and then interrupted the drain thread. When the drain thread had already polled a signal and was still writing it, `flush()` saw an empty queue and `stop()` returned before that write finished. The interrupt could also land in the middle of the write. A signal submitted just before shutdown (here, a resolve) could be lost.
**Fix:** `stop()` sets a stopping flag that ends the drain loop, joins the thread (up to 10 s; it interrupts only if the thread doesn't finish), then flushes whatever is still queued. The drain poll drops from 1 s to 200 ms so `stop()` returns promptly. A restart resets the flag.
**Test:** `testStopWaitsForInFlightSignals` raises then resolves 25 alerts, calling `stop()` between them, and asserts all 25 are RESOLVED. It fails on the old code (3 of 4 runs) and passes on the fix (3 of 3). The full `mvn verify` passes with all gates.
Unblocks qbit-alerts 0.1.0-RC.1.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The release/0.1 build (CircleCI 12) failed in
SinkAndScheduleTest.testQueueAndAdapter:74(expected RESOLVED, got OPEN), although the same commit passed on develop.Root cause (product, not only the test):
QbitAlertsSink.stop()calledflush()and then interrupted the drain thread. When the drain thread had already polled a signal and was still writing it,flush()saw an empty queue andstop()returned before that write finished. The interrupt could also land in the middle of the write. A signal submitted just before shutdown (here, a resolve) could be lost.Fix:
stop()sets a stopping flag that ends the drain loop, joins the thread (up to 10 s; it interrupts only if the thread doesn't finish), then flushes whatever is still queued. The drain poll drops from 1 s to 200 ms sostop()returns promptly. A restart resets the flag.Test:
testStopWaitsForInFlightSignalsraises then resolves 25 alerts, callingstop()between them, and asserts all 25 are RESOLVED. It fails on the old code (3 of 4 runs) and passes on the fix (3 of 3). The fullmvn verifypasses with all gates.Unblocks qbit-alerts 0.1.0-RC.1.
🤖 Generated with Claude Code