Problem
A Put with SequenceKeysDeltas is retried transparently by the client SDK on transient errors. If the first attempt committed but the response was lost (e.g., a timeout at the ambiguous point), the retry increments the sequence again: a second range is assigned and a duplicate entry is written. Sequence assignment is therefore at-least-once under ambiguous failures.
Clients cannot guard against this themselves: ExpectedVersionId is rejected for sequential keys (db_sequences.go returns ErrBadVersionId — "Cannot set an expected version id when key is sequential"), so there is no conditional-insert escape hatch.
Proposal
Server-side deduplication keyed by a client-supplied idempotency token:
- The client attaches a token (e.g.,
(client id, request id)) to sequence Puts; the SDK reuses the same token across internal retries.
- The leader records the token in the replicated entry alongside the assigned sequence key.
- A retry carrying an already-applied token returns the originally assigned key instead of re-incrementing.
- The dedup window can be bounded (per session, or a bounded per-sequence history) so state does not grow unbounded.
This makes sequence assignment exactly-once end-to-end under ambiguous failures. Primary beneficiary: offset assignment in Ursa-style usage, where a duplicate assignment produces a duplicate offset range and index entry.
Problem
A
PutwithSequenceKeysDeltasis retried transparently by the client SDK on transient errors. If the first attempt committed but the response was lost (e.g., a timeout at the ambiguous point), the retry increments the sequence again: a second range is assigned and a duplicate entry is written. Sequence assignment is therefore at-least-once under ambiguous failures.Clients cannot guard against this themselves:
ExpectedVersionIdis rejected for sequential keys (db_sequences.goreturnsErrBadVersionId— "Cannot set an expected version id when key is sequential"), so there is no conditional-insert escape hatch.Proposal
Server-side deduplication keyed by a client-supplied idempotency token:
(client id, request id)) to sequencePuts; the SDK reuses the same token across internal retries.This makes sequence assignment exactly-once end-to-end under ambiguous failures. Primary beneficiary: offset assignment in Ursa-style usage, where a duplicate assignment produces a duplicate offset range and index entry.