Cut the prose the sweep of #48 found restated or false
Mirror / push (push) Successful in 8s
Test / lint (pull_request) Successful in 24s
Test / test (18) (pull_request) Successful in 32s
Test / test (20) (pull_request) Successful in 31s
Test / test (22) (pull_request) Successful in 33s
Test / test (24) (pull_request) Successful in 32s
Test / test (26) (pull_request) Successful in 31s
Mirror / push (push) Successful in 8s
Test / lint (pull_request) Successful in 24s
Test / test (18) (pull_request) Successful in 32s
Test / test (20) (pull_request) Successful in 31s
Test / test (22) (pull_request) Successful in 33s
Test / test (24) (pull_request) Successful in 32s
Test / test (26) (pull_request) Successful in 31s
This commit is contained in:
+11
-23
@@ -508,10 +508,7 @@ rule and an index of the titles below.
|
||||
|
||||
- **`close` means the session is over, and a drop the loop will retry is `disconnected`.**
|
||||
Maintainer's call, 2026-08-31: without the split, an application that opens a replacement client on
|
||||
`close` ends up holding two binds on one account. `teardown()` picks the event by
|
||||
`LinkLife.retrying()`, and `end()` stops the session before tearing down, so every deliberate
|
||||
shutdown emits `close`. A retry that opens a socket and then loses it is attached again through
|
||||
`attach()`, which is why a second drop emits again.
|
||||
`close` ends up holding two binds on one account, which goal 4 forbids.
|
||||
|
||||
- **An answer belongs to the link the message arrived on; a receipt does not.** Maintainer's call,
|
||||
2026-09-01. Rejected: answering on the new link, which succeeds and reports `{}` for a response
|
||||
@@ -541,9 +538,7 @@ rule and an index of the titles below.
|
||||
gives up on the operator whose provisioning lands a minute later; the backoff is what bounds the
|
||||
rate goal 4 cares about. The attempts before the first link report nothing, because the session
|
||||
running one has not reached the application: `disconnected` would have no listener and `close`
|
||||
would be a lie. Its wait is the one retry timer that is not `unref()`'d, for the reason
|
||||
`LinkLife`'s hold is not — it is awaited with no other handle, so a process whose only work is
|
||||
`client()` would exit unbound.
|
||||
would be a lie.
|
||||
|
||||
- **`connectTimeout` defaults to 10 s, bounds the whole connect including the TLS handshake, and
|
||||
`false` is the one way to turn it off.** Maintainer's call, 2026-09-20, serving goal 5: a connect
|
||||
@@ -739,9 +734,7 @@ rule and an index of the titles below.
|
||||
the one spelling on the public surface. The hold is bounded by `responseTimeout` rather than an
|
||||
option of its own — that is already the answer to how long one request may wait — and its clock
|
||||
starts when the send is issued rather than when it first finds the link down, so one budget covers
|
||||
every hold a single call makes. That timer is the one here that is not `unref()`'d: a held request
|
||||
is awaited with the socket already destroyed, so an unref'd one lets a process whose only remaining
|
||||
work is that send exit without settling it.
|
||||
every hold a single call makes.
|
||||
|
||||
- **A send queued for a send-window slot is bounded by the caller's `signal`, and by nothing else.**
|
||||
Maintainer's call, 2026-09-06, from a review of PR #71: the hold above observes the signal and the
|
||||
@@ -760,19 +753,14 @@ rule and an index of the titles below.
|
||||
an abort while held for a link already gives. The drain half needs nothing: `close({ signal })` already hands the signal to
|
||||
`window.idle()`, and `unbind()` taking none is the shape README states.
|
||||
|
||||
- **`LinkLife` decides whether a link can carry a request, and a bind is what makes it one.**
|
||||
Maintainer's call, 2026-09-01: `attach()` marks the session attached the moment a socket is
|
||||
handed over, one round trip before the bind is answered, so gating on that let a send arriving in
|
||||
that window go out unbound and come back `ESME_RINVBNDSTS`. `LinkLife` is told what happened and
|
||||
never reads back into the session: a collaborator that has to ask does not own its decision, which
|
||||
is how the first cut ended up answering the same question two different ways at admit and at
|
||||
release. Every other collaborator reads whether the link lives from it and keeps no copy: five
|
||||
copies held in step by statement order were what the 2026-09-28 comprehension runs ranked hardest.
|
||||
`ReconnectLoop.halted` is the loop's own, for its timer, because `client()` also runs a loop with
|
||||
no session behind it for `fromStart`; a session's loop is stopped by `Session.stop()` alone.
|
||||
The retry in `requestPastDrain()` asks `link.awaitsNextLink()` rather than `canCarry()`, which also
|
||||
reads the socket: a loop condition the link does not gate on spins against a link that admits it
|
||||
straight back.
|
||||
- **One owner decides whether a link can carry a request, and a bind is what makes it one.**
|
||||
Maintainer's call, 2026-09-01, extended 2026-09-28; goal 1, since a send on a link not yet bound
|
||||
comes back `ESME_RINVBNDSTS`. `LinkLife` is told what happened and never reads back into the
|
||||
session; every other collaborator reads it and keeps no copy. Rejected: gating on the socket being
|
||||
attached, which admits a send one round trip before the bind is answered, and collaborators that
|
||||
ask the session, which answered the same question two ways at admit and at release.
|
||||
`ReconnectLoop.halted` is the one other flag, because `client()` also runs a loop with no session
|
||||
behind it for `fromStart`; a session's loop is stopped by `Session.stop()` alone.
|
||||
|
||||
|
||||
## Internals and tests
|
||||
|
||||
Reference in New Issue
Block a user