Skip to content

feature: ConcurrencyOperation and Parallel#201

Merged
wangyb-A merged 6 commits intomainfrom
feat/parallel
Mar 16, 2026
Merged

feature: ConcurrencyOperation and Parallel#201
wangyb-A merged 6 commits intomainfrom
feat/parallel

Conversation

@wangyb-A
Copy link
Copy Markdown
Contributor

@wangyb-A wangyb-A commented Mar 12, 2026

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

Description

  • Add parallel design from ParidelPooya @
  • Add basic parallel operation

Demo/Screenshots

iShot_2026-03-16_16 37 38

Note that the hierarchy is not correct, will be fixed in the follow up PRs

Checklist

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

Testing

Unit Tests

Have unit tests been written for these changes? Yes

Integration Tests

Have integration tests been written for these changes? Not yet

Examples

Has a new example been added for the change? (if applicable) Yes

@wangyb-A wangyb-A requested a review from a team March 12, 2026 23:07
Comment thread docs/core/parallel.md
Comment thread docs/core/parallel.md
Comment thread docs/core/parallel.md
Comment thread docs/core/parallel.md
@wangyb-A wangyb-A changed the title Add parallel design feature: ConcurrencyOperation and Parallel Mar 13, 2026
* prefixed with the parent hashed contextId (e.g. "<hash>-1", "<hash>-2" inside parent context <hash>). This
* matches the Python SDK's stepPrefix convention and prevents ID collisions in checkpoint batches.
*/
private String nextOperationId() {
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.

This change will not be required with this PR: #206

Comment thread docs/core/parallel.md
Comment thread sdk/pom.xml
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
<scope>test</scope>
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.

why is this needed for test?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It's for local debugging

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.

Let's not add additional dependencies, especially for sdk module, unless it's very necessary.

TypeToken<T> resultTypeToken,
SerDes resultSerDes,
DurableContext durableContext) {
this(operationIdentifier, function, resultTypeToken, resultSerDes, durableContext, null);
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.

adding a callback to the completableFuture like in Map seems a cleaner solution than this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agree, that's on my following up refactoring list

@wangyb-A wangyb-A merged commit 03dd8c0 into main Mar 16, 2026
11 checks passed
return;
}
joined = true;
parallelOperation.get();
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.

Can we return a state of all branches here, like the map operation returns List<MapResultItem>. For Parallel, we can return something similar, just without the result of branches.

import software.amazon.lambda.durable.operation.ParallelOperation;

/** User-facing context for managing parallel branch execution within a durable function. */
public class ParallelContext implements AutoCloseable {
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.

Let's make this a subclass of DurableFuture, so that this can be used with the other utilities such as allOf

@Override
protected void handleFailure(ConcurrencyCompletionStatus concurrencyCompletionStatus) {
sendOperationUpdate(OperationUpdate.builder()
.action(OperationAction.FAIL)
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.

I think parallel operation always succeed no matter the children succeed or fail

case MAP -> throw new ChildContextFailedException(op);
case MAP_ITERATION -> throw new ChildContextFailedException(op);
case PARALLEL -> throw new ChildContextFailedException(op);
case PARALLEL_BRANCH -> throw new ChildContextFailedException(op);
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.

We should throw parallel specific exceptions here.

public enum ConcurrencyCompletionStatus {
ALL_COMPLETED,
MIN_SUCCESSFUL_REACHED,
MIN_SUCCESSFUL_NOT_REACHED,
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.

What's the purpose of this value MIN_SUCCESSFUL_NOT_REACHED

@zhongkechen zhongkechen deleted the feat/parallel branch March 30, 2026 19:58
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.

2 participants