async-durable-execution-runner 2.0.0a1__tar.gz → 2.0.0a2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/.gitignore +1 -1
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/PKG-INFO +30 -22
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/README.md +26 -19
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/VERSION.py +1 -1
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/__init__.py +10 -7
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/checkpoint/processor.py +9 -10
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/checkpoint/processors/base.py +5 -5
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/checkpoint/processors/callback.py +11 -10
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/checkpoint/processors/context.py +4 -5
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/checkpoint/processors/execution.py +5 -10
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/checkpoint/processors/step.py +11 -8
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/checkpoint/processors/wait.py +7 -8
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/checkpoint/transformer.py +9 -10
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/checkpoint/validators/checkpoint.py +10 -11
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/checkpoint/validators/operations/callback.py +2 -3
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/checkpoint/validators/operations/context.py +2 -3
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/checkpoint/validators/operations/execution.py +2 -3
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/checkpoint/validators/operations/invoke.py +2 -3
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/checkpoint/validators/operations/step.py +2 -3
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/checkpoint/validators/operations/wait.py +2 -3
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/checkpoint/validators/transitions.py +8 -9
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/cli.py +25 -22
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/client.py +6 -7
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/exceptions.py +1 -13
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/execution.py +12 -15
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/executor.py +67 -42
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/invoker.py +21 -12
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/model.py +13 -70
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/observer.py +4 -6
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/runner.py +259 -140
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/scheduler.py +35 -24
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/stores/base.py +5 -6
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/stores/filesystem.py +3 -3
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/stores/memory.py +2 -2
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/stores/sqlite.py +5 -5
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/web/handlers.py +15 -17
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/web/models.py +3 -3
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/web/routes.py +1 -1
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/web/serialization.py +4 -6
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/web/server.py +10 -10
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/pyproject.toml +18 -19
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/LICENSE +0 -0
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/NOTICE +0 -0
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/__about__.py +0 -0
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/checkpoint/__init__.py +0 -0
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/checkpoint/processors/__init__.py +0 -0
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/checkpoint/validators/__init__.py +0 -0
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/checkpoint/validators/operations/__init__.py +0 -0
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/py.typed +0 -0
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/stores/__init__.py +0 -0
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/token.py +0 -0
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/web/__init__.py +0 -0
- {async_durable_execution_runner-2.0.0a1 → async_durable_execution_runner-2.0.0a2}/async_durable_execution_runner/web/errors.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: async-durable-execution-runner
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.0a2
|
|
4
4
|
Summary: Community-maintained durable execution local and cloud test runner for Python
|
|
5
5
|
Project-URL: Documentation, https://github.com/zhongkechen/async-durable-execution#readme
|
|
6
6
|
Project-URL: Issues, https://github.com/zhongkechen/async-durable-execution/issues
|
|
@@ -11,17 +11,20 @@ License-File: LICENSE
|
|
|
11
11
|
License-File: NOTICE
|
|
12
12
|
Classifier: Development Status :: 4 - Beta
|
|
13
13
|
Classifier: Programming Language :: Python
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
15
|
Classifier: Programming Language :: Python :: 3.11
|
|
15
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
16
17
|
Classifier: Programming Language :: Python :: 3.13
|
|
17
18
|
Classifier: Programming Language :: Python :: 3.14
|
|
18
19
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
19
20
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
20
|
-
Requires-Python: >=3.
|
|
21
|
-
Requires-Dist: async-durable-execution>=
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Requires-Dist: async-durable-execution>=2.0.0a2
|
|
22
23
|
Requires-Dist: boto3>=1.42.1
|
|
23
24
|
Description-Content-Type: text/markdown
|
|
24
25
|
|
|
26
|
+
from async_durable_execution.operation import child
|
|
27
|
+
|
|
25
28
|
# Async Durable Execution Runner for Python
|
|
26
29
|
|
|
27
30
|
[](https://pypi.org/project/async-durable-execution-runner)
|
|
@@ -43,6 +46,8 @@ Description-Content-Type: text/markdown
|
|
|
43
46
|
|
|
44
47
|
## Installation
|
|
45
48
|
|
|
49
|
+
Requires Python 3.10 or newer.
|
|
50
|
+
|
|
46
51
|
```console
|
|
47
52
|
pip install async-durable-execution-runner
|
|
48
53
|
```
|
|
@@ -62,58 +67,54 @@ before you deploy it.
|
|
|
62
67
|
|
|
63
68
|
```python
|
|
64
69
|
import asyncio
|
|
70
|
+
from datetime import timedelta
|
|
71
|
+
from functools import partial
|
|
65
72
|
from typing import Any
|
|
66
73
|
|
|
67
74
|
from async_durable_execution import (
|
|
68
|
-
DurableContext,
|
|
69
75
|
durable_execution,
|
|
70
|
-
|
|
71
|
-
durable_with_child_context,
|
|
76
|
+
get_current_context,
|
|
72
77
|
)
|
|
73
|
-
from async_durable_execution.config import Duration
|
|
74
78
|
|
|
75
79
|
|
|
76
|
-
@durable_step
|
|
77
80
|
async def one(a: int, b: int) -> str:
|
|
78
81
|
await asyncio.sleep(0)
|
|
79
82
|
return f"{a} {b}"
|
|
80
83
|
|
|
81
84
|
|
|
82
|
-
@durable_step
|
|
83
85
|
async def two_1(a: int, b: int) -> str:
|
|
84
86
|
await asyncio.sleep(0)
|
|
85
87
|
return f"{a} {b}"
|
|
86
88
|
|
|
87
89
|
|
|
88
|
-
@durable_step
|
|
89
90
|
async def two_2(a: int, b: int) -> str:
|
|
90
91
|
await asyncio.sleep(0)
|
|
91
92
|
return f"{b} {a}"
|
|
92
93
|
|
|
93
94
|
|
|
94
|
-
|
|
95
|
-
|
|
95
|
+
async def two(a: int, b: int) -> str:
|
|
96
|
+
ctx = get_current_context()
|
|
96
97
|
two_1_result: str = ctx.step(two_1(a, b))
|
|
97
98
|
two_2_result: str = ctx.step(two_2(a, b))
|
|
98
99
|
return f"{two_1_result} {two_2_result}"
|
|
99
100
|
|
|
100
101
|
|
|
101
|
-
@durable_step
|
|
102
102
|
async def three(a: int, b: int) -> str:
|
|
103
103
|
await asyncio.sleep(0)
|
|
104
104
|
return f"{a} {b}"
|
|
105
105
|
|
|
106
106
|
|
|
107
107
|
@durable_execution
|
|
108
|
-
async def function_under_test(event: Any
|
|
108
|
+
async def function_under_test(event: Any) -> list[str]:
|
|
109
|
+
context = get_current_context()
|
|
109
110
|
results: list[str] = []
|
|
110
111
|
|
|
111
112
|
result_one: str = context.step(one(1, 2))
|
|
112
113
|
results.append(result_one)
|
|
113
114
|
|
|
114
|
-
context.wait(duration=
|
|
115
|
+
context.wait(duration=timedelta(seconds=1))
|
|
115
116
|
|
|
116
|
-
result_two: str =
|
|
117
|
+
result_two: str = child.run_in_child_context(partial(two, 3, 4), name="two")
|
|
117
118
|
results.append(result_two)
|
|
118
119
|
|
|
119
120
|
result_three: str = context.step(three(5, 6))
|
|
@@ -125,18 +126,25 @@ async def function_under_test(event: Any, context: DurableContext) -> list[str]:
|
|
|
125
126
|
### Your test code
|
|
126
127
|
|
|
127
128
|
```python
|
|
128
|
-
|
|
129
|
-
|
|
129
|
+
import asyncio
|
|
130
|
+
|
|
131
|
+
from async_durable_execution import InvocationStatus
|
|
132
|
+
from async_durable_execution_runner import (
|
|
130
133
|
ContextOperation,
|
|
134
|
+
create_runner,
|
|
131
135
|
DurableFunctionTestResult,
|
|
132
|
-
DurableFunctionTestRunner,
|
|
133
136
|
StepOperation,
|
|
134
137
|
)
|
|
135
138
|
|
|
136
139
|
|
|
137
140
|
def test_my_durable_functions():
|
|
138
|
-
with
|
|
139
|
-
|
|
141
|
+
with create_runner(
|
|
142
|
+
mode="local",
|
|
143
|
+
handler=function_under_test,
|
|
144
|
+
input="input str",
|
|
145
|
+
timeout=10,
|
|
146
|
+
) as runner:
|
|
147
|
+
result: DurableFunctionTestResult = asyncio.run(runner.run())
|
|
140
148
|
|
|
141
149
|
assert result.status is InvocationStatus.SUCCEEDED
|
|
142
150
|
assert result.result == '["1 2", "3 4 4 3", "5 6"]'
|
|
@@ -163,7 +171,7 @@ def test_my_durable_functions():
|
|
|
163
171
|
5. **ExecutionNotifier** broadcasts events to **Executor** (observer)
|
|
164
172
|
6. **Executor** updates **Execution** state based on events
|
|
165
173
|
7. **Execution** completion triggers final event notifications
|
|
166
|
-
8. **DurableTestRunner** run()
|
|
174
|
+
8. **DurableTestRunner** exposes async runner methods, so `await runner.run()` resolves once the execution completes and returns `DurableFunctionTestResult`.
|
|
167
175
|
|
|
168
176
|
## Major Components
|
|
169
177
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from async_durable_execution.operation import child
|
|
2
|
+
|
|
1
3
|
# Async Durable Execution Runner for Python
|
|
2
4
|
|
|
3
5
|
[](https://pypi.org/project/async-durable-execution-runner)
|
|
@@ -19,6 +21,8 @@
|
|
|
19
21
|
|
|
20
22
|
## Installation
|
|
21
23
|
|
|
24
|
+
Requires Python 3.10 or newer.
|
|
25
|
+
|
|
22
26
|
```console
|
|
23
27
|
pip install async-durable-execution-runner
|
|
24
28
|
```
|
|
@@ -38,58 +42,54 @@ before you deploy it.
|
|
|
38
42
|
|
|
39
43
|
```python
|
|
40
44
|
import asyncio
|
|
45
|
+
from datetime import timedelta
|
|
46
|
+
from functools import partial
|
|
41
47
|
from typing import Any
|
|
42
48
|
|
|
43
49
|
from async_durable_execution import (
|
|
44
|
-
DurableContext,
|
|
45
50
|
durable_execution,
|
|
46
|
-
|
|
47
|
-
durable_with_child_context,
|
|
51
|
+
get_current_context,
|
|
48
52
|
)
|
|
49
|
-
from async_durable_execution.config import Duration
|
|
50
53
|
|
|
51
54
|
|
|
52
|
-
@durable_step
|
|
53
55
|
async def one(a: int, b: int) -> str:
|
|
54
56
|
await asyncio.sleep(0)
|
|
55
57
|
return f"{a} {b}"
|
|
56
58
|
|
|
57
59
|
|
|
58
|
-
@durable_step
|
|
59
60
|
async def two_1(a: int, b: int) -> str:
|
|
60
61
|
await asyncio.sleep(0)
|
|
61
62
|
return f"{a} {b}"
|
|
62
63
|
|
|
63
64
|
|
|
64
|
-
@durable_step
|
|
65
65
|
async def two_2(a: int, b: int) -> str:
|
|
66
66
|
await asyncio.sleep(0)
|
|
67
67
|
return f"{b} {a}"
|
|
68
68
|
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
async def two(a: int, b: int) -> str:
|
|
71
|
+
ctx = get_current_context()
|
|
72
72
|
two_1_result: str = ctx.step(two_1(a, b))
|
|
73
73
|
two_2_result: str = ctx.step(two_2(a, b))
|
|
74
74
|
return f"{two_1_result} {two_2_result}"
|
|
75
75
|
|
|
76
76
|
|
|
77
|
-
@durable_step
|
|
78
77
|
async def three(a: int, b: int) -> str:
|
|
79
78
|
await asyncio.sleep(0)
|
|
80
79
|
return f"{a} {b}"
|
|
81
80
|
|
|
82
81
|
|
|
83
82
|
@durable_execution
|
|
84
|
-
async def function_under_test(event: Any
|
|
83
|
+
async def function_under_test(event: Any) -> list[str]:
|
|
84
|
+
context = get_current_context()
|
|
85
85
|
results: list[str] = []
|
|
86
86
|
|
|
87
87
|
result_one: str = context.step(one(1, 2))
|
|
88
88
|
results.append(result_one)
|
|
89
89
|
|
|
90
|
-
context.wait(duration=
|
|
90
|
+
context.wait(duration=timedelta(seconds=1))
|
|
91
91
|
|
|
92
|
-
result_two: str =
|
|
92
|
+
result_two: str = child.run_in_child_context(partial(two, 3, 4), name="two")
|
|
93
93
|
results.append(result_two)
|
|
94
94
|
|
|
95
95
|
result_three: str = context.step(three(5, 6))
|
|
@@ -101,18 +101,25 @@ async def function_under_test(event: Any, context: DurableContext) -> list[str]:
|
|
|
101
101
|
### Your test code
|
|
102
102
|
|
|
103
103
|
```python
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
import asyncio
|
|
105
|
+
|
|
106
|
+
from async_durable_execution import InvocationStatus
|
|
107
|
+
from async_durable_execution_runner import (
|
|
106
108
|
ContextOperation,
|
|
109
|
+
create_runner,
|
|
107
110
|
DurableFunctionTestResult,
|
|
108
|
-
DurableFunctionTestRunner,
|
|
109
111
|
StepOperation,
|
|
110
112
|
)
|
|
111
113
|
|
|
112
114
|
|
|
113
115
|
def test_my_durable_functions():
|
|
114
|
-
with
|
|
115
|
-
|
|
116
|
+
with create_runner(
|
|
117
|
+
mode="local",
|
|
118
|
+
handler=function_under_test,
|
|
119
|
+
input="input str",
|
|
120
|
+
timeout=10,
|
|
121
|
+
) as runner:
|
|
122
|
+
result: DurableFunctionTestResult = asyncio.run(runner.run())
|
|
116
123
|
|
|
117
124
|
assert result.status is InvocationStatus.SUCCEEDED
|
|
118
125
|
assert result.result == '["1 2", "3 4 4 3", "5 6"]'
|
|
@@ -139,7 +146,7 @@ def test_my_durable_functions():
|
|
|
139
146
|
5. **ExecutionNotifier** broadcasts events to **Executor** (observer)
|
|
140
147
|
6. **Executor** updates **Execution** state based on events
|
|
141
148
|
7. **Execution** completion triggers final event notifications
|
|
142
|
-
8. **DurableTestRunner** run()
|
|
149
|
+
8. **DurableTestRunner** exposes async runner methods, so `await runner.run()` resolves once the execution completes and returns `DurableFunctionTestResult`.
|
|
143
150
|
|
|
144
151
|
## Major Components
|
|
145
152
|
|
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
"""DurableExecutionsPythonTestingLibrary module."""
|
|
2
2
|
|
|
3
|
-
from
|
|
4
|
-
|
|
3
|
+
from .__about__ import __version__
|
|
4
|
+
from .runner import (
|
|
5
5
|
DurableFunctionCloudTestRunner,
|
|
6
|
+
DurableFunctionLocalTestRunner,
|
|
6
7
|
DurableFunctionTestResult,
|
|
7
|
-
DurableFunctionTestRunner,
|
|
8
8
|
WebRunner,
|
|
9
9
|
WebRunnerConfig,
|
|
10
|
+
create_runner,
|
|
11
|
+
ContextOperation,
|
|
12
|
+
StepOperation,
|
|
10
13
|
)
|
|
11
14
|
|
|
12
|
-
from async_durable_execution_runner.__about__ import __version__
|
|
13
|
-
|
|
14
15
|
|
|
15
16
|
__all__ = [
|
|
16
|
-
"DurableChildContextTestRunner",
|
|
17
17
|
"DurableFunctionCloudTestRunner",
|
|
18
|
+
"DurableFunctionLocalTestRunner",
|
|
18
19
|
"DurableFunctionTestResult",
|
|
19
|
-
"DurableFunctionTestRunner",
|
|
20
20
|
"WebRunner",
|
|
21
21
|
"WebRunnerConfig",
|
|
22
22
|
"__version__",
|
|
23
|
+
"create_runner",
|
|
24
|
+
"ContextOperation",
|
|
25
|
+
"StepOperation",
|
|
23
26
|
]
|
|
@@ -4,30 +4,29 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
|
-
from async_durable_execution.
|
|
7
|
+
from async_durable_execution.models import (
|
|
8
8
|
CheckpointOutput,
|
|
9
9
|
CheckpointUpdatedExecutionState,
|
|
10
10
|
OperationUpdate,
|
|
11
11
|
StateOutput,
|
|
12
12
|
)
|
|
13
|
-
|
|
14
|
-
from async_durable_execution_runner.checkpoint.transformer import (
|
|
13
|
+
from .transformer import (
|
|
15
14
|
OperationTransformer,
|
|
16
15
|
)
|
|
17
|
-
from
|
|
16
|
+
from .validators.checkpoint import (
|
|
18
17
|
CheckpointValidator,
|
|
19
18
|
)
|
|
20
|
-
from
|
|
19
|
+
from ..exceptions import (
|
|
21
20
|
InvalidParameterValueException,
|
|
22
21
|
)
|
|
23
|
-
from
|
|
24
|
-
from
|
|
22
|
+
from ..observer import ExecutionNotifier
|
|
23
|
+
from ..token import CheckpointToken
|
|
25
24
|
|
|
26
25
|
|
|
27
26
|
if TYPE_CHECKING:
|
|
28
|
-
from
|
|
29
|
-
from
|
|
30
|
-
from
|
|
27
|
+
from ..execution import Execution
|
|
28
|
+
from ..scheduler import Scheduler
|
|
29
|
+
from ..stores.base import ExecutionStore
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
class CheckpointProcessor:
|
|
@@ -6,7 +6,7 @@ import datetime
|
|
|
6
6
|
from datetime import timedelta
|
|
7
7
|
from typing import TYPE_CHECKING
|
|
8
8
|
|
|
9
|
-
from async_durable_execution.
|
|
9
|
+
from async_durable_execution.models import (
|
|
10
10
|
CallbackDetails,
|
|
11
11
|
ChainedInvokeDetails,
|
|
12
12
|
ContextDetails,
|
|
@@ -22,7 +22,7 @@ from async_durable_execution.lambda_service import (
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
if TYPE_CHECKING:
|
|
25
|
-
from
|
|
25
|
+
from ...observer import ExecutionNotifier
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
class OperationProcessor:
|
|
@@ -44,7 +44,7 @@ class OperationProcessor:
|
|
|
44
44
|
start_time: datetime.datetime | None = (
|
|
45
45
|
current_operation.start_timestamp
|
|
46
46
|
if current_operation
|
|
47
|
-
else datetime.datetime.now(tz=datetime.
|
|
47
|
+
else datetime.datetime.now(tz=datetime.timezone.utc)
|
|
48
48
|
)
|
|
49
49
|
return start_time
|
|
50
50
|
|
|
@@ -61,7 +61,7 @@ class OperationProcessor:
|
|
|
61
61
|
OperationStatus.TIMED_OUT,
|
|
62
62
|
OperationStatus.STOPPED,
|
|
63
63
|
}:
|
|
64
|
-
return datetime.datetime.now(tz=datetime.
|
|
64
|
+
return datetime.datetime.now(tz=datetime.timezone.utc)
|
|
65
65
|
return None
|
|
66
66
|
|
|
67
67
|
def _create_execution_details(
|
|
@@ -193,7 +193,7 @@ class OperationProcessor:
|
|
|
193
193
|
)
|
|
194
194
|
else:
|
|
195
195
|
scheduled_end_timestamp = datetime.datetime.now(
|
|
196
|
-
tz=datetime.
|
|
196
|
+
tz=datetime.timezone.utc
|
|
197
197
|
) + timedelta(seconds=update.wait_options.wait_seconds)
|
|
198
198
|
return WaitDetails(scheduled_end_timestamp=scheduled_end_timestamp)
|
|
199
199
|
return None
|
|
@@ -5,25 +5,26 @@ from __future__ import annotations
|
|
|
5
5
|
import datetime
|
|
6
6
|
from typing import TYPE_CHECKING
|
|
7
7
|
|
|
8
|
-
from async_durable_execution.
|
|
8
|
+
from async_durable_execution.models import (
|
|
9
|
+
CallbackDetails,
|
|
10
|
+
CallbackOptions,
|
|
9
11
|
Operation,
|
|
10
12
|
OperationAction,
|
|
11
13
|
OperationStatus,
|
|
12
|
-
OperationUpdate,
|
|
13
|
-
CallbackDetails,
|
|
14
14
|
OperationType,
|
|
15
|
-
|
|
15
|
+
OperationUpdate,
|
|
16
16
|
)
|
|
17
|
-
from
|
|
17
|
+
from .base import (
|
|
18
18
|
OperationProcessor,
|
|
19
19
|
)
|
|
20
|
-
from
|
|
20
|
+
from ...exceptions import (
|
|
21
21
|
InvalidParameterValueException,
|
|
22
22
|
)
|
|
23
|
-
from
|
|
23
|
+
from ...token import CallbackToken
|
|
24
|
+
|
|
24
25
|
|
|
25
26
|
if TYPE_CHECKING:
|
|
26
|
-
from
|
|
27
|
+
from ...observer import ExecutionNotifier
|
|
27
28
|
|
|
28
29
|
|
|
29
30
|
class CallbackProcessor(OperationProcessor):
|
|
@@ -33,8 +34,8 @@ class CallbackProcessor(OperationProcessor):
|
|
|
33
34
|
self,
|
|
34
35
|
update: OperationUpdate,
|
|
35
36
|
current_op: Operation | None,
|
|
36
|
-
notifier: ExecutionNotifier,
|
|
37
|
-
execution_arn: str,
|
|
37
|
+
notifier: ExecutionNotifier,
|
|
38
|
+
execution_arn: str,
|
|
38
39
|
) -> Operation:
|
|
39
40
|
"""Process CALLBACK operation update with scheduler integration for activities."""
|
|
40
41
|
match update.action:
|
|
@@ -4,23 +4,22 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
|
-
from async_durable_execution.
|
|
7
|
+
from async_durable_execution.models import (
|
|
8
8
|
Operation,
|
|
9
9
|
OperationAction,
|
|
10
10
|
OperationStatus,
|
|
11
11
|
OperationUpdate,
|
|
12
12
|
)
|
|
13
|
-
|
|
14
|
-
from async_durable_execution_runner.checkpoint.processors.base import (
|
|
13
|
+
from .base import (
|
|
15
14
|
OperationProcessor,
|
|
16
15
|
)
|
|
17
|
-
from
|
|
16
|
+
from ...exceptions import (
|
|
18
17
|
InvalidParameterValueException,
|
|
19
18
|
)
|
|
20
19
|
|
|
21
20
|
|
|
22
21
|
if TYPE_CHECKING:
|
|
23
|
-
from
|
|
22
|
+
from ...observer import ExecutionNotifier
|
|
24
23
|
|
|
25
24
|
|
|
26
25
|
class ContextProcessor(OperationProcessor):
|
|
@@ -4,20 +4,19 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
|
-
from async_durable_execution.
|
|
7
|
+
from async_durable_execution.models import (
|
|
8
8
|
ErrorObject,
|
|
9
9
|
Operation,
|
|
10
10
|
OperationAction,
|
|
11
11
|
OperationUpdate,
|
|
12
12
|
)
|
|
13
|
-
|
|
14
|
-
from async_durable_execution_runner.checkpoint.processors.base import (
|
|
13
|
+
from .base import (
|
|
15
14
|
OperationProcessor,
|
|
16
15
|
)
|
|
17
16
|
|
|
18
17
|
|
|
19
18
|
if TYPE_CHECKING:
|
|
20
|
-
from
|
|
19
|
+
from ...observer import ExecutionNotifier
|
|
21
20
|
|
|
22
21
|
|
|
23
22
|
class ExecutionProcessor(OperationProcessor):
|
|
@@ -38,12 +37,8 @@ class ExecutionProcessor(OperationProcessor):
|
|
|
38
37
|
)
|
|
39
38
|
case _:
|
|
40
39
|
# intentional. actual service will fail any EXECUTION update that is not SUCCEED.
|
|
41
|
-
error = (
|
|
42
|
-
|
|
43
|
-
if update.error
|
|
44
|
-
else ErrorObject.from_message(
|
|
45
|
-
"There is no error details but EXECUTION checkpoint action is not SUCCEED."
|
|
46
|
-
)
|
|
40
|
+
error = update.error or ErrorObject.from_message(
|
|
41
|
+
"There is no error details but EXECUTION checkpoint action is not SUCCEED."
|
|
47
42
|
)
|
|
48
43
|
# All EXECUTION failures go through normal fail path
|
|
49
44
|
# Timeout/Stop status is set by executor based on the operation that caused it
|
|
@@ -2,27 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from datetime import
|
|
5
|
+
from datetime import datetime, timedelta, timezone
|
|
6
6
|
from typing import TYPE_CHECKING
|
|
7
7
|
|
|
8
|
-
from async_durable_execution.
|
|
8
|
+
from async_durable_execution.models import (
|
|
9
9
|
Operation,
|
|
10
10
|
OperationAction,
|
|
11
11
|
OperationStatus,
|
|
12
12
|
OperationUpdate,
|
|
13
13
|
StepDetails,
|
|
14
14
|
)
|
|
15
|
-
|
|
16
|
-
from async_durable_execution_runner.checkpoint.processors.base import (
|
|
15
|
+
from .base import (
|
|
17
16
|
OperationProcessor,
|
|
18
17
|
)
|
|
19
|
-
from
|
|
18
|
+
from ...exceptions import (
|
|
20
19
|
InvalidParameterValueException,
|
|
21
20
|
)
|
|
22
21
|
|
|
23
22
|
|
|
24
23
|
if TYPE_CHECKING:
|
|
25
|
-
from
|
|
24
|
+
from ...observer import ExecutionNotifier
|
|
26
25
|
|
|
27
26
|
|
|
28
27
|
class StepProcessor(OperationProcessor):
|
|
@@ -50,7 +49,9 @@ class StepProcessor(OperationProcessor):
|
|
|
50
49
|
if update.step_options
|
|
51
50
|
else 0
|
|
52
51
|
)
|
|
53
|
-
next_attempt_time = datetime.now(
|
|
52
|
+
next_attempt_time = datetime.now(timezone.utc) + timedelta(
|
|
53
|
+
seconds=delay
|
|
54
|
+
)
|
|
54
55
|
|
|
55
56
|
# Build new step_details with incremented attempt
|
|
56
57
|
current_attempt = (
|
|
@@ -81,7 +82,9 @@ class StepProcessor(OperationProcessor):
|
|
|
81
82
|
parent_id=update.parent_id,
|
|
82
83
|
name=update.name,
|
|
83
84
|
start_timestamp=(
|
|
84
|
-
current_op.start_timestamp
|
|
85
|
+
current_op.start_timestamp
|
|
86
|
+
if current_op
|
|
87
|
+
else datetime.now(timezone.utc)
|
|
85
88
|
),
|
|
86
89
|
end_timestamp=None,
|
|
87
90
|
sub_type=update.sub_type,
|
|
@@ -4,27 +4,26 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import logging
|
|
6
6
|
import os
|
|
7
|
-
from datetime import
|
|
7
|
+
from datetime import datetime, timedelta, timezone
|
|
8
8
|
from typing import TYPE_CHECKING
|
|
9
9
|
|
|
10
|
-
from async_durable_execution.
|
|
10
|
+
from async_durable_execution.models import (
|
|
11
11
|
Operation,
|
|
12
12
|
OperationAction,
|
|
13
13
|
OperationStatus,
|
|
14
14
|
OperationUpdate,
|
|
15
15
|
WaitDetails,
|
|
16
16
|
)
|
|
17
|
-
|
|
18
|
-
from async_durable_execution_runner.checkpoint.processors.base import (
|
|
17
|
+
from .base import (
|
|
19
18
|
OperationProcessor,
|
|
20
19
|
)
|
|
21
|
-
from
|
|
20
|
+
from ...exceptions import (
|
|
22
21
|
InvalidParameterValueException,
|
|
23
22
|
)
|
|
24
23
|
|
|
25
24
|
|
|
26
25
|
if TYPE_CHECKING:
|
|
27
|
-
from
|
|
26
|
+
from ...observer import ExecutionNotifier
|
|
28
27
|
|
|
29
28
|
|
|
30
29
|
class WaitProcessor(OperationProcessor):
|
|
@@ -47,7 +46,7 @@ class WaitProcessor(OperationProcessor):
|
|
|
47
46
|
logging.info("Using DURABLE_EXECUTION_TIME_SCALE: %f", time_scale)
|
|
48
47
|
scaled_wait_seconds = wait_seconds * time_scale
|
|
49
48
|
|
|
50
|
-
scheduled_end_timestamp = datetime.now(
|
|
49
|
+
scheduled_end_timestamp = datetime.now(timezone.utc) + timedelta(
|
|
51
50
|
seconds=scaled_wait_seconds
|
|
52
51
|
)
|
|
53
52
|
|
|
@@ -63,7 +62,7 @@ class WaitProcessor(OperationProcessor):
|
|
|
63
62
|
status=OperationStatus.STARTED,
|
|
64
63
|
parent_id=update.parent_id,
|
|
65
64
|
name=update.name,
|
|
66
|
-
start_timestamp=datetime.now(
|
|
65
|
+
start_timestamp=datetime.now(timezone.utc),
|
|
67
66
|
end_timestamp=None,
|
|
68
67
|
sub_type=update.sub_type,
|
|
69
68
|
execution_details=None,
|
|
@@ -4,28 +4,27 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
|
-
from async_durable_execution.
|
|
7
|
+
from async_durable_execution.models import (
|
|
8
8
|
Operation,
|
|
9
9
|
OperationType,
|
|
10
10
|
OperationUpdate,
|
|
11
11
|
)
|
|
12
|
-
|
|
13
|
-
from async_durable_execution_runner.checkpoint.processors.callback import (
|
|
12
|
+
from .processors.callback import (
|
|
14
13
|
CallbackProcessor,
|
|
15
14
|
)
|
|
16
|
-
from
|
|
15
|
+
from .processors.context import (
|
|
17
16
|
ContextProcessor,
|
|
18
17
|
)
|
|
19
|
-
from
|
|
18
|
+
from .processors.execution import (
|
|
20
19
|
ExecutionProcessor,
|
|
21
20
|
)
|
|
22
|
-
from
|
|
21
|
+
from .processors.step import (
|
|
23
22
|
StepProcessor,
|
|
24
23
|
)
|
|
25
|
-
from
|
|
24
|
+
from .processors.wait import (
|
|
26
25
|
WaitProcessor,
|
|
27
26
|
)
|
|
28
|
-
from
|
|
27
|
+
from ..exceptions import (
|
|
29
28
|
InvalidParameterValueException,
|
|
30
29
|
)
|
|
31
30
|
|
|
@@ -33,7 +32,7 @@ from async_durable_execution_runner.exceptions import (
|
|
|
33
32
|
if TYPE_CHECKING:
|
|
34
33
|
from collections.abc import MutableMapping
|
|
35
34
|
|
|
36
|
-
from
|
|
35
|
+
from .processors.base import (
|
|
37
36
|
OperationProcessor,
|
|
38
37
|
)
|
|
39
38
|
|
|
@@ -55,7 +54,7 @@ class OperationTransformer:
|
|
|
55
54
|
self,
|
|
56
55
|
processors: MutableMapping[OperationType, OperationProcessor] | None = None,
|
|
57
56
|
):
|
|
58
|
-
self.processors = processors
|
|
57
|
+
self.processors = processors or self._DEFAULT_PROCESSORS
|
|
59
58
|
|
|
60
59
|
def process_updates(
|
|
61
60
|
self,
|