Repository navigation
feat(core): remember what a command dispatched with an idempotency key answered - #212
Open
benatespina wants to merge 2 commits into
Open
benatespina wants to merge 2 commits into
benatespina wants to merge 2 commits into
Conversation
…y answered A request that times out on the way back, a form submitted twice or a webhook delivered again dispatches its command twice, and the aggregate either rejects a retry of something that went through or does its work twice. A dispatch with idempotencyKey records what it answered, in the transaction of the events it stores, and every later dispatch under the same key, command and payload answers the same without running, its rejection included; another command or payload under the key is refused. Keys live 24 hours by default and the scheduled-command worker purges them. The React Router middleware passes the Idempotency-Key header to the commands of the request. The in-memory adapter now reserves positions when a transaction stages events and shows readers only the contiguous committed prefix, so a transaction answers the positions its events commit with, as the SQL adapters do.
The job summary piped sed into head -60 under pipefail; once the table of a package grew past 60 lines, head closed the pipe while sed still wrote, sed failed with a broken pipe and the job failed after a green run. awk prints the first 60 lines of the table and reads the rest without a reader to lose.
This branch has not been deployed
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
idempotencyKeyrecords what it answered, in the same transaction as the events it stores; every later dispatch under the same key, command and payload answers the same without running, its rejection included. Two dispatches racing for one key store the events once.IdempotencyKeyConflictError(IDEMPOTENCY_KEY_CONFLICT). Keys liveruntime.commands.idempotencyKeyLifetime(24 h by default) in a newbounda_idempotency_keystable, purged by the scheduled-command worker.Idempotency-Keyheader to every command of the request;failure()answers a conflict with a 422.Changes
IdempotencyStoreonStorageandStorageTransaction: memory, SQLite (libSQL and the Durable Object), PostgreSQL, with its contract test and a case in the storage transaction contract, run in workerd too.createCommandPipelinetakesstorage; a keyed dispatch records its outcome with the append that stores its events, or with the unit of work of a reaction; a replay setsbounda.outcometoreplayed.tx.eventStore.appendanswers the positions its events commit with, as the SQL adapters do.guides/idempotent-commands, plus configuration, errors, React Router, adapters and observability pages. Changesetminor.Verification
pnpm checkgreen (2050 tests, 3 skipped), PostgreSQL suite against a container, Cloudflare suite in workerd.main; every surviving mutant in the new code was killed except two equivalent ones.