diff --git a/src/held-messages.ts b/src/held-messages.ts index dc43272..c47bbf3 100644 --- a/src/held-messages.ts +++ b/src/held-messages.ts @@ -27,7 +27,8 @@ type HoldEntry = { /** * One message offered to the application. A drain waits on it until the first of: `answered()`, - * every listener that took it rejecting, no listener taking it, its deadline, or the link going. + * every listener that took it rejecting, no listener taking it or one throwing, a later message on + * its sequence number, its deadline, or the link going. */ export class MessageHold { private readonly entry: HoldEntry; @@ -55,7 +56,7 @@ export class MessageHold { if (this.working <= 0) this.answered(); } - /** At once, for a message nobody took: that is not work a shutdown can wait for. */ + /** At once, for a message nobody took or a listener threw on: that is not work a shutdown can wait for. */ release(): void { this.entry.release(); } diff --git a/todo.md b/todo.md index 123c150..02f96c4 100644 --- a/todo.md +++ b/todo.md @@ -204,6 +204,10 @@ and 5. Every seat ranked the session's lifecycle hardest and least wanted to mod - [ ] **Lift Locality to 7, and confirm it with a scoring run.** A run reading 7.0 or above also retires the #30 decision. The sub-items are what the 2026-09-28 run named, most seats first. +- [ ] **Count an `sms` listener that throws as one giving up, as a rejection already is.** A + synchronous throw makes `Session.emit` return false, and `HeldMessages.offer()` then releases + the hold at once, so a drain stops waiting on an async listener still answering beside it. + Goal 2. From the stability review of #45. - [ ] **Shrink the `IncomingDeps` closure bag.** 16 lambdas, six of them repeated in `SmsHandlers`, which makes every inbound call path indirect. Two seats.