Repository navigation
Trash: a delivery fmsgd has given up on no longer keeps a message - #59
Merged
Merged
Conversation
fmsgd stops retrying a delivery once it is older than FMSG_RETRY_MAX_AGE (one day by default) but never marks it: a host that never answered leaves time_delivered null and response_code -1 for good. Delete for good treated every such row as pending with no age limit, and any add-to participant notification with time_notified null whatever its code, so a message sent to a dead or mistyped domain could never be removed from the host. The mirror was wrong too: fmsgd also retries codes 3, 5 and 101, which were treated as finished, so a message could be removed while fmsgd was still delivering it. Pending now means what it means to fmsgd: undelivered, last code null or one fmsgd retries (-1, 3, 5, 101), and younger than the retry window measured from the message's time_sent or the add-to batch's time_added. The rule is fmsg_api_delivery_pending in dd.sql, used by removeIfUnheld; the retryable codes are one list in trash.go that must match fmsgd's. FMSG_RETRY_MAX_AGE is read by the Web API as well (same default) and documented as a setting to keep equal on both. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
fmsgd stops retrying a delivery once it is older than
FMSG_RETRY_MAX_AGE(one day by default), but it never marks the row: a host that never answered leavestime_deliverednull andresponse_codeat -1 forever. Delete for good (removeIfUnheld) counted every such row as pending with no age limit, and any add-to participant notification withtime_notifiednull whatever its code. A message sent to a dead or mistyped domain therefore could never be removed from the host: its body and attachments stayed on disk after every local participant had deleted it for good.The mirror was wrong too. fmsgd also retries reject codes 3 (undisclosed), 5 (insufficient resources) and 101 (user full); the Web API treated those as finished, so it could remove a message, and its delivery rows, while fmsgd was still delivering it.
Change
dd.sql:fmsg_api_delivery_pending(msg, now, max_age, retryable)is the rule, next tofmsg_api_trash_state: amsg_to,msg_add_toormsg_add_to_notifyrow is pending while undelivered, its last code is null or retryable, and it is younger than the window measured frommsg.time_sentormsg_add_to_batch.time_added, exactly as fmsgd's sender measures it.trash.go:retryableResponseCodes(-1, 3, 5, 101) with a note that it must match fmsgd's list;removeIfUnheldcalls the function.MessageHandler.RetryMaxAge, read fromFMSG_RETRY_MAX_AGEin main (default 86400, must be positive). README documents it as a setting to keep equal to fmsgd's, and the Delete for good section says what pending means.Tests
TestPurgeKeepsRetryableDelivery: a delivery that last got 101 keeps the message; one that got 100 does not.TestPurgeRemovesGivenUpDelivery: with a short window, a -1 delivery inside it keeps the message; past it, an add-to delivery and participant notification that fmsgd gave up on no longer do, and the message leaves the host.Both fail on main.
go test ./...passes against Postgres 17 with fmsgd'sdd.sql.Not in this PR
A message deleted for good while a delivery was still inside the window is never re-checked once the window closes; nothing sweeps those. Worth a periodic sweep as a follow-up.
🤖 Generated with Claude Code