Skip to content

docs(power): "Step Semantics Deep Dive" example op mismatched with its semantic #182

@yaythomas

Description

@yaythomas

The Step Semantics Deep Dive section in aws-lambda-durable-functions-power/steering/advanced-patterns.md has a remaining pedagogical mismatch after #174 and #175 land their narrower fixes.

Code example op is mismatched with its semantic

await context.step(
  'update-database',
  async () => {
    // This is idempotent - safe to retry
    return await updateUserRecord(userId, data);
  },
  { semantics: StepSemantics.AtMostOncePerRetry }
);

updateUserRecord is idempotent, and the inline comment even says so. Pairing it with AtMostOncePerRetry teaches the opposite of what the SDK intends — at-most-once is the semantic for non-idempotent operations where duplicates would be user-visible or harmful. The SDK's own JSDoc at step.ts:55–59 uses processPayment() in this slot, which is the canonical teaching example.

Suggested rewrite of that block:

await context.step(
  'charge-payment',
  async () => {
    // Non-idempotent - duplicates would double-charge the customer
    return await chargePayment(customerId, amount);
  },
  {
    semantics: StepSemantics.AtMostOncePerRetry,
    // Pair with shouldRetry: false to guarantee at-most-once overall,
    // since the default retry strategy still allows multiple retry attempts.
    retryStrategy: () => ({ shouldRetry: false }),
  }
);

The AtLeastOncePerRetry block (send-notification / sendEmail) is also a little awkward — emails with no external dedup would actually benefit from AtMostOncePerRetry. A clearer example would be a queue send or a metrics emit where duplicates are tolerable.

Context

Surfaced during review of #174 and #175, which fix the (DEFAULT) label and the use-case column labels respectively. Those narrower PRs are correct as-is; this issue tracks the cohesive example-selection rewrite.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions