Skip to content

One idempotency key per logical request across retry attempts #73

Description

@Wahbeh-Mohammad

Part of the audit remediation umbrella #67. Milestone 3. Severity: HIGH. Requirements: RECOV-32, RETRY-38.

Current SDK behavior

The @public TSDoc of idempotencyKeyStep
(packages/core/src/recovery/idempotency-key.ts:33-35) says: "Runs ONCE per call, upstream of
retry — not per attempt … so the server sees one stable key across every retry of the same
logical request."

The retry composition does the opposite. retry-dispatch.ts:24 calls dispatchWithRecovery
for each attempt. orchestrator.ts:59 runs requestChain.apply() inside it. engine.ts:351
re-sends the captured template, which never carries the header. generate() runs once per
attempt. Three attempts of one request produce three different keys.
retry-dispatch.test.ts:67 asserts this by name: "re-runs the request recovery chain on every
attempt".

dispatchWithRetry is @internal, so no consumer can build this composition today. Commit
1f48926 promoted idempotencyKeyStep and IdempotencyKeyOptions to @public, which
publishes the claim.

Expected behavior

The SDK sends the same idempotency key on every attempt of one logical request. The
idempotencyKeyStep TSDoc describes the layering the code has. The retry engine's test names
the behavior it proves.

Notes and leads

  • Two layerings satisfy the contract. (a) Run the request recovery chain once, above the retry
    loop, and let each attempt copy the prepared request; attempt-stamp then writes the ordinal
    on the copy (RETRY-38 already preserves the key). (b) Memoize the key per logical request,
    keyed on the template, so re-application is a no-op. (a) matches the TSDoc; (b) is smaller.
  • Check recovery/orchestrator.ts for other request steps that must not re-run per attempt
    (client identity, auth stamps). The same question applies to them.
  • Tests: N attempts, one generate() call, identical header on every wire send. Rename
    retry-dispatch.test.ts:67.
  • Behavior change on an internal path plus a public doc: patch changeset for @dexpace/core.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

area:coreCore HTTP, IO, body, context, encoding: HTTP-* IO-* BODY-* CTX-* UTF-*area:resilienceRetry, recovery, redirects: RETRY-* RECOV-* REDIR-*type:bugDefect in shipped behavior

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions