diff --git a/lambda-durable-parallel-execution-python-sam/README.md b/lambda-durable-parallel-execution-python-sam/README.md new file mode 100644 index 000000000..53a7dbb35 --- /dev/null +++ b/lambda-durable-parallel-execution-python-sam/README.md @@ -0,0 +1,171 @@ +# Parallel Execution of Math Operations with AWS Lambda durable functions + +This pattern demonstrates parallel execution of mathematical operations using AWS Lambda durable functions. The workflow executes addition, subtraction, multiplication, and division operations concurrently, showcasing the power of parallel execution in durable functions. + +## Architecture + +The pattern uses AWS Lambda durable functions to execute multiple mathematical operations in parallel, collecting all results before returning the final response. The durable function uses `context.parallel()` to execute multiple operations concurrently. + +```mermaid +graph LR + A[Lambda Invoke] --> B[Get num1 & num2] + B --> C{Parallel Execution} + + C --> D[Addition] + C --> E[Subtraction] + C --> F[Multiplication] + C --> G[Division] + + D --> H[Collect Results] + E --> H + F --> H + G --> H + + H --> I{Any Failures?} + I -->|No| J[Return Results] + I -->|Yes| K[Return Error] + + style C fill:#e1f5ff + style D fill:#d4edda + style E fill:#d4edda + style F fill:#d4edda + style G fill:#fff3cd + style J fill:#d4edda + style K fill:#f8d7da +``` + +### Workflow Steps + +1. **User invokes Lambda function** with two numbers (num1 and num2) +2. **Lambda durable functions parses input**, defaulting to 0 for missing values +3. **Four operations execute in parallel**: + - Addition: num1 + num2 + - Subtraction: num1 - num2 + - Multiplication: num1 * num2 + - Division: num1 / num2 +4. **Results collected** from all parallel operations +5. **Response returned** with all calculation results + +## Key Features + +- ✅ **Parallel Execution** - All four operations run concurrently +- ✅ **Error Handling** - Division by zero protection with custom retry strategy +- ✅ **Batch Results** - Collects all results before returning +- ✅ **Failure Detection** - Identifies if any operation failed +- ✅ **Configurable Retries** - Per-step retry configuration (division has no retries) +- ✅ **Structured Logging** - Detailed logging for each operation + +## Prerequisites + +* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured +* [AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) installed + +## Deployment + +1. Navigate to the pattern directory: + ```bash + cd lambda-durable-parallel-execution-python-sam + ``` + +2. Build the SAM application: + ```bash + sam build + ``` + +3. Deploy the application: + ```bash + sam deploy --guided + ``` + + During the guided deployment: + - Accept default values or customize as needed + - Allow SAM CLI to create IAM roles when prompted + +4. Note the `MathFunction` name from the outputs + +## Testing + +### Invoke with Valid Numbers + +```bash +aws lambda invoke \ + --function-name :live \ + --payload '{"num1": 10, "num2": 5}' \ + --cli-binary-format raw-in-base64-out \ + response.json + +cat response.json +``` + +Response: +```json +{ + "Add": 15, + "Subtract": 5, + "Multiply": 50, + "Division": 2.0 +} +``` + +### Test Division by Zero + +```bash +aws lambda invoke \ + --function-name :live \ + --payload '{"num1": 10, "num2": 0}' \ + --cli-binary-format raw-in-base64-out \ + response.json + +cat response.json +``` + +Response: +```json +{ + "error_details": "One or more operations failed" +} +``` + +### Test with Default Values + +```bash +aws lambda invoke \ + --function-name :live \ + --payload '{}' \ + --cli-binary-format raw-in-base64-out \ + response.json +``` + +Response (both numbers default to 0): +```json +{ + "error_details": "One or more operations failed" +} +``` + +## Use Cases + +- **Parallel Data Processing** - Execute multiple transformations concurrently +- **Multi-Service Calls** - Call multiple APIs in parallel and aggregate results +- **Batch Calculations** - Perform multiple calculations simultaneously +- **Validation Workflows** - Run multiple validation checks in parallel +- **Data Enrichment** - Enrich data from multiple sources concurrently + +## Cleanup + +```bash +sam delete --stack-name +``` + +## Learn More + +- [AWS Lambda durable functions documentation](https://docs.aws.amazon.com/lambda/latest/dg/durable-functions.html) +- [Durable Execution SDK (Python)](https://github.com/aws/aws-durable-execution-sdk-python) +- [Parallel Execution](https://github.com/aws/aws-durable-execution-sdk-python/blob/main/docs/core/parallel.md) +- [Retry Strategies](https://github.com/aws/aws-durable-execution-sdk-python/blob/main/docs/advanced/error-handling.md#retry-strategies) + +--- + +Copyright 2026 Amazon.com, Inc. or its affiliates. All Rights Reserved. + +SPDX-License-Identifier: MIT-0 diff --git a/lambda-durable-parallel-execution-python-sam/example-pattern.json b/lambda-durable-parallel-execution-python-sam/example-pattern.json new file mode 100644 index 000000000..f5602282a --- /dev/null +++ b/lambda-durable-parallel-execution-python-sam/example-pattern.json @@ -0,0 +1,76 @@ +{ + "title": "Parallel execution of operations with AWS Lambda durable functions", + "description": "Demonstrates parallel execution of operations using Lambda durable functions with batch result collection and error handling", + "language": "Python", + "level": "200", + "framework": "AWS SAM", + "introBox": { + "headline": "How it works", + "text": [ + "This pattern demonstrates parallel execution capabilities of AWS Lambda durable functions by performing four mathematical operations concurrently.", + "The workflow uses context.parallel() to execute addition, subtraction, multiplication, and division operations simultaneously on two input numbers.", + "Each operation is defined as a separate step with its own logging and error handling, showcasing the durable execution model.", + "The division operation uses a custom retry strategy (RetryPresets.none()) to prevent retries on division by zero errors.", + "Results from all parallel operations are collected using BatchResult, which tracks both successful results and failure counts.", + "If any operation fails, the workflow returns an error response; otherwise, it returns all calculation results in a structured JSON format." + ] + }, + "gitHub": { + "template": { + "repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/lambda-durable-parallel-execution-python-sam", + "templateURL": "serverless-patterns/lambda-durable-parallel-execution-python-sam", + "projectFolder": "lambda-durable-parallel-execution-python-sam", + "templateFile": "template.yaml" + } + }, + "resources": { + "bullets": [ + { + "text": "AWS Lambda durable functions documentation", + "link": "https://docs.aws.amazon.com/lambda/latest/dg/durable-functions.html" + }, + { + "text": "Durable Execution SDK for Python", + "link": "https://github.com/aws/aws-durable-execution-sdk-python" + }, + { + "text": "Parallel Execution", + "link": "https://github.com/aws/aws-durable-execution-sdk-python/blob/main/docs/core/parallel.md" + }, + { + "text": "Retry Strategies", + "link": "https://github.com/aws/aws-durable-execution-sdk-python/blob/main/docs/advanced/error-handling.md#retry-strategies" + } + ] + }, + "deploy": { + "text": [ + "sam build", + "sam deploy --guided" + ] + }, + "testing": { + "text": [ + "See the GitHub repo for detailed testing instructions." + ] + }, + "cleanup": { + "text": [ + "Delete the stack: sam delete." + ] + }, +"authors": [ + { + "name": "Anup Rajpara", + "image": "https://drive.google.com/file/d/1MqpPNLCqbU4kvvtTspNXZBqD99aVIJI9/view?usp=sharing", + "bio": "Anup is a Sr. Technical Account Manager at Amazon Web Services. He is passionate about serverless & event-driven architectures.", + "linkedin": "anup-rajpara-developer" + }, + { + "name": "Sahil Bhimjiani", + "image": "https://drive.google.com/file/d/1E2p7S5UtU36x6Sk1xPS3XnSGJyIUoqK7/view?usp=drivesdk", + "bio": "Sahil Bhimjiani is a Solutions Architect at Amazon Web Services.", + "linkedin": "sahil9701" + } + ] +} diff --git a/lambda-durable-parallel-execution-python-sam/lambda-durable-parallel-execution-python-sam.json b/lambda-durable-parallel-execution-python-sam/lambda-durable-parallel-execution-python-sam.json new file mode 100644 index 000000000..2425961ed --- /dev/null +++ b/lambda-durable-parallel-execution-python-sam/lambda-durable-parallel-execution-python-sam.json @@ -0,0 +1,84 @@ +{ + "title": "Parallel execution of operations with AWS Lambda durable functions", + "description": "Demonstrates parallel execution of operations using Lambda durable functions with batch result collection and error handling", + "language": "Python", + "level": "200", + "framework": "AWS SAM", + "introBox": { + "headline": "How it works", + "text": [ + "This pattern demonstrates parallel execution capabilities of AWS Lambda durable functions by performing four mathematical operations concurrently.", + "The workflow uses context.parallel() to execute addition, subtraction, multiplication, and division operations simultaneously on two input numbers.", + "Each operation is defined as a separate step with its own logging and error handling, showcasing the durable execution model.", + "The division operation uses a custom retry strategy (RetryPresets.none()) to prevent retries on division by zero errors.", + "Results from all parallel operations are collected using BatchResult, which tracks both successful results and failure counts.", + "If any operation fails, the workflow returns an error response; otherwise, it returns all calculation results in a structured JSON format." + ] + }, + "gitHub": { + "template": { + "repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/lambda-durable-parallel-execution-python-sam", + "templateURL": "serverless-patterns/lambda-durable-parallel-execution-python-sam", + "projectFolder": "lambda-durable-parallel-execution-python-sam", + "templateFile": "template.yaml" + } + }, + "resources": { + "bullets": [ + { + "text": "AWS Lambda durable functions documentation", + "link": "https://docs.aws.amazon.com/lambda/latest/dg/durable-functions.html" + }, + { + "text": "Durable Execution SDK for Python", + "link": "https://github.com/aws/aws-durable-execution-sdk-python" + }, + { + "text": "Parallel Execution", + "link": "https://github.com/aws/aws-durable-execution-sdk-python/blob/main/docs/core/parallel.md" + }, + { + "text": "Retry Strategies", + "link": "https://github.com/aws/aws-durable-execution-sdk-python/blob/main/docs/advanced/error-handling.md#retry-strategies" + } + ] + }, + "deploy": { + "text": [ + "sam build", + "sam deploy --guided" + ] + }, + "testing": { + "text": [ + "See the GitHub repo for detailed testing instructions." + ] + }, + "cleanup": { + "text": [ + "Delete the stack: sam delete." + ] + }, + "authors": [ + { + "name": "Anup Rajpara", + "image": "https://drive.google.com/file/d/1MqpPNLCqbU4kvvtTspNXZBqD99aVIJI9/view?usp=sharing", + "bio": "Anup is a Sr. Technical Account Manager at Amazon Web Services. He is passionate about serverless & event-driven architectures.", + "linkedin": "anup-rajpara-developer" + }, + { + "name": "Sahil Bhimjiani", + "image": "https://drive.google.com/file/d/1E2p7S5UtU36x6Sk1xPS3XnSGJyIUoqK7/view?usp=drivesdk", + "bio": "Sahil Bhimjiani is a Solutions Architect at Amazon Web Services.", + "linkedin": "sahil9701" + } + ], + "patternArch": { + "icon1": { + "x": 50, + "y": 50, + "service": "lambda", + "label": "AWS Lambda durable functions" + } + } +} diff --git a/lambda-durable-parallel-execution-python-sam/src/lambda_function.py b/lambda-durable-parallel-execution-python-sam/src/lambda_function.py new file mode 100644 index 000000000..c9627468f --- /dev/null +++ b/lambda-durable-parallel-execution-python-sam/src/lambda_function.py @@ -0,0 +1,57 @@ +from aws_durable_execution_sdk_python import BatchResult, DurableContext, durable_execution, durable_step +from aws_durable_execution_sdk_python.retries import RetryPresets +from aws_durable_execution_sdk_python.config import StepConfig + +@durable_execution +def lambda_handler(event: dict, context: DurableContext) -> dict: + context.logger.info(event) + num1 = event.get('num1', 0) + num2 = event.get('num2', 0) + + # No retries + step_config = StepConfig(retry_strategy=RetryPresets.none()) + + # Define the functions for each step + def add_nums(): + context.logger.info(f"Adding {num1} and {num2}") + return num1 + num2 + + def sub_nums(): + context.logger.info(f"Subtracting {num2} from {num1}") + return num1 - num2 + + def mul_nums(): + context.logger.info(f"Multiplying {num1} and {num2}") + return num1 * num2 + + def div_nums(): + context.logger.info(f"Dividing {num1} by {num2}") + if num2 == 0: + raise ValueError("Division by zero is not allowed") + return num1 / num2 + + try: + # context.parallel takes a list of step definitions and executes them in parallel. + # It returns a list of results in the same order as the input list. + results = context.parallel([ + lambda ctx: ctx.step(lambda _: add_nums(), name="addition"), + lambda ctx: ctx.step(lambda _: sub_nums(), name="subtraction"), + lambda ctx: ctx.step(lambda _: mul_nums(), name="multiplication"), + lambda ctx: ctx.step(lambda _: div_nums(), name="division", config=step_config) + ]) + + if results.failure_count != 0: + raise Exception(f"One or more operations failed") + + add, sub, mul, div = results.get_results() + return { + "Add": add, + "Subtract": sub, + "Multiply": mul, + "Division": div + } + + except Exception as e: + return { + "error_details": str(e) + } \ No newline at end of file diff --git a/lambda-durable-parallel-execution-python-sam/src/requirements.txt b/lambda-durable-parallel-execution-python-sam/src/requirements.txt new file mode 100644 index 000000000..0cf8bca12 --- /dev/null +++ b/lambda-durable-parallel-execution-python-sam/src/requirements.txt @@ -0,0 +1 @@ +aws-durable-execution-sdk-python \ No newline at end of file diff --git a/lambda-durable-parallel-execution-python-sam/template.yaml b/lambda-durable-parallel-execution-python-sam/template.yaml new file mode 100644 index 000000000..6ba1a9b6f --- /dev/null +++ b/lambda-durable-parallel-execution-python-sam/template.yaml @@ -0,0 +1,20 @@ +AWSTemplateFormatVersion: "2010-09-09" +Transform: AWS::Serverless-2016-10-31 +Description: AWS Lambda durable functions with Parallel Execution + +Resources: + MathFunction: + Type: AWS::Serverless::Function + Properties: + Handler: lambda_function.lambda_handler + CodeUri: src/ + Runtime: python3.14 + Timeout: 10 + AutoPublishAlias: live + DurableConfig: + ExecutionTimeout: 300 + RetentionPeriodInDays: 5 + +Outputs: + MathFunction: + Value: !Ref MathFunction