Skip to content

feat: add custom extension operations API - #607

Open
zhongkechen wants to merge 46 commits into
mainfrom
codex/extension-operation-refactor
Open

feat: add custom extension operations API#607
zhongkechen wants to merge 46 commits into
mainfrom
codex/extension-operation-refactor

Conversation

@zhongkechen

@zhongkechen zhongkechen commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Issue Link, if available

Closes #571

Description

  • Add the public ExtensionContext and ExtensionOperation SPI for composing SDK-owned durable primitives with stable reservations, custom subtypes, stateful step replay, and configurable child contexts.
  • Route customer-facing operations through singular Durable*Operation facades and move backend engines into the primitive package.
  • Add operation-owned nested config types while preserving existing DurableContext, ParallelDurableFuture, and compatibility config APIs.
  • Implement map, parallel, callback, condition, and retry operations on the extension path while preserving checkpoint/replay, plugin, retry, and serialization behavior.
  • Add extension author documentation and ADR-006.
  • PR #611, which migrates the experimental DAG support to the extension SPI, is a concrete example of using this new SPI.

Demo/Screenshots

Not applicable. This change adds Java SDK APIs and internal architecture; no visual interface is changed.

Checklist

  • I have filled out every section of the PR template
  • I have thoroughly tested this change

Testing

Unit Tests

Yes. Added and updated unit coverage for extension reservations, stateful steps, child-context replay, operation facades/config conversion, primitive implementations, deterministic IDs, plugin metadata, and compatibility APIs.

Full SDK result: 1,202 tests passed.

Integration Tests

Yes. Added integration coverage for extension operations, static operation facades, extension concurrency, plugins, replay, callbacks, retries, map, and parallel behavior.

Full integration result: 413 tests passed.

Examples

No new example was required. Existing examples remain source-compatible and passed their test suite: 120 tests passed, with 34 cloud-only tests skipped by default.

Verification command:

mvn clean install

The OpenTelemetry module also passed 163 tests. Spotless and diff checks pass.

@zhongkechen
zhongkechen had a problem deploying to ai-pr-review-runtime August 20, 2026 03:47 — with GitHub Actions Failure
@zhongkechen
zhongkechen temporarily deployed to ai-pr-review-runtime August 20, 2026 03:47 — with GitHub Actions Inactive
Comment thread sdk/src/main/java/software/amazon/lambda/durable/model/OperationIdentifier.java Outdated
@github-actions

This comment has been minimized.

@zhongkechen
zhongkechen temporarily deployed to ai-pr-review-runtime August 20, 2026 04:50 — with GitHub Actions Inactive
@zhongkechen
zhongkechen had a problem deploying to ai-pr-review-runtime August 20, 2026 04:50 — with GitHub Actions Failure
@github-actions

This comment has been minimized.

@zhongkechen
zhongkechen had a problem deploying to ai-pr-review-runtime August 20, 2026 17:31 — with GitHub Actions Failure
@zhongkechen
zhongkechen temporarily deployed to ai-pr-review-runtime August 20, 2026 17:31 — with GitHub Actions Inactive
@zhongkechen
zhongkechen had a problem deploying to ai-pr-review-runtime August 20, 2026 18:41 — with GitHub Actions Failure
@zhongkechen
zhongkechen temporarily deployed to ai-pr-review-runtime August 20, 2026 18:41 — with GitHub Actions Inactive
Comment on lines +295 to +297
if (activeThreads.isEmpty()
&& waitState.compareAndSet(FutureWaitState.WAITING, FutureWaitState.SUSPENDED)) {
suspendForNoActiveThreads();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex AI review

[P1] Avoid losing a completion while committing suspension. After the CAS sets SUSPENDED, the future can complete before suspendForNoActiveThreads() runs; completeFutureWait() then returns without re-registering the thread, and execution suspends despite the awaited future being complete. If no durable work remains, this can leave the execution pending indefinitely. Introduce a SUSPENDING handshake so completion can still win until suspension is committed, and add a race test that completes the future immediately after this transition.

var future = context.reserve(contextName)
.runInChildContextAsync(
OperationSubType.WITH_RETRY.getValue(),
new TypeToken<Object>() {},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex AI review

[P1] Preserve the retry result type. This erases T to Object, but ChildContextPrimitive round-trips results through this token by default. With JacksonSerDes, a POJO becomes a LinkedHashMap and generic element types are lost, causing casts from the new public withRetry API to fail on first execution or replay. Require or add Class<T>/TypeToken<T> overloads and pass that token here; cover POJO and generic results across replay.

Comment on lines +101 to +103
return details != null && details.result() != null
? deserializeResult(details.result())
: extensionConfig.initialState();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex AI review

[P1] Distinguish a checkpointed null state from missing state. ExtensionStepResult.retry(null, ...) is valid, but after suspension a PENDING/READY operation has stepDetails.result() == null, so this restores initialState instead of the checkpointed null. That changes extension behavior between initial execution and replay. Determine state presence from the attempt/status or checkpoint an explicit state envelope, and test a non-null initial state followed by retry(null, ...) across replay.

@github-actions

Copy link
Copy Markdown
Contributor

Codex AI review

Found three correctness issues affecting suspension races, typed retry results, and replayed extension state.

Reviewed commit e416145586413569dc52e041245deb58e16f4606. Workflow run

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Add a public API for custom extension operations

1 participant