Skip to content

feat: add custom map iteration naming - #585

Merged
wangyb-A merged 5 commits into
mainfrom
feature/map-item-namer-fresh
Aug 4, 2026
Merged

feat: add custom map iteration naming#585
wangyb-A merged 5 commits into
mainfrom
feature/map-item-namer-fresh

Conversation

@wangyb-A

@wangyb-A wangyb-A commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add MapConfig.itemNamer for custom nested map-iteration names
  • add a typed itemNamer(Class<I>, BiFunction<? super I, Integer, String>) overload so domain-object namers need no cast
  • preserve a null namer result as an unnamed iteration
  • resolve and validate names before allocating the map operation ID
  • reject itemNamer with NestingType.FLAT, whose virtual iterations have no context operation to name
  • detect changed iteration names when replaying STARTED and cached SUCCEEDED maps
  • implement Java conformance requirement 9-13

Item namer API

Untyped form (unchanged):

MapConfig.builder()
        .itemNamer((item, index) -> item + "-" + index)
        .build();

Typed form for domain objects:

MapConfig.builder()
        .itemNamer(Order.class, (order, index) -> order.id())
        .build();

The typed overload bridges through Class#cast, so it needs no @SuppressWarnings("unchecked") and a mismatched item class fails with a ClassCastException naming the offending type. MapConfig stays non-generic, so no raw-type warnings are introduced for existing callers.

Compatibility

  • MapConfig remains non-generic
  • the original public MapOperation constructor is retained as a delegating overload
  • existing DurableContext method signatures are unchanged
  • default map iteration naming is unchanged when no item namer is configured

Validation

  • mvn -pl sdk test — 1110 passed
  • mvn -pl sdk-integration-tests test — 393 passed
  • mvn -pl conformance-tests package -DskipTests — passed
  • mvn spotless:check — passed
  • javac -Xlint:unchecked,rawtypes — no warnings in the item-namer files
  • real deployed map conformance run is pending

Closes #528

@wangyb-A
wangyb-A temporarily deployed to ai-pr-review-runtime July 31, 2026 23:58 — with GitHub Actions Inactive
@wangyb-A
wangyb-A had a problem deploying to ai-pr-review-runtime July 31, 2026 23:58 — with GitHub Actions Failure
@github-actions

This comment has been minimized.

Comment thread sdk/src/main/java/software/amazon/lambda/durable/context/DurableContextImpl.java Outdated
@wangyb-A
wangyb-A temporarily deployed to ai-pr-review-runtime August 1, 2026 00:31 — with GitHub Actions Inactive
@wangyb-A
wangyb-A temporarily deployed to ai-pr-review-runtime August 1, 2026 00:31 — with GitHub Actions Inactive
@github-actions

This comment has been minimized.

Comment thread sdk/src/main/java/software/amazon/lambda/durable/context/DurableContextImpl.java Outdated
@github-actions

This comment has been minimized.

@wangyb-A
wangyb-A temporarily deployed to ai-pr-review-runtime August 4, 2026 20:26 — with GitHub Actions Inactive
@wangyb-A
wangyb-A temporarily deployed to ai-pr-review-runtime August 4, 2026 20:26 — with GitHub Actions Inactive
@github-actions

This comment has been minimized.

Comment thread sdk/src/main/java/software/amazon/lambda/durable/context/DurableContextImpl.java Outdated
@wangyb-A
wangyb-A force-pushed the feature/map-item-namer-fresh branch from 6818465 to 3e65ac0 Compare August 4, 2026 21:40
@aws aws deleted a comment from github-actions Bot Aug 4, 2026
@wangyb-A
wangyb-A temporarily deployed to ai-pr-review-runtime August 4, 2026 21:44 — with GitHub Actions Inactive
@wangyb-A
wangyb-A temporarily deployed to ai-pr-review-runtime August 4, 2026 21:44 — with GitHub Actions Inactive
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@wangyb-A
wangyb-A force-pushed the feature/map-item-namer-fresh branch from 3e65ac0 to b186199 Compare August 4, 2026 22:05
@wangyb-A
wangyb-A temporarily deployed to ai-pr-review-runtime August 4, 2026 22:06 — with GitHub Actions Inactive
@wangyb-A
wangyb-A temporarily deployed to ai-pr-review-runtime August 4, 2026 22:06 — with GitHub Actions Inactive
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@wangyb-A
wangyb-A marked this pull request as ready for review August 4, 2026 22:36
@wangyb-A
wangyb-A requested a review from a team August 4, 2026 22:36
@wangyb-A
wangyb-A temporarily deployed to ai-pr-review-runtime August 4, 2026 22:36 — with GitHub Actions Inactive
@wangyb-A
wangyb-A temporarily deployed to ai-pr-review-runtime August 4, 2026 22:36 — with GitHub Actions Inactive
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

Codex AI review

  • [P2] Cached-map validation depends on unavailable child checkpointssdk/src/main/java/software/amazon/lambda/durable/operation/MapOperation.java:167: Small completed maps use replayChildren=false, so replay state may contain only the parent map operation. In that case checkpointed is null for every branch and changed or removed item names pass silently. Persist iteration names or a digest in the parent checkpoint, or request child replay for named maps. Add a test whose replay state contains only the completed parent map.

Reviewed commit b18619902ea672933e3fb2280f95f2e983daab43. Workflow run

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

Claude AI review

Reviewed PR #585 (custom map iteration naming). Traced the changed code against the map/concurrency/replay machinery.

Verified correct:

  • resolveIterationNames runs in DurableContextImpl.mapAsync before nextOperationId(), with per-name validation via ParameterValidator.validateOperationName, so an invalid name throws without consuming an operation ID.
  • The namer is invoked exactly once per invocation: the SDK uses the new 7-arg MapOperation constructor (no re-resolve); the retained 6-arg constructor is for external API compatibility only.
  • validateIterationNamesAgainstCheckpoint matches branches to checkpointed children by stable, deterministic operation ID (not name), runs before the SUCCEEDED small/large split and in the STARTED branch, and correctly treats a preserved null name as equal on replay. This adds real coverage for the cached small-result path.
  • FLAT-nesting rejection is enforced at build time for untyped and typed (wrapped) namers; null namer leaves default naming; toBuilder() round-trips both fields.
  • Empty maps never invoke the namer (loop bounded by items.size()).
  • Typed overload bridges via Class#cast (no unchecked warning), throws ClassCastException on mismatch and NPE on null itemType; the iterationNames.size() == items.size() guard is present.

Findings: None confirmed. Implementation is correct and well tested (7 new integration tests, 8 unit tests, conformance handler 9-13).

Residual test risk:

  • Null iteration-name replay passes locally because LocalDurableTestRunner round-trips null → null. If the deployed backend normalizes a null operation name to "", validateIterationNamesAgainstCheckpoint would raise a false NonDeterministicExecutionException (sdk/src/main/java/software/amazon/lambda/durable/operation/MapOperation.java:541). The PR already notes the deployed map conformance run is pending — that run should confirm this case.
  • No direct test for a changed name on the large-result replay-children path (MapOperation.java:227, covered indirectly by the pre-split validation) or for duplicate names across iterations (safe by design since identity is ID-based, but unverified for observability).

Reviewed commit b18619902ea672933e3fb2280f95f2e983daab43. Workflow run

@wangyb-A
wangyb-A merged commit b01bb5f into main Aug 4, 2026
34 of 37 checks passed
@wangyb-A
wangyb-A deleted the feature/map-item-namer-fresh branch August 4, 2026 23:31
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]: Item namer for map operation

2 participants