#338: cancel timed-out queued deliveries #343

Closed
agent wants to merge 0 commits from worker/fleetd-338-83a4a1-22 into main
Member

Fixes #338.

Change

Injector.enqueue now returns an identity Delivery handle. MessageService cancels that exact handle when its reply deadline passes before delivery. queuedDeliveries still records the health fact. The changed MessageServiceTest assertion now proves the old text is not typed after the target becomes idle. Injector tests also prove middle-queue cancellation preserves FIFO order and that a pickup race reports DELIVERED.

Race decision

Cancellation and Injector.onStatus use the same target monitor. If cancellation gets the monitor first, it removes the exact Pending and the worker never receives it. If onStatus gets it first, agent.prompt has already succeeded and Pending becomes DELIVERED. Cancellation then returns DELIVERED, so MessageService returns TIMED_OUT_WORKING, not TIMED_OUT_QUEUED. This does not silently claim a queued timeout while the text landed.

Cost

A member that was about to become idle can lose an undelivered message. The lead must send it again. This is loud and recoverable, unlike a stale brief that arrives after its sender was told it did not go.

Tests

Mutation proof: I removed the timeout cancellation call and ran mvn -Dtest=MessageServiceTest#hasQueuedDeliveryIsTrueAfterAnUndeliveredSendTimesOut test. It failed with: a TIMED_OUT_QUEUED send must be cancelled, not delivered when the worker later goes idle ==> expected: but was: . I restored the call.

cd fleetd && mvn clean install: Tests run: 1357, Failures: 0, Errors: 0, Skipped: 0; BUILD SUCCESS.

Other matching shape, not fixed

MessageService.answer has the existing fleetd #334 race documented in its source: an ask timeout removes the async task by turn ID before a late answer looks it up, so the task can stay pending after answer returns REPLIED. This is outside #338.

Fixes #338. ## Change Injector.enqueue now returns an identity Delivery handle. MessageService cancels that exact handle when its reply deadline passes before delivery. queuedDeliveries still records the health fact. The changed MessageServiceTest assertion now proves the old text is not typed after the target becomes idle. Injector tests also prove middle-queue cancellation preserves FIFO order and that a pickup race reports DELIVERED. ## Race decision Cancellation and Injector.onStatus use the same target monitor. If cancellation gets the monitor first, it removes the exact Pending and the worker never receives it. If onStatus gets it first, agent.prompt has already succeeded and Pending becomes DELIVERED. Cancellation then returns DELIVERED, so MessageService returns TIMED_OUT_WORKING, not TIMED_OUT_QUEUED. This does not silently claim a queued timeout while the text landed. ## Cost A member that was about to become idle can lose an undelivered message. The lead must send it again. This is loud and recoverable, unlike a stale brief that arrives after its sender was told it did not go. ## Tests Mutation proof: I removed the timeout cancellation call and ran mvn -Dtest=MessageServiceTest#hasQueuedDeliveryIsTrueAfterAnUndeliveredSendTimesOut test. It failed with: a TIMED_OUT_QUEUED send must be cancelled, not delivered when the worker later goes idle ==> expected: <true> but was: <false>. I restored the call. cd fleetd && mvn clean install: Tests run: 1357, Failures: 0, Errors: 0, Skipped: 0; BUILD SUCCESS. ## Other matching shape, not fixed MessageService.answer has the existing fleetd #334 race documented in its source: an ask timeout removes the async task by turn ID before a late answer looks it up, so the task can stay pending after answer returns REPLIED. This is outside #338.
agent added 1 commit 2026-09-04 10:56:35 +02:00
#338: cancel timed-out queued deliveries
CI / contract (pull_request) Successful in 43s
CI / build (pull_request) Failing after 2m11s
147f50c19e
ltms closed this pull request 2026-09-04 11:01:33 +02:00
Some checks are pending
CI / contract (pull_request) Successful in 43s
CI / build (pull_request) Failing after 2m11s

Pull request closed

Sign in to join this conversation.