Skip to content
Closed
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
11 changes: 11 additions & 0 deletions examples/examples-catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,17 @@
},
"path": "./src/wait_for_callback/wait_for_callback_serdes.py"
},
{
"name": "Wait For Callback Timeout",
"description": "Usage of context.wait_for_callback() to wait for external system responses",
"handler": "wait_for_callback_timeout.handler",
"integration": true,
"durableConfig": {
"RetentionPeriodInDays": 7,
"ExecutionTimeout": 300
},
"path": "./src/wait_for_callback/wait_for_callback_timeout.py"
},
{
"name": "Wait For Callback Nested",
"description": "Usage of context.wait_for_callback() to wait for external system responses",
Expand Down
37 changes: 37 additions & 0 deletions examples/src/wait_for_callback/wait_for_callback_timeout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""Demonstrates waitForCallback timeout scenarios."""

from typing import Any

from aws_durable_execution_sdk_python.context import DurableContext
from aws_durable_execution_sdk_python.execution import durable_execution
from aws_durable_execution_sdk_python.config import Duration
from aws_durable_execution_sdk_python.config import WaitForCallbackConfig


@durable_execution
def handler(_event: Any, context: DurableContext) -> dict[str, Any]:
"""Handler demonstrating waitForCallback timeout."""

config = WaitForCallbackConfig(
timeout=Duration.from_seconds(1), heartbeat_timeout=Duration.from_seconds(2)
)

def submitter(_) -> None:
"""Submitter succeeds but callback never completes."""
return None

try:
result: str = context.wait_for_callback(
submitter,
config=config,
)

return {
"callbackResult": result,
"success": True,
}
except Exception as error:
return {
"success": False,
"error": str(error),
}
14 changes: 14 additions & 0 deletions examples/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,20 @@ Resources:
DurableConfig:
RetentionPeriodInDays: 7
ExecutionTimeout: 300
WaitForCallbackTimeout:
Type: AWS::Serverless::Function
Properties:
CodeUri: build/
Handler: wait_for_callback_timeout.handler
Description: Usage of context.wait_for_callback() to wait for external system
responses
Role:
Fn::GetAtt:
- DurableFunctionRole
- Arn
DurableConfig:
RetentionPeriodInDays: 7
ExecutionTimeout: 300
WaitForCallbackNested:
Type: AWS::Serverless::Function
Properties:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""Tests for wait_for_callback_timeout."""

import pytest
from aws_durable_execution_sdk_python.execution import InvocationStatus

from src.wait_for_callback import wait_for_callback_timeout
from test.conftest import deserialize_operation_payload


@pytest.mark.example
@pytest.mark.durable_execution(
handler=wait_for_callback_timeout.handler,
lambda_function_name="Wait For Callback Timeout",
)
def test_handle_wait_for_callback_timeout_scenarios(durable_runner):
"""Test waitForCallback timeout scenarios."""
test_payload = {"test": "timeout-scenario"}

with durable_runner:
execution_arn = durable_runner.run_async(input=test_payload, timeout=30)
# Don't send callback - let it timeout
result = durable_runner.wait_for_result(execution_arn=execution_arn)

# Handler catches the timeout error, so execution succeeds with error in result
assert result.status is InvocationStatus.SUCCEEDED

result_data = deserialize_operation_payload(result.result)

assert result_data["success"] is False
assert isinstance(result_data["error"], str)
assert len(result_data["error"]) > 0
assert "Callback timed out" == result_data["error"]
Loading