Name the retry status by direction, and correct what the held-message decision claims
Test / lint (pull_request) Successful in 28s
Test / test (18) (pull_request) Successful in 31s
Test / test (20) (pull_request) Successful in 30s
Test / test (22) (pull_request) Successful in 31s
Test / test (24) (pull_request) Successful in 30s
Test / test (26) (pull_request) Successful in 37s
Mirror / push (push) Successful in 4s

This commit was merged in pull request #29.
This commit is contained in:
2026-09-26 14:53:09 +02:00
parent f2977638f2
commit 42b1239f3d
5 changed files with 28 additions and 29 deletions
+18 -18
View File
@@ -679,25 +679,25 @@ rule and an index of the titles below.
- **What the application holds unanswered is capped on constants, and a message past the cap is
refused.** A bound the application cannot raise is the point: an application that answers nothing
would otherwise grow it for the life of the link, which goal 4 forbids. Reassembly's `maxOctets`
is an option because it bounds what the peer sends; this bounds what the application leaves
unanswered. Maintainer's call, 2026-09-26: a message arriving past the cap is refused with the
retry status, so the peer keeps it (goal 2). Rejected: dropping the oldest to make room, which
frees nothing while the application still holds its `Sms`, and stops the drain waiting for a
message the peer is owed. Rejected: pausing the socket, which also stalls every answer and
`enquire_link` on the link. Reaching the bound is a log line and nothing more (goal 8): an event
or a public count would be surface for what the application already knows, since it is the one
not answering. A message held past its timeout is still dropped, so `close()` can
report fewer unanswered than there were — accepted, because the alternative is holding what
nothing will answer.
would otherwise hold ever more messages, which goal 4 forbids. Reassembly's `maxOctets` is an
option because it bounds what the peer sends; this bounds what the application leaves unanswered.
Maintainer's call, 2026-09-26. Refusing leaves the message with the peer, which will send it again
(goal 2). Rejected: dropping the oldest to make room, which frees nothing while the application
still holds its `Sms`, and stops the drain waiting for a message the peer is owed. Rejected:
pausing the socket, which also stalls every answer and `enquire_link` on the link. Reaching the
bound shows only in the log (goal 8): an event or a public count would be surface for what the
application already knows, since it is the one not answering. A message held past its timeout is
still dropped, so `close()` can report fewer unanswered than there were — accepted, because the
alternative is holding what nothing will answer.
- **A store at its bound answers `ESME_RTHROTTLED` to a `submit_sm` and `ESME_RX_T_APPN` to a
`deliver_sm`.** Maintainer's call, 2026-09-26, for reassembly and held messages alike, so "keep it
and retry" has one spelling per direction. `ESME_RTHROTTLED` asks the sender to slow down, which
is what the peer outrunning us needs, and operators send it (Vonage, LINK Mobility, Route Mobile,
Jasmin), so clients built against them meet it (goal 1). Rejected: `ESME_RMSGQFUL`, which names an
exhausted queue and no rate. `ESME_RTHROTTLED` is the SMSC's to send, so an ESME answers with
SMPP 3.4's temporary receiver error, the one an SMSC retries on (goal 3).
- **A store at its bound answers `ESME_RTHROTTLED` to a submission and `ESME_RX_T_APPN` to a
delivery, a `data_sm` by whichever it stands in for.** Maintainer's call, 2026-09-26, for
reassembly and held messages alike, so "keep it and retry" has one spelling per direction.
`ESME_RTHROTTLED` asks the sender to slow down, which is what the peer outrunning us needs, and
operators send it (Vonage, LINK Mobility, Route Mobile, Jasmin), so clients built against them
meet it (goal 1). Rejected: `ESME_RMSGQFUL`, which names an exhausted queue and no rate.
`ESME_RTHROTTLED` is the SMSC's to send, so an ESME answers with SMPP 3.4's temporary receiver
error, the one an SMSC retries on (goal 3).
- **A reconnect keeps the delivery-receipt merges; everything else the link held is dropped.**
`onDelivery()` answers each receipt before the group it belongs to is complete, and `teardown()`