Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/scripts/maven_publish.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ echo "settings.xml written."
echo "=== Step 3: Upload to Sonatype Central Portal ==="

mvn clean deploy -s "${SETTINGS_FILE}" -pl sdk -P publishing -DskipTests --no-transfer-progress
mvn clean deploy -s "${SETTINGS_FILE}" -pl dag -P publishing -DskipTests --no-transfer-progress
mvn clean deploy -s "${SETTINGS_FILE}" -pl sdk-testing -P publishing -DskipTests --no-transfer-progress
mvn clean deploy -s "${SETTINGS_FILE}" -pl otel-plugin -P publishing -DskipTests --no-transfer-progress

Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ on:
- '.github/workflows/ai-pr-review.yml'
- '.github/prompts/ai-pr-review.md'
- 'sdk/**'
- 'dag/**'
- 'sdk-testing/**'
- 'sdk-integration-tests/**'
- 'examples/**'
Expand All @@ -38,6 +39,7 @@ on:
- '.github/workflows/ai-pr-review.yml'
- '.github/prompts/ai-pr-review.md'
- 'sdk/**'
- 'dag/**'
- 'sdk-testing/**'
- 'sdk-integration-tests/**'
- 'examples/**'
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
paths:
- '.github/**' # for testing Github Actions
- 'sdk/**'
- 'dag/**'
- 'sdk-testing/**'
- 'sdk-integration-tests/**'
- 'examples/**'
Expand All @@ -18,6 +19,7 @@ on:
paths:
- '.github/**'
- 'sdk/**'
- 'dag/**'
- 'sdk-testing/**'
- 'sdk-integration-tests/**'
- 'examples/**'
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/publish_maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ jobs:
run: |
gh release upload "$RELEASE_TAG" \
"sdk/target/aws-durable-execution-sdk-java-${RELEASE_VERSION}.jar" \
"dag/target/aws-durable-execution-sdk-java-dag-${RELEASE_VERSION}.jar" \
"sdk-testing/target/aws-durable-execution-sdk-java-testing-${RELEASE_VERSION}.jar" \
"otel-plugin/target/aws-durable-execution-sdk-java-plugin-otel-${RELEASE_VERSION}.jar" \
--clobber
Expand Down
9 changes: 5 additions & 4 deletions RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ The publication workflow:

