887aca0183
Site 1 (abandon()'s matching loop, reachable): the recovery/put-back branch calls inbox.publish, which AmqpReplyInbox implements as a real broker round trip that throws IllegalStateException on an unroutable/unconfirmed/interrupted publish. An uncaught throw there aborted the loop, stranding every task after it in `matching` PENDING forever. Fixed by recording each task's own future.complete() result before any cleanup runs, then wrapping the cleanup in try/catch so one task's failure cannot stop its siblings from getting their outcome. Reaching the throwing branch by real timing needs a race the file's own #137 follow-up already found unreachable through the public API, so the reproducing test uses a test-only hook (same technique as the existing fleetd #324/#329 hooks) to inject the throw at that exact point. Site 2 (sendAsync's task.future.whenComplete, reachable): the returned stage is discarded, so an uncaught throw from pushLoop.onTicketTerminal vanished with no log line. Reproduced for real: Fleetd's shutdown hook runs messages.close() (stops the async executor from taking new work, but does not cancel a send already in flight) before pushLoop.close() (shuts its scheduler down immediately) — a ticket completing in that window makes onTicketTerminal's own scheduler.schedule(...) throw a genuine RejectedExecutionException. Fixed with a try/catch(Throwable) plus log.error inside the whenComplete action. Site 3 (the two `finally { asyncTasksByWaiter.remove(reply); rendezvous.close(...); }` blocks in send() and answer()): read Rendezvous.close/closeAsk and the ConcurrentHashMap operations behind them — both are plain map ops on a non-null key with no user-overridable code, so neither can throw. Left unchanged; not a defect. Mutation-proven: reverting either fix reproduces the failure it exists to catch — removing site 1's try/catch aborts abandon() with the injected exception (MessageServiceTest#aPerTaskCleanupFailureDoesNotStrandTheRemainingMatchingTasks errors); removing site 2's try/catch leaves the RejectedExecutionException unlogged (MessageServiceTest#aTicketTerminalPushFailureDoesNotVanishSilently fails its log assertion). Full suite: mvn clean install, Tests run: 1365, Failures: 0, Errors: 0, BUILD SUCCESS.