Skip to content

Commit 77938c5

Browse files
committed
fix anyOf with empty map
1 parent 7678056 commit 77938c5

3 files changed

Lines changed: 26 additions & 6 deletions

File tree

sdk-integration-tests/src/test/java/software/amazon/lambda/durable/MapIntegrationTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -928,4 +928,20 @@ void testMultipleMapAsyncInParallel() {
928928
assertEquals(ExecutionStatus.SUCCEEDED, result.getStatus());
929929
assertEquals("2,4,6|A,B|olleh,dlrow,oof,rab", result.getResult(String.class));
930930
}
931+
932+
@Test
933+
void testMapWithEmptyItems() {
934+
var runner = LocalDurableTestRunner.create(String.class, (input, context) -> {
935+
List<String> items = List.of();
936+
var result = context.map("empty-map", items, String.class, (item, index, ctx) -> item);
937+
938+
assertTrue(result.allSucceeded());
939+
assertEquals(0, result.size());
940+
assertTrue(result.results().isEmpty());
941+
return "done";
942+
});
943+
944+
var result = runner.runUntilComplete("test");
945+
assertEquals(ExecutionStatus.SUCCEEDED, result.getStatus());
946+
}
931947
}

sdk/src/main/java/software/amazon/lambda/durable/context/DurableContextImpl.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
import software.amazon.lambda.durable.operation.StepOperation;
4444
import software.amazon.lambda.durable.operation.WaitForConditionOperation;
4545
import software.amazon.lambda.durable.operation.WaitOperation;
46-
import software.amazon.lambda.durable.util.CompletedDurableFuture;
4746
import software.amazon.lambda.durable.util.ParameterValidator;
4847

4948
/**
@@ -256,11 +255,6 @@ public <I, O> DurableFuture<MapResult<O>> mapAsync(
256255
config = config.toBuilder().serDes(getDurableConfig().getSerDes()).build();
257256
}
258257

259-
// Short-circuit for empty collections — no checkpoint overhead
260-
if (items.isEmpty()) {
261-
return new CompletedDurableFuture<>(MapResult.empty());
262-
}
263-
264258
// Convert to List for deterministic index-based access
265259
var itemList = List.copyOf(items);
266260
var operationId = nextOperationId();

sdk/src/main/java/software/amazon/lambda/durable/operation/MapOperation.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ private static Integer getToleratedFailureCount(CompletionConfig completionConfi
111111

112112
@Override
113113
protected void start() {
114+
if (items.isEmpty()) {
115+
return;
116+
}
114117
sendOperationUpdateAsync(OperationUpdate.builder()
115118
.action(OperationAction.START)
116119
.subType(getSubType().getValue()));
@@ -120,6 +123,10 @@ protected void start() {
120123

121124
@Override
122125
protected void replay(Operation existing) {
126+
if (items.isEmpty()) {
127+
markAlreadyCompleted();
128+
return;
129+
}
123130
switch (existing.status()) {
124131
case SUCCEEDED -> {
125132
if (existing.contextDetails() != null
@@ -194,6 +201,9 @@ protected void handleCompletion(ConcurrencyCompletionStatus concurrencyCompletio
194201

195202
@Override
196203
public MapResult<O> get() {
204+
if (items.isEmpty()) {
205+
return MapResult.empty();
206+
}
197207
if (replayFromPayload) {
198208
// Small result replay: deserialize MapResult directly from checkpoint payload
199209
var op = waitForOperationCompletion();

0 commit comments

Comments
 (0)