1. Verifies that the tag is a semantic version, points to a commit on the
default branch, and matches the Maven version in the tagged POM.
2. Builds, signs, and uploads the SDK, testing library, and OpenTelemetry plugin
to Sonatype Central Portal.
3. Uploads the three JARs to the existing GitHub release.
2. Builds, signs, and uploads the SDK, DAG extension, testing library, and
OpenTelemetry plugin to Sonatype Central Portal.
3. Uploads the four JARs to the existing GitHub release.
4. Opens a pull request for the next development version. A final release
increments the patch version, so `2.1.1` produces `2.1.2-SNAPSHOT`. A
prerelease keeps the same base version, so `2.1.1-rc1` produces
Expand All @@ -56,7 +56,8 @@ After **Publish Maven Release** succeeds:
1. Open [Publishing Deployments](https://central.sonatype.com/publishing/deployments)
in Sonatype Central Portal.
2. Find the deployments for the release version and verify that they contain
the expected SDK, testing library, and OpenTelemetry plugin artifacts.
the expected SDK, DAG extension, testing library, and OpenTelemetry plugin
artifacts.
3. Click **Publish** for each deployment and wait for publication to complete.
The workflow uses `autoPublish=false`, so this manual action is required.
4. Confirm that the GitHub release contains the expected JARs and that the
Expand Down
5 changes: 5 additions & 0 deletions coverage-report/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
<artifactId>aws-durable-execution-sdk-java</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>software.amazon.lambda.durable</groupId>
<artifactId>aws-durable-execution-sdk-java-dag</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>software.amazon.lambda.durable</groupId>
<artifactId>aws-durable-execution-sdk-java-testing</artifactId>
Expand Down
106 changes: 106 additions & 0 deletions dag/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>software.amazon.lambda.durable</groupId>
<artifactId>aws-durable-execution-sdk-java-parent</artifactId>
<version>2.1.1-SNAPSHOT</version>
</parent>

<artifactId>aws-durable-execution-sdk-java-dag</artifactId>
<packaging>jar</packaging>

<name>AWS Lambda Durable Execution SDK DAG Extension</name>
<description>Experimental DAG extension for the AWS Lambda Durable Execution SDK</description>
<url>https://github.com/aws/aws-durable-execution-sdk-java</url>

<scm>
<connection>scm:git:https://github.com/aws/aws-durable-execution-sdk-java.git</connection>
<developerConnection>scm:git:https://github.com/aws/aws-durable-execution-sdk-java.git</developerConnection>
<url>https://github.com/aws/aws-durable-execution-sdk-java</url>
</scm>

<dependencies>
<dependency>
<groupId>software.amazon.lambda.durable</groupId>
<artifactId>aws-durable-execution-sdk-java</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>

<dependency>
<groupId>software.amazon.lambda.durable</groupId>
<artifactId>aws-durable-execution-sdk-java-testing</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package software.amazon.lambda.durable.dag;

import java.util.Objects;
import java.util.function.Function;

/**
* Custom-predicate DAG completion: a deterministic predicate evaluated over the DAG's live progress and task results
* after every task settlement.
*
* @param shouldComplete the predicate; receives a {@link DagCompletionStatus} snapshot of everything settled so far
* @apiNote <b>Experimental.</b> This API is experimental and may be changed or removed in future releases without a
* major-version bump.
*/
@Experimental
public record CustomDagCompletion(Function<DagCompletionStatus, DagCompletionDecision> shouldComplete)
implements DagCompletionConfig {
public CustomDagCompletion {
Objects.requireNonNull(shouldComplete, "shouldComplete cannot be null");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package software.amazon.lambda.durable.dag;

import software.amazon.lambda.durable.StepContext;

/**
* A DAG callback submitter: receives resolved upstream results ({@link Deps}), the generated callback ID, and a
* {@link StepContext}. Mirrors the native {@code BiConsumer<String, StepContext>} submitter shape plus {@link Deps}.
*
* @apiNote <b>Experimental.</b> This API is experimental and may be changed or removed in future releases without a
* major-version bump.
*/
@Experimental
@FunctionalInterface
public interface DagCallbackSubmitter {
void apply(Deps deps, String callbackId, StepContext ctx);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package software.amazon.lambda.durable.dag;

import software.amazon.lambda.durable.DurableContext;

/**
* A DAG runInChildContext task body: receives resolved upstream results ({@link Deps}) and a child
* {@link DurableContext}.
*
* @param <T> the child context result type
* @apiNote <b>Experimental.</b> This API is experimental and may be changed or removed in future releases without a
* major-version bump.
*/
@Experimental
@FunctionalInterface
public interface DagChildFunction<T> {
T apply(Deps deps, DurableContext childCtx);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package software.amazon.lambda.durable.dag;

import java.util.function.Function;
import software.amazon.lambda.durable.config.CompletionConfig;

/**
* Controls when a DAG completes: threshold-based, via the six factory methods below (mirroring the base SDK's
* {@code CompletionConfig} factories), or a custom, results-aware predicate via {@link #custom(Function)}. This sealed
* interface permits {@link ThresholdDagCompletion} and {@link CustomDagCompletion}.
*
* @apiNote <b>Experimental.</b> This API is experimental and may be changed or removed in future releases without a
* major-version bump.
*/
@Experimental
public sealed interface DagCompletionConfig permits ThresholdDagCompletion, CustomDagCompletion {

/** Every task must complete; failures tolerated (captured per-task). */
static DagCompletionConfig allCompleted() {
return new ThresholdDagCompletion(CompletionConfig.allCompleted());
}

/** Every task must succeed; zero failures tolerated. */
static DagCompletionConfig allSuccessful() {
return new ThresholdDagCompletion(CompletionConfig.allSuccessful());
}

/** Complete as soon as the first task succeeds. */
static DagCompletionConfig firstSuccessful() {
return new ThresholdDagCompletion(CompletionConfig.firstSuccessful());
}

/** Complete when {@code n} tasks have succeeded. */
static DagCompletionConfig minSuccessful(int n) {
return new ThresholdDagCompletion(CompletionConfig.minSuccessful(n));
}

/** Complete when more than {@code n} failures have occurred. */
static DagCompletionConfig toleratedFailureCount(int n) {
return new ThresholdDagCompletion(CompletionConfig.toleratedFailureCount(n));
}

/** Complete when the failure percentage exceeds {@code p} (0.0 to 1.0). */
static DagCompletionConfig toleratedFailurePercentage(double p) {
return new ThresholdDagCompletion(CompletionConfig.toleratedFailurePercentage(p));
}

/**
* Complete based on a custom, results-aware predicate evaluated after every task settlement.
*
* <p>Unlike the threshold factories above, this predicate can inspect individual tasks' results (via
* {@link DagCompletionStatus#items()} / {@link DagCompletionStatus#results()}), not just aggregate counts — for
* example, stopping the moment any task's result matches a business condition.
*
* @param shouldComplete receives a live {@link DagCompletionStatus} snapshot; return
* {@link DagCompletionDecision#continueDag()} to keep scheduling or
* {@link DagCompletionDecision#complete(DagCompletionOutcome)} to stop the DAG now
*/
static DagCompletionConfig custom(Function<DagCompletionStatus, DagCompletionDecision> shouldComplete) {
return new CustomDagCompletion(shouldComplete);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package software.amazon.lambda.durable.dag;

/**
* The value a DAG custom completion predicate returns.
*
* @param complete whether the DAG should complete now
* @param outcome the completion's disposition; only meaningful when {@code complete} is {@code true}, and defaults to
* {@link DagCompletionOutcome#SUCCEEDED} via {@link #complete()}
* @apiNote <b>Experimental.</b> This API is experimental and may be changed or removed in future releases without a
* major-version bump.
*/
@Experimental
public record DagCompletionDecision(boolean complete, DagCompletionOutcome outcome) {

/** Returns a decision meaning "keep scheduling ready tasks". */
public static DagCompletionDecision continueDag() {
return new DagCompletionDecision(false, null);
}

/** Returns a decision meaning "complete the DAG now" as a success. */
public static DagCompletionDecision completeSuccessfully() {
return new DagCompletionDecision(true, DagCompletionOutcome.SUCCEEDED);
}

/** Returns a decision meaning "complete the DAG now" with the given outcome. */
public static DagCompletionDecision complete(DagCompletionOutcome outcome) {
return new DagCompletionDecision(true, outcome == null ? DagCompletionOutcome.SUCCEEDED : outcome);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package software.amazon.lambda.durable.dag;

import java.util.Optional;

/**
* Per-task snapshot passed to a DAG custom completion predicate.
*
* @param name the task name
* @param status the task's status; {@link Optional#empty()} if the task has not started
* @param result present only when {@code status} is {@link TaskStatus#SUCCEEDED}
* @param skipReason present only when {@code status} is {@link TaskStatus#SKIPPED}
* @apiNote <b>Experimental.</b> This API is experimental and may be changed or removed in future releases without a
* major-version bump.
*/
@Experimental
public record DagCompletionItemStatus(
String name, Optional<TaskStatus> status, Optional<Object> result, Optional<SkipReason> skipReason) {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package software.amazon.lambda.durable.dag;

/**
* The terminal disposition a custom DAG completion predicate assigns to an early completion.
*
* @apiNote <b>Experimental.</b> This API is experimental and may be changed or removed in future releases without a
* major-version bump.
*/
@Experimental
public enum DagCompletionOutcome {
/** Marks the early completion as a success. */
SUCCEEDED,
/** Marks the early completion as a failure, even if no individual task failed. */
FAILED
}
Loading
Loading