Skip to content

[Testing]: Record callback terminal completions as updated operations #860

Open

Description

@zhongkechen

Split from PR #795 — match replay state to the service, reference commit f8ac9b4; baseline main is d7ae95571c44b18c2a2efdef9a308b1c916c5049. This issue owns one independently implementable slice of that PR. Start a focused branch from current main and port only this slice, rather than stacking on the full PR.

Problem and reproduction

Execution.complete_callback_success, complete_callback_failure, and complete_callback_timeout update operation state and its sequence but do not consistently record the operation ID in updated_operation_ids on the baseline. A callback that finishes outside the handler can therefore resume with terminal state but missing updated-operation metadata, causing its first externally delivered completion to look like ordinary replay.

Create a STARTED callback in an execution, complete it through each supported outcome, persist/reload, and build the next invocation input. Its ID must appear in UpdatedOperationIds; the terminal result/error and status must accompany the first delivery.

Scope and implementation

  • Use the existing _record_updated_operation helper after each accepted callback terminal state change, keeping the update atomic with the existing state mutation.
  • Preserve current sequence/timestamp/result/error logic and validation of unknown or already-terminal callbacks.
  • Keep ID insertion idempotent. Rejected completions must not alter the list or create another successful state transition.

Primary code: the three completion methods in execution.py. Their existing executor/public-runner entry points are the integration surface; no new producer or generic delivery scheduler is needed.

Acceptance criteria

  • Success, explicit failure, and timeout each add the callback's ID once after a successful state transition.
  • Unknown/already-terminal callbacks are rejected without changing pending IDs or the recorded terminal result.
  • Cover sequence accounting and persistence in both memory and filesystem stores.
  • A suspended public handler resumes with the callback in InvocationStartInfo.updated_operations; its first observed terminal hook has the correct status/result/error and is_replayed=False before the dependent step runs.
  • Resume/replay preserves completed step outcomes; unrelated callback IDs/results are untouched.

Reference tests

Start with test_callback_completion_records_only_successful_state_changes and the first-delivery portion of test_callback_update_is_consumed_before_user_code. Keep this slice's tests focused on creating the correct update, rather than requiring the complete multi-resume acknowledgment behavior from the reference.

Independence

This producer fix can land directly on main; it does not need replay pruning, flag projection, empty-error normalization, or the acknowledgment fix. Use a nonempty error in the failure control to avoid coupling to the empty-error issue. The separate acknowledgment issue owns when delivered IDs are removed, including failed delivery and newer concurrent updates. Combined multi-barrier regressions can be added after both land, but they are not a prerequisite for this smaller PR. This also does not change OTel deduplication or core plugin hook scheduling.

Validation and evidence

Add a regression that fails on main without this fix and passes with this slice alone. Run from the repository root:

hatch run dev-testing:test
hatch run dev-testing:typecheck
hatch run dev-testing:js-examples

Use the repository's CI-pinned Hatch version (1.16.5 at the reference) and Node.js 22+ for the JS harness; run hatch fmt --check from packages/aws-durable-execution-sdk-python-testing. Use public-handler integration tests for cross-component behavior and both memory/filesystem stores where relevant. List changed test expectations and their reasons in the implementing PR.

The service-parity expectations are carried forward from #795. This split does not independently verify them against deployed AWS Lambda; cite service evidence or mark the external assumption unverified before claiming deployed-service qualification. Shared conformance work belongs to #796 / conformance PR #131; coordinate new requirements there.

Related issues in this split

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugpkg:testingPackage: aws-durable-execution-sdk-python-testing

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions