Coverage for async-durable-execution/src/async_durable_execution/runner/local/processors/execution.py: 100%
28 statements
« prev ^ index » next coverage.py v7.15.0, created at 2026-07-07 16:54 +0000
« prev ^ index » next coverage.py v7.15.0, created at 2026-07-07 16:54 +0000
1"""Execution operation processor for handling EXECUTION operation updates."""
3from __future__ import annotations
5from typing import Any
7from ....models import (
8 ErrorObject,
9 Operation,
10 OperationAction,
11 OperationUpdate,
12)
13from .base import (
14 OperationProcessor,
15)
16from ...exceptions import (
17 InvalidParameterValueException,
18)
21VALID_ACTIONS_FOR_EXECUTION = frozenset(
22 [
23 OperationAction.SUCCEED,
24 OperationAction.FAIL,
25 ]
26)
29class ExecutionProcessor(OperationProcessor):
30 """Processes EXECUTION operation updates for workflow completion."""
32 valid_actions = VALID_ACTIONS_FOR_EXECUTION
34 @classmethod
35 def validate(cls, current_state: Operation | None, update: OperationUpdate) -> None:
36 """Validate EXECUTION operation update."""
37 super().validate(current_state, update)
39 match update.action:
40 case OperationAction.SUCCEED:
41 if update.error is not None:
42 msg_exec_succeed_error: str = (
43 "Cannot provide an Error for SUCCEED action."
44 )
45 raise InvalidParameterValueException(msg_exec_succeed_error)
46 case OperationAction.FAIL:
47 if update.payload is not None:
48 msg_exec_fail_payload: str = (
49 "Cannot provide a Payload for FAIL action."
50 )
51 raise InvalidParameterValueException(msg_exec_fail_payload)
53 def process(
54 self,
55 update: OperationUpdate,
56 current_op: Operation | None, # noqa: ARG002
57 notifier: Any,
58 execution_arn: str,
59 ) -> Operation | None:
60 """Process EXECUTION operation update for workflow completion/failure."""
61 match update.action:
62 case OperationAction.SUCCEED:
63 notifier.complete_execution(execution_arn, update.payload)
64 case _:
65 # intentional. actual service will fail any EXECUTION update that is not SUCCEED.
66 error = update.error or ErrorObject.from_message(
67 "There is no error details but EXECUTION checkpoint action is not SUCCEED."
68 )
69 # All EXECUTION failures go through normal fail path
70 # Timeout/Stop status is set by executor based on the operation that caused it
71 notifier.fail_execution(execution_arn, error)
72 # TODO: Svc doesn't actually create checkpoint for EXECUTION. might have to for localrunner though.
73 return None