Repository navigation
Retry a throttled lock claim when restarting a server - #42
Merged
Merged
Conversation
A restart of an existing server claims its key with an If-Match PUT.
Unlike the first-ever claim (ObjectStore.try_claim/3, two transient
retries), that PUT had no retries, so one transient failure failed the
start. Object storage throttles rapid writes to one key: Tigris answers
503 SlowDown, and a restart claims the key right after the previous
owner's final writes. On Sprites staging a `sprite start` issued right
after a stop failed with internal_error this way:
Failed to put object with etag: ... status: 503 ... <Code>SlowDown</Code>
Failed to initialize DurableServer: %Req.Response{status: 503, ...}
The claim now retries transient failures twice, like try_claim. A retry
whose earlier attempt landed gets 412, which the object store backend
already resolves as this boot's own write (same-boot owner check).
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.
Summary
A restarted server claims its existing key in
try_lock_object_via_update/2with anIf-MatchPUT. That PUT had no retries. The first-ever claim (ObjectStore.try_claim/3) and regular syncs (@max_sync_retries) both retry. So a single transient object-storage failure failed the start.Object storage throttles rapid writes to one key, and a restart claims the key right after the previous owner's final writes. Sprites staging hit exactly that: a
sprite startissued right after a stop returnedinternal_error, and the retained logs show:The lock claim now passes
max_retries: 2, the same budget astry_claim. The object store retries 408/429/500/502/503/504 and transport timeouts and closes.Safety. A retry whose earlier attempt actually landed gets 412.
Backends.ObjectStore.put_object/4already resolves a 412 on an:etagput throughresolve_ambiguous_conditional_put/5. That reads the object back and adopts it only if it holds exactly this attempt's encoded state from the same boot owner. The claim's state carries this attempt's pid and heartbeat, so a different winner is still{:error, :conflict}→ "raced the lock".Testing
New
DurableServerTestcases run against LocalStack with a Req adapter in front of it:mix test: 454 passed, 37 excluded.mix compile --warnings-as-errorsis clean.