Skip to content

Commit 465ee2a

Browse files
FullyTypedAstraea Quinn S
authored andcommitted
chore: Update Suspension models
Updates: - WaitOptions - CallbackOptions - ChainedInvoke Options
1 parent e9802ae commit 465ee2a

File tree

4 files changed

+43
-27
lines changed

4 files changed

+43
-27
lines changed

src/aws_durable_execution_sdk_python/lambda_service.py

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -241,18 +241,41 @@ def to_dict(self) -> MutableMapping[str, Any]:
241241

242242
@dataclass(frozen=True)
243243
class WaitOptions:
244-
wait_seconds: int = 0
244+
"""
245+
Wait Options provides details regarding suspension.
246+
247+
As of 2025/10/27:
248+
249+
- `wait_seconds` accepts values between 1, and 31622400
250+
- When wait_second seconds does not exist,then we default to 1
251+
252+
"""
253+
254+
wait_seconds: int = 1
245255

246256
@classmethod
247257
def from_dict(cls, data: MutableMapping[str, Any]) -> WaitOptions:
248-
return cls(wait_seconds=data.get("WaitSeconds", 0))
258+
return cls(wait_seconds=data.get("WaitSeconds", 1))
249259

250260
def to_dict(self) -> MutableMapping[str, Any]:
251261
return {"WaitSeconds": self.wait_seconds}
252262

253263

254264
@dataclass(frozen=True)
255265
class CallbackOptions:
266+
"""
267+
Callback options provides details about the callback, wrt timeout
268+
and heartbeat checks.
269+
270+
As of 2025/10/27:
271+
- When timeout_seconds == 0, then the callback has no timeout
272+
- When heartbeat_timeout_seconds == 0, then the callback has no timeout
273+
274+
- When timeout_seconds is not present, then default is 0
275+
- When heartbeat_timeout_seconds, then default is 0
276+
277+
"""
278+
256279
timeout_seconds: TimeoutSeconds = 0
257280
heartbeat_timeout_seconds: int = 0
258281

@@ -272,20 +295,22 @@ def to_dict(self) -> MutableMapping[str, Any]:
272295

273296
@dataclass(frozen=True)
274297
class ChainedInvokeOptions:
298+
"""
299+
As of 2025/10/27:
300+
- Chained invoke options only contains a function name
301+
"""
302+
275303
function_name: str
276-
timeout_seconds: TimeoutSeconds = 0
277304

278305
@classmethod
279306
def from_dict(cls, data: MutableMapping[str, Any]) -> ChainedInvokeOptions:
280307
return cls(
281308
function_name=data["FunctionName"],
282-
timeout_seconds=data.get("TimeoutSeconds", 0),
283309
)
284310

285311
def to_dict(self) -> MutableMapping[str, Any]:
286312
result: MutableMapping[str, Any] = {
287313
"FunctionName": self.function_name,
288-
"TimeoutSeconds": self.timeout_seconds,
289314
}
290315
return result
291316

