Outbox: let an effect that failed be attempted again - #26
Open
nishanthvonteddu wants to merge 1 commit into
Open
nishanthvonteddu wants to merge 1 commit into
nishanthvonteddu wants to merge 1 commit into
Conversation
`ActionOutbox.execute()` caches a failed operation as terminal and raises the stored error on every later call for that key. A failed operation did not take effect, so running it again is not a repeat — it is the first time it happens. The outbox exists to stop one side effect being applied twice. Refusing a failure forever solves a different problem and creates one: a transient fault becomes permanent, because the receipt outlives its cause and repairing the cause changes nothing. A run that hit a full disk, a rate limit or a misconfigured path can never complete that node again, on any retry or resume, even after the operator has fixed it. Observed with S16_SANDBOX_ROOT pointing at a path that did not exist: four `write_file` receipts in ~/.s16code/outbox were left holding "OSError: [Errno 30] Read-only file system", and stayed unrunnable after the setting was corrected. `failed` now falls through to a fresh attempt, carrying an `attempt` counter and the previous error so a retry that keeps failing for the same reason stays legible. `completed` and `started` are unchanged: a receipt is still reused, and a crash left in flight is still parked for reconciliation rather than guessed at. The shipped test covered `completed` and `started` but not `failed`, which is why this survived; the new test fails before this change and passes after.
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.
A side effect that failed did not happen. Running it again is not a repeat — it is the first time it happens.
What breaks
ActionOutbox.execute()caches a failed operation as terminal:Every later call for that key re-raises the stored error. The outbox exists to stop one side effect being applied twice; refusing a failure forever solves a different problem and creates one. A transient fault — a full disk, a rate limit, a misconfigured path — becomes permanent, because the receipt outlives its cause and repairing the cause changes nothing. The affected node can never complete on any retry or resume.
How to see it break
Point
S16_SANDBOX_ROOTat a path that does not exist and run anything that callswrite_file. Correct the setting, then retry the same node: it still fails, with the stale error.I hit this for real. Four
write_filereceipts in~/.s16code/outbox/were left holdingOSError: [Errno 30] Read-only file systemand stayed unrunnable after the setting was fixed.The fix
failedfalls through to a fresh attempt, carrying anattemptcounter and theprevious_errorso a retry that keeps failing for the same reason stays legible without a log search.completedandstartedare unchanged: a receipt is still reused, and a crash left in flight is still parked for reconciliation rather than guessed at.Test
test_outbox_retries_an_effect_that_failedfails before this change and passes after.The shipped test covered
completedandstartedbut notfailed, which is why this survived.