Drop the drain and gate decisions' stale closed flag and what the code already says
Mirror / push (push) Has been cancelled
Test / lint (pull_request) Successful in 24s
Test / test (22) (pull_request) Successful in 32s
Test / test (18) (pull_request) Successful in 31s
Test / test (20) (pull_request) Successful in 31s
Test / test (24) (pull_request) Successful in 32s
Test / test (26) (pull_request) Successful in 32s
Mirror / push (push) Has been cancelled
Test / lint (pull_request) Successful in 24s
Test / test (22) (pull_request) Successful in 32s
Test / test (18) (pull_request) Successful in 31s
Test / test (20) (pull_request) Successful in 31s
Test / test (24) (pull_request) Successful in 32s
Test / test (26) (pull_request) Successful in 32s
This commit is contained in:
+11
-17
@@ -577,18 +577,14 @@ rule and an index of the titles below.
|
|||||||
|
|
||||||
- **A deliberate shutdown drains; an unusable link and an abort do not.** `close()` and `unbind()`
|
- **A deliberate shutdown drains; an unusable link and an abort do not.** `close()` and `unbind()`
|
||||||
wait on the send window rather than the pending map — the map misses a segment still queued behind
|
wait on the send window rather than the pending map — the map misses a segment still queued behind
|
||||||
a full window, and finishing a half-sent multipart message is the point. The window counts slots,
|
a full window, and finishing a half-sent multipart message is the point. A stream the framer or
|
||||||
never outcomes, and empties on a drop too, where `teardown()` settles everything the link was
|
the codec cannot read, an aborted `close({ signal })` and a peer's own `unbind` do not drain:
|
||||||
carrying, which is why `drain()` reads `closed` before it reads the count. A stream the framer or
|
nothing on a dead link can answer, an abort means stop now, and a peer that has declared itself
|
||||||
the codec cannot read takes `teardown()` instead, and `close({ signal })` on an aborted signal and
|
finished will not answer what it still owes, so draining any of the three would only hold a socket
|
||||||
a peer's own `unbind` take `end()`: nothing on a dead link can answer, an abort means stop now, and
|
open for the timeout. `shutdownTimeout` stays a session option rather than a `close()` argument:
|
||||||
a peer that has declared itself finished will not answer what it still owes, so draining any of the
|
`server()` builds sessions on the caller's behalf, so the option is the only composition point.
|
||||||
three would only hold a socket open for the timeout. `unbind()` sends its own PDU through
|
`SmppServer.close()` reports each session's unfinished drain through `serverError`, because its
|
||||||
`requestPastDrainGateAndWindow()`, because it must go out either way.
|
own result says nothing but that the listener stopped.
|
||||||
`shutdownTimeout` stays a session option rather than a `close()` argument: `server()` builds
|
|
||||||
sessions on the caller's behalf, so the option is the only composition point. `SmppServer.close()`
|
|
||||||
reports each session's unfinished drain through `serverError`, because its own result says nothing
|
|
||||||
but that the listener stopped.
|
|
||||||
|
|
||||||
- **`sendSms()` puts every segment of a message on the wire together.** Goal 6: a long message costs
|
- **`sendSms()` puts every segment of a message on the wire together.** Goal 6: a long message costs
|
||||||
one round trip rather than one per segment. Rejected: sending each segment once the last is
|
one round trip rather than one per segment. Rejected: sending each segment once the last is
|
||||||
@@ -765,11 +761,9 @@ rule and an index of the titles below.
|
|||||||
`window.idle()`, and `unbind()` taking none is the shape README states.
|
`window.idle()`, and `unbind()` taking none is the shape README states.
|
||||||
|
|
||||||
- **The gate decides whether a link can carry a request, and a bind is what makes it one.**
|
- **The gate decides whether a link can carry a request, and a bind is what makes it one.**
|
||||||
Maintainer's call, 2026-09-01: `attach()` clears `closed` the moment a socket is handed over, one
|
Maintainer's call, 2026-09-01: `attach()` marks the session attached the moment a socket is
|
||||||
round trip before the bind is answered, so gating on `closed` let a send arriving in that window go
|
handed over, one round trip before the bind is answered, so gating on that let a send arriving in
|
||||||
out unbound and come back `ESME_RINVBNDSTS`. `LinkGate` owns the answer instead — `shut(returning)`
|
that window go out unbound and come back `ESME_RINVBNDSTS`. The gate is told what happened and
|
||||||
on every teardown, `open()` only once `comeBackUp()` has a bound link — and
|
|
||||||
`OutgoingRequests.canCarry()` reads it rather than `closed`. The gate is told what happened and
|
|
||||||
never reads back into the session: a collaborator that has to ask does not own its decision, which
|
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
|
is how the first cut ended up answering the same question two different ways at admit and at
|
||||||
release. The retry in `requestPastDrain()` asks `gate.awaitsNextLink()` rather than `canCarry()`,
|
release. The retry in `requestPastDrain()` asks `gate.awaitsNextLink()` rather than `canCarry()`,
|
||||||
|
|||||||
Reference in New Issue
Block a user