src/aws_durable_execution_sdk_python/operation/invoke.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,7 @@ def invoke_handler(
8787
start_operation: OperationUpdate = OperationUpdate.create_invoke_start(
8888
identifier=operation_identifier,
8989
payload=serialized_payload,
90-
chained_invoke_options=ChainedInvokeOptions(
91-
function_name=function_name, timeout_seconds=config.timeout_seconds
92-
),
90+
chained_invoke_options=ChainedInvokeOptions(function_name=function_name),
9391
)
9492

9593
state.create_checkpoint(operation_update=start_operation)

tests/lambda_service_test.py

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -402,15 +402,13 @@ def test_invoke_options_from_dict():
402402
data = {"FunctionName": "test-function", "TimeoutSeconds": 120}
403403
options = ChainedInvokeOptions.from_dict(data)
404404
assert options.function_name == "test-function"
405-
assert options.timeout_seconds == 120
406405

407406

408407
def test_invoke_options_from_dict_required_only():
409408
"""Test ChainedInvokeOptions.from_dict with only required field."""
410409
data = {"FunctionName": "test-function"}
411410
options = ChainedInvokeOptions.from_dict(data)
412411
assert options.function_name == "test-function"
413-
assert options.timeout_seconds == 0
414412

415413

416414
def test_context_options_from_dict():
@@ -444,7 +442,7 @@ def test_callback_options_roundtrip():
444442

445443
def test_invoke_options_roundtrip():
446444
"""Test ChainedInvokeOptions to_dict -> from_dict roundtrip."""
447-
original = ChainedInvokeOptions(function_name="test-func", timeout_seconds=120)
445+
original = ChainedInvokeOptions(function_name="test-func")
448446
data = original.to_dict()
449447
restored = ChainedInvokeOptions.from_dict(data)
450448
assert restored == original
@@ -498,12 +496,10 @@ def test_invoke_options_to_dict():
498496
"""Test ChainedInvokeOptions.to_dict method."""
499497
options = ChainedInvokeOptions(
500498
function_name="test_function",
501-
timeout_seconds=30,
502499
)
503500
result = options.to_dict()
504501
expected = {
505502
"FunctionName": "test_function",
506-
"TimeoutSeconds": 30,
507503
}
508504
assert result == expected
509505

@@ -512,7 +508,7 @@ def test_invoke_options_to_dict_minimal():
512508
"""Test ChainedInvokeOptions.to_dict with minimal fields."""
513509
options = ChainedInvokeOptions(function_name="test_function")
514510
result = options.to_dict()
515-
assert result == {"FunctionName": "test_function", "TimeoutSeconds": 0}
511+
assert result == {"FunctionName": "test_function"}
516512

517513

518514
def test_context_options_to_dict():
@@ -546,12 +542,11 @@ def test_invoke_options_from_dict_missing_function_name():
546542

547543
def test_invoke_options_to_dict_complete():
548544
"""Test ChainedInvokeOptions.to_dict with all fields."""
549-
options = ChainedInvokeOptions(function_name="test_func", timeout_seconds=120)
545+
options = ChainedInvokeOptions(function_name="test_func")
550546

551547
result = options.to_dict()
552548

553549
assert result["FunctionName"] == "test_func"
554-
assert result["TimeoutSeconds"] == 120
555550

556551

557552
# =============================================================================
@@ -562,7 +557,7 @@ def test_invoke_options_to_dict_complete():
562557
def test_operation_update_create_invoke_start():
563558
"""Test OperationUpdate.create_invoke_start method to cover line 545."""
564559
identifier = OperationIdentifier("test-id", "parent-id")
565-
invoke_options = ChainedInvokeOptions("test-func", 120)
560+
invoke_options = ChainedInvokeOptions("test-func")
566561
update = OperationUpdate.create_invoke_start(identifier, "payload", invoke_options)
567562
assert update.operation_id == "test-id"
568563

@@ -609,9 +604,7 @@ def test_operation_update_to_dict_complete():
609604
callback_options = CallbackOptions(
610605
timeout_seconds=300, heartbeat_timeout_seconds=60
611606
)
612-
chained_invoke_options = ChainedInvokeOptions(
613-
function_name="test_func", timeout_seconds=60
614-
)
607+
chained_invoke_options = ChainedInvokeOptions(function_name="test_func")
615608

616609
update = OperationUpdate(
617610
operation_id="op1",
@@ -639,7 +632,7 @@ def test_operation_update_to_dict_complete():
639632
"StepOptions": {"NextAttemptDelaySeconds": 30},
640633
"WaitOptions": {"WaitSeconds": 60},
641634
"CallbackOptions": {"TimeoutSeconds": 300, "HeartbeatTimeoutSeconds": 60},
642-
"ChainedInvokeOptions": {"FunctionName": "test_func", "TimeoutSeconds": 60},
635+
"ChainedInvokeOptions": {"FunctionName": "test_func"},
643636
}
644637
assert result == expected
645638

@@ -884,9 +877,7 @@ def test_operation_update_complete_with_new_fields():
884877
callback_options = CallbackOptions(
885878
timeout_seconds=300, heartbeat_timeout_seconds=60
886879
)
887-
chained_invoke_options = ChainedInvokeOptions(
888-
function_name="test_func", timeout_seconds=60
889-
)
880+
chained_invoke_options = ChainedInvokeOptions(function_name="test_func")
890881

891882
update = OperationUpdate(
892883
operation_id="op1",
@@ -918,7 +909,7 @@ def test_operation_update_complete_with_new_fields():
918909
"StepOptions": {"NextAttemptDelaySeconds": 30},
919910
"WaitOptions": {"WaitSeconds": 60},
920911
"CallbackOptions": {"TimeoutSeconds": 300, "HeartbeatTimeoutSeconds": 60},
921-
"ChainedInvokeOptions": {"FunctionName": "test_func", "TimeoutSeconds": 60},
912+
"ChainedInvokeOptions": {"FunctionName": "test_func"},
922913
}
923914
assert result == expected
924915

tests/operation/invoke_test.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,6 @@ def test_invoke_handler_new_operation():
247247
assert operation_update.name == "test_invoke"
248248
assert operation_update.payload == json.dumps("test_input")
249249
assert operation_update.chained_invoke_options.function_name == "test_function"
250-
assert operation_update.chained_invoke_options.timeout_seconds == 60
251250

252251

253252
def test_invoke_handler_new_operation_with_timeout():
@@ -309,7 +308,10 @@ def test_invoke_handler_no_config():
309308

310309
# Verify default config was used
311310
operation_update = mock_state.create_checkpoint.call_args[1]["operation_update"]
312-
assert operation_update.chained_invoke_options.timeout_seconds == 0
311+
assert (
312+
operation_update.to_dict()["ChainedInvokeOptions"]["FunctionName"]
313+
== "test_function"
314+
)
313315

314316

315317
def test_invoke_handler_custom_serdes():

0 commit comments

Comments
 (0)