Outbox: make an effect a crash left uncertain findable - #30
Open
nishanthvonteddu wants to merge 1 commit into
Open
nishanthvonteddu wants to merge 1 commit into
nishanthvonteddu wants to merge 1 commit into
Conversation
`execute()` parks a run on `Deferred(key, "outbox.reconcile")` when it meets a record left `started` by a process that died mid-dispatch. Not guessing is right: repeating an effect that may already have landed is worse than waiting. But `"outbox.reconcile"` appears exactly once in the package -- where it is created. Nothing emits it. The only way out is an operator completing the handle by hand, and they cannot, because nothing lists the stuck keys, nothing timestamps them, and nothing says the recovery path exists. The run waits forever and no surface admits it. `started` records now carry `started_at`, so an effect in flight can be told from one abandoned weeks ago. `uncertain()` lists them oldest first, and `resolve()` closes one with what the person found out -- stored in the shape `execute` returns, so the next call does not re-park on a question that has already been answered. The module docstring now states the contract, which was the part a reader had no way to discover.
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 run parked by a crash mid-side-effect waits on an event nothing ever sends, and nothing records that it is stuck.
What breaks
execute()meets a record leftstarted— the process died between dispatching an effect and learning whether it landed — and parks:Refusing to guess is right. Repeating an effect that may already have happened is worse than waiting.
But
"outbox.reconcile"appears exactly once in the package — where it is created. No producer emits it. The only way out is an operator completing the handle by hand through/completions, and they cannot:startedcarries no timestamp, so an effect in flight looks identical to one abandoned weeks agoThe run waits forever and no surface admits it.
The fix
Not a reconciler — the answer genuinely requires a person checking whether the effect landed. What was missing is the means to act:
startedrecords carrystarted_atuncertain()lists parked effects, oldest firstresolve(key, receipt)closes one with what the person found, stored in the shapeexecutereturns so the next call does not re-park on an answered questionTest
test_outbox_can_list_what_a_crash_left_uncertain— parks an effect, finds it viauncertain(), resolves it, confirms the receipt is reused afterwards. Fails before, passes after.