dapr-ext-workflow-dev 1.17.0.dev102__tar.gz → 1.17.0.dev103__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.
- {dapr_ext_workflow_dev-1.17.0.dev102/dapr_ext_workflow_dev.egg-info → dapr_ext_workflow_dev-1.17.0.dev103}/PKG-INFO +1 -1
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/helpers.py +9 -26
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/history_events_pb2.py +27 -23
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/history_events_pb2.pyi +49 -3
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/orchestrator_actions_pb2.py +12 -12
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/orchestrator_actions_pb2.pyi +11 -3
- dapr_ext_workflow_dev-1.17.0.dev103/dapr/ext/workflow/_durabletask/internal/timer.py +142 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/task.py +85 -6
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/worker.py +161 -9
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/dapr_workflow_context.py +7 -2
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/workflow_context.py +21 -2
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103/dapr_ext_workflow_dev.egg-info}/PKG-INFO +1 -1
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr_ext_workflow_dev.egg-info/SOURCES.txt +1 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/LICENSE +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/README.rst +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/__init__.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/__init__.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/aio/__init__.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/aio/client.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/aio/internal/__init__.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/aio/internal/grpc_interceptor.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/aio/internal/shared.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/client.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/deterministic.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/__init__.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/backend_service_pb2.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/backend_service_pb2.pyi +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/backend_service_pb2_grpc.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/grpc_interceptor.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/history_events_pb2_grpc.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/orchestration_pb2.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/orchestration_pb2.pyi +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/orchestration_pb2_grpc.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/orchestrator_actions_pb2_grpc.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/orchestrator_service_pb2.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/orchestrator_service_pb2.pyi +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/orchestrator_service_pb2_grpc.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/protos.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/runtime_state_pb2.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/runtime_state_pb2.pyi +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/runtime_state_pb2_grpc.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/internal/shared.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/aio/__init__.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/aio/dapr_workflow_client.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/dapr_workflow_client.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/logger/__init__.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/logger/logger.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/logger/options.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/py.typed +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/retry_policy.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/util.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/version.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/workflow_activity_context.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/workflow_runtime.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/workflow_state.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr_ext_workflow_dev.egg-info/dependency_links.txt +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr_ext_workflow_dev.egg-info/requires.txt +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr_ext_workflow_dev.egg-info/top_level.txt +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/setup.cfg +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/setup.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/tests/test_dapr_workflow_context.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/tests/test_workflow_activity_context.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/tests/test_workflow_client.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/tests/test_workflow_client_aio.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/tests/test_workflow_runtime.py +0 -0
- {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/tests/test_workflow_util.py +0 -0
|
@@ -14,6 +14,15 @@ from datetime import datetime
|
|
|
14
14
|
from typing import Optional
|
|
15
15
|
|
|
16
16
|
import dapr.ext.workflow._durabletask.internal.protos as pb
|
|
17
|
+
from dapr.ext.workflow._durabletask.internal.timer import ( # noqa: F401
|
|
18
|
+
OPTIONAL_TIMER_FIRE_AT,
|
|
19
|
+
TimerOrigin,
|
|
20
|
+
is_optional_timer_action,
|
|
21
|
+
is_optional_timer_event,
|
|
22
|
+
new_create_timer_action,
|
|
23
|
+
new_timer_created_event,
|
|
24
|
+
new_timer_fired_event,
|
|
25
|
+
)
|
|
17
26
|
from google.protobuf import timestamp_pb2, wrappers_pb2
|
|
18
27
|
|
|
19
28
|
# TODO: The new_xxx_event methods are only used by test code and should be moved elsewhere
|
|
@@ -40,26 +49,6 @@ def new_execution_started_event(
|
|
|
40
49
|
)
|
|
41
50
|
|
|
42
51
|
|
|
43
|
-
def new_timer_created_event(timer_id: int, fire_at: datetime) -> pb.HistoryEvent:
|
|
44
|
-
ts = timestamp_pb2.Timestamp()
|
|
45
|
-
ts.FromDatetime(fire_at)
|
|
46
|
-
return pb.HistoryEvent(
|
|
47
|
-
eventId=timer_id,
|
|
48
|
-
timestamp=timestamp_pb2.Timestamp(),
|
|
49
|
-
timerCreated=pb.TimerCreatedEvent(fireAt=ts),
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def new_timer_fired_event(timer_id: int, fire_at: datetime) -> pb.HistoryEvent:
|
|
54
|
-
ts = timestamp_pb2.Timestamp()
|
|
55
|
-
ts.FromDatetime(fire_at)
|
|
56
|
-
return pb.HistoryEvent(
|
|
57
|
-
eventId=-1,
|
|
58
|
-
timestamp=timestamp_pb2.Timestamp(),
|
|
59
|
-
timerFired=pb.TimerFiredEvent(fireAt=ts, timerId=timer_id),
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
|
|
63
52
|
def new_task_scheduled_event(
|
|
64
53
|
event_id: int, name: str, encoded_input: Optional[str] = None
|
|
65
54
|
) -> pb.HistoryEvent:
|
|
@@ -202,12 +191,6 @@ def new_workflow_version_not_available_action(
|
|
|
202
191
|
)
|
|
203
192
|
|
|
204
193
|
|
|
205
|
-
def new_create_timer_action(id: int, fire_at: datetime) -> pb.WorkflowAction:
|
|
206
|
-
timestamp = timestamp_pb2.Timestamp()
|
|
207
|
-
timestamp.FromDatetime(fire_at)
|
|
208
|
-
return pb.WorkflowAction(id=id, createTimer=pb.CreateTimerAction(fireAt=timestamp))
|
|
209
|
-
|
|
210
|
-
|
|
211
194
|
def new_schedule_task_action(
|
|
212
195
|
id: int,
|
|
213
196
|
name: str,
|
|
@@ -27,7 +27,7 @@ from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__
|
|
|
27
27
|
from google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14history_events.proto\x1a\x13orchestration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/wrappers.proto\"\xd6\x03\n\x15\x45xecutionStartedEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x07version\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x10workflowInstance\x18\x04 \x01(\x0b\x32\x11.WorkflowInstance\x12+\n\x0eparentInstance\x18\x05 \x01(\x0b\x32\x13.ParentInstanceInfo\x12;\n\x17scheduledStartTimestamp\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12)\n\x12parentTraceContext\x18\x07 \x01(\x0b\x32\r.TraceContext\x12\x34\n\x0eworkflowSpanID\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12.\n\x04tags\x18\t \x03(\x0b\x32 .ExecutionStartedEvent.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xa2\x01\n\x17\x45xecutionCompletedEvent\x12,\n\x0eworkflowStatus\x18\x01 \x01(\x0e\x32\x14.OrchestrationStatus\x12,\n\x06result\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x0e\x66\x61ilureDetails\x18\x03 \x01(\x0b\x32\x13.TaskFailureDetails\"X\n\x18\x45xecutionTerminatedEvent\x12+\n\x05input\x18\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x0f\n\x07recurse\x18\x02 \x01(\x08\"\x9e\x02\n\x12TaskScheduledEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x07version\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12)\n\x12parentTraceContext\x18\x04 \x01(\x0b\x32\r.TraceContext\x12\x17\n\x0ftaskExecutionId\x18\x05 \x01(\t\x12>\n\x17rerunParentInstanceInfo\x18\x06 \x01(\x0b\x32\x18.RerunParentInstanceInfoH\x00\x88\x01\x01\x42\x1a\n\x18_rerunParentInstanceInfo\"t\n\x12TaskCompletedEvent\x12\x17\n\x0ftaskScheduledId\x18\x01 \x01(\x05\x12,\n\x06result\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x17\n\x0ftaskExecutionId\x18\x03 \x01(\t\"p\n\x0fTaskFailedEvent\x12\x17\n\x0ftaskScheduledId\x18\x01 \x01(\x05\x12+\n\x0e\x66\x61ilureDetails\x18\x02 \x01(\x0b\x32\x13.TaskFailureDetails\x12\x17\n\x0ftaskExecutionId\x18\x03 \x01(\t\"\xa8\x02\n!ChildWorkflowInstanceCreatedEvent\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12-\n\x07version\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12)\n\x12parentTraceContext\x18\x05 \x01(\x0b\x32\r.TraceContext\x12>\n\x17rerunParentInstanceInfo\x18\x06 \x01(\x0b\x32\x18.RerunParentInstanceInfoH\x00\x88\x01\x01\x42\x1a\n\x18_rerunParentInstanceInfo\"l\n#ChildWorkflowInstanceCompletedEvent\x12\x17\n\x0ftaskScheduledId\x18\x01 \x01(\x05\x12,\n\x06result\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"h\n ChildWorkflowInstanceFailedEvent\x12\x17\n\x0ftaskScheduledId\x18\x01 \x01(\x05\x12+\n\x0e\x66\x61ilureDetails\x18\x02 \x01(\x0b\x32\x13.TaskFailureDetails\"\x18\n\x16TimerOriginCreateTimer\"(\n\x18TimerOriginExternalEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\"\
|
|
30
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14history_events.proto\x1a\x13orchestration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/wrappers.proto\"\xd6\x03\n\x15\x45xecutionStartedEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x07version\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x10workflowInstance\x18\x04 \x01(\x0b\x32\x11.WorkflowInstance\x12+\n\x0eparentInstance\x18\x05 \x01(\x0b\x32\x13.ParentInstanceInfo\x12;\n\x17scheduledStartTimestamp\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12)\n\x12parentTraceContext\x18\x07 \x01(\x0b\x32\r.TraceContext\x12\x34\n\x0eworkflowSpanID\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12.\n\x04tags\x18\t \x03(\x0b\x32 .ExecutionStartedEvent.TagsEntry\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xa2\x01\n\x17\x45xecutionCompletedEvent\x12,\n\x0eworkflowStatus\x18\x01 \x01(\x0e\x32\x14.OrchestrationStatus\x12,\n\x06result\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x0e\x66\x61ilureDetails\x18\x03 \x01(\x0b\x32\x13.TaskFailureDetails\"X\n\x18\x45xecutionTerminatedEvent\x12+\n\x05input\x18\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x0f\n\x07recurse\x18\x02 \x01(\x08\"\x9e\x02\n\x12TaskScheduledEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x07version\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12)\n\x12parentTraceContext\x18\x04 \x01(\x0b\x32\r.TraceContext\x12\x17\n\x0ftaskExecutionId\x18\x05 \x01(\t\x12>\n\x17rerunParentInstanceInfo\x18\x06 \x01(\x0b\x32\x18.RerunParentInstanceInfoH\x00\x88\x01\x01\x42\x1a\n\x18_rerunParentInstanceInfo\"t\n\x12TaskCompletedEvent\x12\x17\n\x0ftaskScheduledId\x18\x01 \x01(\x05\x12,\n\x06result\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x17\n\x0ftaskExecutionId\x18\x03 \x01(\t\"p\n\x0fTaskFailedEvent\x12\x17\n\x0ftaskScheduledId\x18\x01 \x01(\x05\x12+\n\x0e\x66\x61ilureDetails\x18\x02 \x01(\x0b\x32\x13.TaskFailureDetails\x12\x17\n\x0ftaskExecutionId\x18\x03 \x01(\t\"\xa8\x02\n!ChildWorkflowInstanceCreatedEvent\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12-\n\x07version\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12)\n\x12parentTraceContext\x18\x05 \x01(\x0b\x32\r.TraceContext\x12>\n\x17rerunParentInstanceInfo\x18\x06 \x01(\x0b\x32\x18.RerunParentInstanceInfoH\x00\x88\x01\x01\x42\x1a\n\x18_rerunParentInstanceInfo\"l\n#ChildWorkflowInstanceCompletedEvent\x12\x17\n\x0ftaskScheduledId\x18\x01 \x01(\x05\x12,\n\x06result\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"h\n ChildWorkflowInstanceFailedEvent\x12\x17\n\x0ftaskScheduledId\x18\x01 \x01(\x05\x12+\n\x0e\x66\x61ilureDetails\x18\x02 \x01(\x0b\x32\x13.TaskFailureDetails\"\x18\n\x16TimerOriginCreateTimer\"(\n\x18TimerOriginExternalEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\"3\n\x18TimerOriginActivityRetry\x12\x17\n\x0ftaskExecutionId\x18\x01 \x01(\t\"3\n\x1dTimerOriginChildWorkflowRetry\x12\x12\n\ninstanceId\x18\x01 \x01(\t\"\x97\x03\n\x11TimerCreatedEvent\x12*\n\x06\x66ireAt\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x11\n\x04name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12>\n\x17rerunParentInstanceInfo\x18\x03 \x01(\x0b\x32\x18.RerunParentInstanceInfoH\x02\x88\x01\x01\x12.\n\x0b\x63reateTimer\x18\x04 \x01(\x0b\x32\x17.TimerOriginCreateTimerH\x00\x12\x32\n\rexternalEvent\x18\x05 \x01(\x0b\x32\x19.TimerOriginExternalEventH\x00\x12\x32\n\ractivityRetry\x18\x06 \x01(\x0b\x32\x19.TimerOriginActivityRetryH\x00\x12<\n\x12\x63hildWorkflowRetry\x18\x07 \x01(\x0b\x32\x1e.TimerOriginChildWorkflowRetryH\x00\x42\x08\n\x06originB\x07\n\x05_nameB\x1a\n\x18_rerunParentInstanceInfo\"N\n\x0fTimerFiredEvent\x12*\n\x06\x66ireAt\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0f\n\x07timerId\x18\x02 \x01(\x05\"J\n\x14WorkflowStartedEvent\x12&\n\x07version\x18\x01 \x01(\x0b\x32\x10.WorkflowVersionH\x00\x88\x01\x01\x42\n\n\x08_version\"\x18\n\x16WorkflowCompletedEvent\"_\n\x0e\x45ventSentEvent\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12+\n\x05input\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"M\n\x10\x45ventRaisedEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12+\n\x05input\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"A\n\x12\x43ontinueAsNewEvent\x12+\n\x05input\x18\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"F\n\x17\x45xecutionSuspendedEvent\x12+\n\x05input\x18\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"D\n\x15\x45xecutionResumedEvent\x12+\n\x05input\x18\x01 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"a\n\x15\x45xecutionStalledEvent\x12\x1e\n\x06reason\x18\x01 \x01(\x0e\x32\x0e.StalledReason\x12\x18\n\x0b\x64\x65scription\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0e\n\x0c_description\"\xa8\t\n\x0cHistoryEvent\x12\x0f\n\x07\x65ventId\x18\x01 \x01(\x05\x12-\n\ttimestamp\x18\x02 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x32\n\x10\x65xecutionStarted\x18\x03 \x01(\x0b\x32\x16.ExecutionStartedEventH\x00\x12\x36\n\x12\x65xecutionCompleted\x18\x04 \x01(\x0b\x32\x18.ExecutionCompletedEventH\x00\x12\x38\n\x13\x65xecutionTerminated\x18\x05 \x01(\x0b\x32\x19.ExecutionTerminatedEventH\x00\x12,\n\rtaskScheduled\x18\x06 \x01(\x0b\x32\x13.TaskScheduledEventH\x00\x12,\n\rtaskCompleted\x18\x07 \x01(\x0b\x32\x13.TaskCompletedEventH\x00\x12&\n\ntaskFailed\x18\x08 \x01(\x0b\x32\x10.TaskFailedEventH\x00\x12J\n\x1c\x63hildWorkflowInstanceCreated\x18\t \x01(\x0b\x32\".ChildWorkflowInstanceCreatedEventH\x00\x12N\n\x1e\x63hildWorkflowInstanceCompleted\x18\n \x01(\x0b\x32$.ChildWorkflowInstanceCompletedEventH\x00\x12H\n\x1b\x63hildWorkflowInstanceFailed\x18\x0b \x01(\x0b\x32!.ChildWorkflowInstanceFailedEventH\x00\x12*\n\x0ctimerCreated\x18\x0c \x01(\x0b\x32\x12.TimerCreatedEventH\x00\x12&\n\ntimerFired\x18\r \x01(\x0b\x32\x10.TimerFiredEventH\x00\x12\x30\n\x0fworkflowStarted\x18\x0e \x01(\x0b\x32\x15.WorkflowStartedEventH\x00\x12\x34\n\x11workflowCompleted\x18\x0f \x01(\x0b\x32\x17.WorkflowCompletedEventH\x00\x12$\n\teventSent\x18\x10 \x01(\x0b\x32\x0f.EventSentEventH\x00\x12(\n\x0b\x65ventRaised\x18\x11 \x01(\x0b\x32\x11.EventRaisedEventH\x00\x12,\n\rcontinueAsNew\x18\x14 \x01(\x0b\x32\x13.ContinueAsNewEventH\x00\x12\x36\n\x12\x65xecutionSuspended\x18\x15 \x01(\x0b\x32\x18.ExecutionSuspendedEventH\x00\x12\x32\n\x10\x65xecutionResumed\x18\x16 \x01(\x0b\x32\x16.ExecutionResumedEventH\x00\x12\x32\n\x10\x65xecutionStalled\x18\x1f \x01(\x0b\x32\x16.ExecutionStalledEventH\x00\x12 \n\x06router\x18\x1e \x01(\x0b\x32\x0b.TaskRouterH\x01\x88\x01\x01\x42\x0b\n\teventTypeB\t\n\x07_routerJ\x04\x08\x12\x10\x13J\x04\x08\x13\x10\x14J\x04\x08\x17\x10\x18J\x04\x08\x18\x10\x19J\x04\x08\x19\x10\x1aJ\x04\x08\x1a\x10\x1bJ\x04\x08\x1b\x10\x1cJ\x04\x08\x1c\x10\x1dJ\x04\x08\x1d\x10\x1e\x42V\n+io.dapr.durabletask.implementation.protobufZ\x0b/api/protos\xaa\x02\x19\x44\x61pr.DurableTask.Protobufb\x06proto3')
|
|
31
31
|
|
|
32
32
|
_globals = globals()
|
|
33
33
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
@@ -61,26 +61,30 @@ if not _descriptor._USE_C_DESCRIPTORS:
|
|
|
61
61
|
_globals['_TIMERORIGINCREATETIMER']._serialized_end=1898
|
|
62
62
|
_globals['_TIMERORIGINEXTERNALEVENT']._serialized_start=1900
|
|
63
63
|
_globals['_TIMERORIGINEXTERNALEVENT']._serialized_end=1940
|
|
64
|
-
_globals['
|
|
65
|
-
_globals['
|
|
66
|
-
_globals['
|
|
67
|
-
_globals['
|
|
68
|
-
_globals['
|
|
69
|
-
_globals['
|
|
70
|
-
_globals['
|
|
71
|
-
_globals['
|
|
72
|
-
_globals['
|
|
73
|
-
_globals['
|
|
74
|
-
_globals['
|
|
75
|
-
_globals['
|
|
76
|
-
_globals['
|
|
77
|
-
_globals['
|
|
78
|
-
_globals['
|
|
79
|
-
_globals['
|
|
80
|
-
_globals['
|
|
81
|
-
_globals['
|
|
82
|
-
_globals['
|
|
83
|
-
_globals['
|
|
84
|
-
_globals['
|
|
85
|
-
_globals['
|
|
64
|
+
_globals['_TIMERORIGINACTIVITYRETRY']._serialized_start=1942
|
|
65
|
+
_globals['_TIMERORIGINACTIVITYRETRY']._serialized_end=1993
|
|
66
|
+
_globals['_TIMERORIGINCHILDWORKFLOWRETRY']._serialized_start=1995
|
|
67
|
+
_globals['_TIMERORIGINCHILDWORKFLOWRETRY']._serialized_end=2046
|
|
68
|
+
_globals['_TIMERCREATEDEVENT']._serialized_start=2049
|
|
69
|
+
_globals['_TIMERCREATEDEVENT']._serialized_end=2456
|
|
70
|
+
_globals['_TIMERFIREDEVENT']._serialized_start=2458
|
|
71
|
+
_globals['_TIMERFIREDEVENT']._serialized_end=2536
|
|
72
|
+
_globals['_WORKFLOWSTARTEDEVENT']._serialized_start=2538
|
|
73
|
+
_globals['_WORKFLOWSTARTEDEVENT']._serialized_end=2612
|
|
74
|
+
_globals['_WORKFLOWCOMPLETEDEVENT']._serialized_start=2614
|
|
75
|
+
_globals['_WORKFLOWCOMPLETEDEVENT']._serialized_end=2638
|
|
76
|
+
_globals['_EVENTSENTEVENT']._serialized_start=2640
|
|
77
|
+
_globals['_EVENTSENTEVENT']._serialized_end=2735
|
|
78
|
+
_globals['_EVENTRAISEDEVENT']._serialized_start=2737
|
|
79
|
+
_globals['_EVENTRAISEDEVENT']._serialized_end=2814
|
|
80
|
+
_globals['_CONTINUEASNEWEVENT']._serialized_start=2816
|
|
81
|
+
_globals['_CONTINUEASNEWEVENT']._serialized_end=2881
|
|
82
|
+
_globals['_EXECUTIONSUSPENDEDEVENT']._serialized_start=2883
|
|
83
|
+
_globals['_EXECUTIONSUSPENDEDEVENT']._serialized_end=2953
|
|
84
|
+
_globals['_EXECUTIONRESUMEDEVENT']._serialized_start=2955
|
|
85
|
+
_globals['_EXECUTIONRESUMEDEVENT']._serialized_end=3023
|
|
86
|
+
_globals['_EXECUTIONSTALLEDEVENT']._serialized_start=3025
|
|
87
|
+
_globals['_EXECUTIONSTALLEDEVENT']._serialized_end=3122
|
|
88
|
+
_globals['_HISTORYEVENT']._serialized_start=3125
|
|
89
|
+
_globals['_HISTORYEVENT']._serialized_end=4317
|
|
86
90
|
# @@protoc_insertion_point(module_scope)
|
|
@@ -351,6 +351,44 @@ class TimerOriginExternalEvent(_message.Message):
|
|
|
351
351
|
|
|
352
352
|
Global___TimerOriginExternalEvent: _TypeAlias = TimerOriginExternalEvent # noqa: Y015
|
|
353
353
|
|
|
354
|
+
@_typing.final
|
|
355
|
+
class TimerOriginActivityRetry(_message.Message):
|
|
356
|
+
"""Indicates the timer was created as a retry delay for an activity execution."""
|
|
357
|
+
|
|
358
|
+
DESCRIPTOR: _descriptor.Descriptor
|
|
359
|
+
|
|
360
|
+
TASKEXECUTIONID_FIELD_NUMBER: _builtins.int
|
|
361
|
+
taskExecutionId: _builtins.str
|
|
362
|
+
"""The task execution ID of the activity being retried."""
|
|
363
|
+
def __init__(
|
|
364
|
+
self,
|
|
365
|
+
*,
|
|
366
|
+
taskExecutionId: _builtins.str = ...,
|
|
367
|
+
) -> None: ...
|
|
368
|
+
_ClearFieldArgType: _TypeAlias = _typing.Literal["taskExecutionId", b"taskExecutionId"] # noqa: Y015
|
|
369
|
+
def ClearField(self, field_name: _ClearFieldArgType) -> None: ...
|
|
370
|
+
|
|
371
|
+
Global___TimerOriginActivityRetry: _TypeAlias = TimerOriginActivityRetry # noqa: Y015
|
|
372
|
+
|
|
373
|
+
@_typing.final
|
|
374
|
+
class TimerOriginChildWorkflowRetry(_message.Message):
|
|
375
|
+
"""Indicates the timer was created as a retry delay for a child workflow execution."""
|
|
376
|
+
|
|
377
|
+
DESCRIPTOR: _descriptor.Descriptor
|
|
378
|
+
|
|
379
|
+
INSTANCEID_FIELD_NUMBER: _builtins.int
|
|
380
|
+
instanceId: _builtins.str
|
|
381
|
+
"""The instance ID of the workflow being retried."""
|
|
382
|
+
def __init__(
|
|
383
|
+
self,
|
|
384
|
+
*,
|
|
385
|
+
instanceId: _builtins.str = ...,
|
|
386
|
+
) -> None: ...
|
|
387
|
+
_ClearFieldArgType: _TypeAlias = _typing.Literal["instanceId", b"instanceId"] # noqa: Y015
|
|
388
|
+
def ClearField(self, field_name: _ClearFieldArgType) -> None: ...
|
|
389
|
+
|
|
390
|
+
Global___TimerOriginChildWorkflowRetry: _TypeAlias = TimerOriginChildWorkflowRetry # noqa: Y015
|
|
391
|
+
|
|
354
392
|
@_typing.final
|
|
355
393
|
class TimerCreatedEvent(_message.Message):
|
|
356
394
|
DESCRIPTOR: _descriptor.Descriptor
|
|
@@ -360,6 +398,8 @@ class TimerCreatedEvent(_message.Message):
|
|
|
360
398
|
RERUNPARENTINSTANCEINFO_FIELD_NUMBER: _builtins.int
|
|
361
399
|
CREATETIMER_FIELD_NUMBER: _builtins.int
|
|
362
400
|
EXTERNALEVENT_FIELD_NUMBER: _builtins.int
|
|
401
|
+
ACTIVITYRETRY_FIELD_NUMBER: _builtins.int
|
|
402
|
+
CHILDWORKFLOWRETRY_FIELD_NUMBER: _builtins.int
|
|
363
403
|
name: _builtins.str
|
|
364
404
|
@_builtins.property
|
|
365
405
|
def fireAt(self) -> _timestamp_pb2.Timestamp: ...
|
|
@@ -373,6 +413,10 @@ class TimerCreatedEvent(_message.Message):
|
|
|
373
413
|
def createTimer(self) -> Global___TimerOriginCreateTimer: ...
|
|
374
414
|
@_builtins.property
|
|
375
415
|
def externalEvent(self) -> Global___TimerOriginExternalEvent: ...
|
|
416
|
+
@_builtins.property
|
|
417
|
+
def activityRetry(self) -> Global___TimerOriginActivityRetry: ...
|
|
418
|
+
@_builtins.property
|
|
419
|
+
def childWorkflowRetry(self) -> Global___TimerOriginChildWorkflowRetry: ...
|
|
376
420
|
def __init__(
|
|
377
421
|
self,
|
|
378
422
|
*,
|
|
@@ -381,16 +425,18 @@ class TimerCreatedEvent(_message.Message):
|
|
|
381
425
|
rerunParentInstanceInfo: _orchestration_pb2.RerunParentInstanceInfo | None = ...,
|
|
382
426
|
createTimer: Global___TimerOriginCreateTimer | None = ...,
|
|
383
427
|
externalEvent: Global___TimerOriginExternalEvent | None = ...,
|
|
428
|
+
activityRetry: Global___TimerOriginActivityRetry | None = ...,
|
|
429
|
+
childWorkflowRetry: Global___TimerOriginChildWorkflowRetry | None = ...,
|
|
384
430
|
) -> None: ...
|
|
385
|
-
_HasFieldArgType: _TypeAlias = _typing.Literal["_name", b"_name", "_rerunParentInstanceInfo", b"_rerunParentInstanceInfo", "createTimer", b"createTimer", "externalEvent", b"externalEvent", "fireAt", b"fireAt", "name", b"name", "origin", b"origin", "rerunParentInstanceInfo", b"rerunParentInstanceInfo"] # noqa: Y015
|
|
431
|
+
_HasFieldArgType: _TypeAlias = _typing.Literal["_name", b"_name", "_rerunParentInstanceInfo", b"_rerunParentInstanceInfo", "activityRetry", b"activityRetry", "childWorkflowRetry", b"childWorkflowRetry", "createTimer", b"createTimer", "externalEvent", b"externalEvent", "fireAt", b"fireAt", "name", b"name", "origin", b"origin", "rerunParentInstanceInfo", b"rerunParentInstanceInfo"] # noqa: Y015
|
|
386
432
|
def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ...
|
|
387
|
-
_ClearFieldArgType: _TypeAlias = _typing.Literal["_name", b"_name", "_rerunParentInstanceInfo", b"_rerunParentInstanceInfo", "createTimer", b"createTimer", "externalEvent", b"externalEvent", "fireAt", b"fireAt", "name", b"name", "origin", b"origin", "rerunParentInstanceInfo", b"rerunParentInstanceInfo"] # noqa: Y015
|
|
433
|
+
_ClearFieldArgType: _TypeAlias = _typing.Literal["_name", b"_name", "_rerunParentInstanceInfo", b"_rerunParentInstanceInfo", "activityRetry", b"activityRetry", "childWorkflowRetry", b"childWorkflowRetry", "createTimer", b"createTimer", "externalEvent", b"externalEvent", "fireAt", b"fireAt", "name", b"name", "origin", b"origin", "rerunParentInstanceInfo", b"rerunParentInstanceInfo"] # noqa: Y015
|
|
388
434
|
def ClearField(self, field_name: _ClearFieldArgType) -> None: ...
|
|
389
435
|
_WhichOneofReturnType__name: _TypeAlias = _typing.Literal["name"] # noqa: Y015
|
|
390
436
|
_WhichOneofArgType__name: _TypeAlias = _typing.Literal["_name", b"_name"] # noqa: Y015
|
|
391
437
|
_WhichOneofReturnType__rerunParentInstanceInfo: _TypeAlias = _typing.Literal["rerunParentInstanceInfo"] # noqa: Y015
|
|
392
438
|
_WhichOneofArgType__rerunParentInstanceInfo: _TypeAlias = _typing.Literal["_rerunParentInstanceInfo", b"_rerunParentInstanceInfo"] # noqa: Y015
|
|
393
|
-
_WhichOneofReturnType_origin: _TypeAlias = _typing.Literal["createTimer", "externalEvent"] # noqa: Y015
|
|
439
|
+
_WhichOneofReturnType_origin: _TypeAlias = _typing.Literal["createTimer", "externalEvent", "activityRetry", "childWorkflowRetry"] # noqa: Y015
|
|
394
440
|
_WhichOneofArgType_origin: _TypeAlias = _typing.Literal["origin", b"origin"] # noqa: Y015
|
|
395
441
|
@_typing.overload
|
|
396
442
|
def WhichOneof(self, oneof_group: _WhichOneofArgType__name) -> _WhichOneofReturnType__name | None: ...
|
|
@@ -28,7 +28,7 @@ from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__
|
|
|
28
28
|
from google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1aorchestrator_actions.proto\x1a\x13orchestration.proto\x1a\x14history_events.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/wrappers.proto\"\xc4\x01\n\x12ScheduleTaskAction\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x07version\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12 \n\x06router\x18\x04 \x01(\x0b\x32\x0b.TaskRouterH\x00\x88\x01\x01\x12\x17\n\x0ftaskExecutionId\x18\x05 \x01(\tB\t\n\x07_router\"\xc6\x01\n\x19\x43reateChildWorkflowAction\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12-\n\x07version\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12 \n\x06router\x18\x05 \x01(\x0b\x32\x0b.TaskRouterH\x00\x88\x01\x01\x42\t\n\x07_router\"\
|
|
31
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1aorchestrator_actions.proto\x1a\x13orchestration.proto\x1a\x14history_events.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/wrappers.proto\"\xc4\x01\n\x12ScheduleTaskAction\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\x07version\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12 \n\x06router\x18\x04 \x01(\x0b\x32\x0b.TaskRouterH\x00\x88\x01\x01\x12\x17\n\x0ftaskExecutionId\x18\x05 \x01(\tB\t\n\x07_router\"\xc6\x01\n\x19\x43reateChildWorkflowAction\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12-\n\x07version\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12+\n\x05input\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12 \n\x06router\x18\x05 \x01(\x0b\x32\x0b.TaskRouterH\x00\x88\x01\x01\x42\t\n\x07_router\"\xbb\x02\n\x11\x43reateTimerAction\x12*\n\x06\x66ireAt\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x11\n\x04name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12.\n\x0b\x63reateTimer\x18\x03 \x01(\x0b\x32\x17.TimerOriginCreateTimerH\x00\x12\x32\n\rexternalEvent\x18\x04 \x01(\x0b\x32\x19.TimerOriginExternalEventH\x00\x12\x32\n\ractivityRetry\x18\x05 \x01(\x0b\x32\x19.TimerOriginActivityRetryH\x00\x12<\n\x12\x63hildWorkflowRetry\x18\x06 \x01(\x0b\x32\x1e.TimerOriginChildWorkflowRetryH\x00\x42\x08\n\x06originB\x07\n\x05_name\"p\n\x0fSendEventAction\x12#\n\x08instance\x18\x01 \x01(\x0b\x32\x11.WorkflowInstance\x12\x0c\n\x04name\x18\x02 \x01(\t\x12*\n\x04\x64\x61ta\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\"\xaa\x02\n\x16\x43ompleteWorkflowAction\x12,\n\x0eworkflowStatus\x18\x01 \x01(\x0e\x32\x14.OrchestrationStatus\x12,\n\x06result\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12-\n\x07\x64\x65tails\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x30\n\nnewVersion\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12&\n\x0f\x63\x61rryoverEvents\x18\x05 \x03(\x0b\x32\r.HistoryEvent\x12+\n\x0e\x66\x61ilureDetails\x18\x06 \x01(\x0b\x32\x13.TaskFailureDetails\"l\n\x17TerminateWorkflowAction\x12\x12\n\ninstanceId\x18\x01 \x01(\t\x12,\n\x06reason\x18\x02 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x0f\n\x07recurse\x18\x03 \x01(\x08\"#\n!WorkflowVersionNotAvailableAction\"\xd6\x03\n\x0eWorkflowAction\x12\n\n\x02id\x18\x01 \x01(\x05\x12+\n\x0cscheduleTask\x18\x02 \x01(\x0b\x32\x13.ScheduleTaskActionH\x00\x12\x39\n\x13\x63reateChildWorkflow\x18\x03 \x01(\x0b\x32\x1a.CreateChildWorkflowActionH\x00\x12)\n\x0b\x63reateTimer\x18\x04 \x01(\x0b\x32\x12.CreateTimerActionH\x00\x12%\n\tsendEvent\x18\x05 \x01(\x0b\x32\x10.SendEventActionH\x00\x12\x33\n\x10\x63ompleteWorkflow\x18\x06 \x01(\x0b\x32\x17.CompleteWorkflowActionH\x00\x12\x35\n\x11terminateWorkflow\x18\x07 \x01(\x0b\x32\x18.TerminateWorkflowActionH\x00\x12I\n\x1bworkflowVersionNotAvailable\x18\n \x01(\x0b\x32\".WorkflowVersionNotAvailableActionH\x00\x12 \n\x06router\x18\t \x01(\x0b\x32\x0b.TaskRouterH\x01\x88\x01\x01\x42\x14\n\x12workflowActionTypeB\t\n\x07_routerJ\x04\x08\x08\x10\tBV\n+io.dapr.durabletask.implementation.protobufZ\x0b/api/protos\xaa\x02\x19\x44\x61pr.DurableTask.Protobufb\x06proto3')
|
|
32
32
|
|
|
33
33
|
_globals = globals()
|
|
34
34
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
@@ -41,15 +41,15 @@ if not _descriptor._USE_C_DESCRIPTORS:
|
|
|
41
41
|
_globals['_CREATECHILDWORKFLOWACTION']._serialized_start=338
|
|
42
42
|
_globals['_CREATECHILDWORKFLOWACTION']._serialized_end=536
|
|
43
43
|
_globals['_CREATETIMERACTION']._serialized_start=539
|
|
44
|
-
_globals['_CREATETIMERACTION']._serialized_end=
|
|
45
|
-
_globals['_SENDEVENTACTION']._serialized_start=
|
|
46
|
-
_globals['_SENDEVENTACTION']._serialized_end=
|
|
47
|
-
_globals['_COMPLETEWORKFLOWACTION']._serialized_start=
|
|
48
|
-
_globals['_COMPLETEWORKFLOWACTION']._serialized_end=
|
|
49
|
-
_globals['_TERMINATEWORKFLOWACTION']._serialized_start=
|
|
50
|
-
_globals['_TERMINATEWORKFLOWACTION']._serialized_end=
|
|
51
|
-
_globals['_WORKFLOWVERSIONNOTAVAILABLEACTION']._serialized_start=
|
|
52
|
-
_globals['_WORKFLOWVERSIONNOTAVAILABLEACTION']._serialized_end=
|
|
53
|
-
_globals['_WORKFLOWACTION']._serialized_start=
|
|
54
|
-
_globals['_WORKFLOWACTION']._serialized_end=
|
|
44
|
+
_globals['_CREATETIMERACTION']._serialized_end=854
|
|
45
|
+
_globals['_SENDEVENTACTION']._serialized_start=856
|
|
46
|
+
_globals['_SENDEVENTACTION']._serialized_end=968
|
|
47
|
+
_globals['_COMPLETEWORKFLOWACTION']._serialized_start=971
|
|
48
|
+
_globals['_COMPLETEWORKFLOWACTION']._serialized_end=1269
|
|
49
|
+
_globals['_TERMINATEWORKFLOWACTION']._serialized_start=1271
|
|
50
|
+
_globals['_TERMINATEWORKFLOWACTION']._serialized_end=1379
|
|
51
|
+
_globals['_WORKFLOWVERSIONNOTAVAILABLEACTION']._serialized_start=1381
|
|
52
|
+
_globals['_WORKFLOWVERSIONNOTAVAILABLEACTION']._serialized_end=1416
|
|
53
|
+
_globals['_WORKFLOWACTION']._serialized_start=1419
|
|
54
|
+
_globals['_WORKFLOWACTION']._serialized_end=1889
|
|
55
55
|
# @@protoc_insertion_point(module_scope)
|
|
@@ -104,6 +104,8 @@ class CreateTimerAction(_message.Message):
|
|
|
104
104
|
NAME_FIELD_NUMBER: _builtins.int
|
|
105
105
|
CREATETIMER_FIELD_NUMBER: _builtins.int
|
|
106
106
|
EXTERNALEVENT_FIELD_NUMBER: _builtins.int
|
|
107
|
+
ACTIVITYRETRY_FIELD_NUMBER: _builtins.int
|
|
108
|
+
CHILDWORKFLOWRETRY_FIELD_NUMBER: _builtins.int
|
|
107
109
|
name: _builtins.str
|
|
108
110
|
@_builtins.property
|
|
109
111
|
def fireAt(self) -> _timestamp_pb2.Timestamp: ...
|
|
@@ -111,6 +113,10 @@ class CreateTimerAction(_message.Message):
|
|
|
111
113
|
def createTimer(self) -> _history_events_pb2.TimerOriginCreateTimer: ...
|
|
112
114
|
@_builtins.property
|
|
113
115
|
def externalEvent(self) -> _history_events_pb2.TimerOriginExternalEvent: ...
|
|
116
|
+
@_builtins.property
|
|
117
|
+
def activityRetry(self) -> _history_events_pb2.TimerOriginActivityRetry: ...
|
|
118
|
+
@_builtins.property
|
|
119
|
+
def childWorkflowRetry(self) -> _history_events_pb2.TimerOriginChildWorkflowRetry: ...
|
|
114
120
|
def __init__(
|
|
115
121
|
self,
|
|
116
122
|
*,
|
|
@@ -118,14 +124,16 @@ class CreateTimerAction(_message.Message):
|
|
|
118
124
|
name: _builtins.str | None = ...,
|
|
119
125
|
createTimer: _history_events_pb2.TimerOriginCreateTimer | None = ...,
|
|
120
126
|
externalEvent: _history_events_pb2.TimerOriginExternalEvent | None = ...,
|
|
127
|
+
activityRetry: _history_events_pb2.TimerOriginActivityRetry | None = ...,
|
|
128
|
+
childWorkflowRetry: _history_events_pb2.TimerOriginChildWorkflowRetry | None = ...,
|
|
121
129
|
) -> None: ...
|
|
122
|
-
_HasFieldArgType: _TypeAlias = _typing.Literal["_name", b"_name", "createTimer", b"createTimer", "externalEvent", b"externalEvent", "fireAt", b"fireAt", "name", b"name", "origin", b"origin"] # noqa: Y015
|
|
130
|
+
_HasFieldArgType: _TypeAlias = _typing.Literal["_name", b"_name", "activityRetry", b"activityRetry", "childWorkflowRetry", b"childWorkflowRetry", "createTimer", b"createTimer", "externalEvent", b"externalEvent", "fireAt", b"fireAt", "name", b"name", "origin", b"origin"] # noqa: Y015
|
|
123
131
|
def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ...
|
|
124
|
-
_ClearFieldArgType: _TypeAlias = _typing.Literal["_name", b"_name", "createTimer", b"createTimer", "externalEvent", b"externalEvent", "fireAt", b"fireAt", "name", b"name", "origin", b"origin"] # noqa: Y015
|
|
132
|
+
_ClearFieldArgType: _TypeAlias = _typing.Literal["_name", b"_name", "activityRetry", b"activityRetry", "childWorkflowRetry", b"childWorkflowRetry", "createTimer", b"createTimer", "externalEvent", b"externalEvent", "fireAt", b"fireAt", "name", b"name", "origin", b"origin"] # noqa: Y015
|
|
125
133
|
def ClearField(self, field_name: _ClearFieldArgType) -> None: ...
|
|
126
134
|
_WhichOneofReturnType__name: _TypeAlias = _typing.Literal["name"] # noqa: Y015
|
|
127
135
|
_WhichOneofArgType__name: _TypeAlias = _typing.Literal["_name", b"_name"] # noqa: Y015
|
|
128
|
-
_WhichOneofReturnType_origin: _TypeAlias = _typing.Literal["createTimer", "externalEvent"] # noqa: Y015
|
|
136
|
+
_WhichOneofReturnType_origin: _TypeAlias = _typing.Literal["createTimer", "externalEvent", "activityRetry", "childWorkflowRetry"] # noqa: Y015
|
|
129
137
|
_WhichOneofArgType_origin: _TypeAlias = _typing.Literal["origin", b"origin"] # noqa: Y015
|
|
130
138
|
@_typing.overload
|
|
131
139
|
def WhichOneof(self, oneof_group: _WhichOneofArgType__name) -> _WhichOneofReturnType__name | None: ...
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Copyright 2026 The Dapr Authors
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
7
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
8
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
9
|
+
# See the License for the specific language governing permissions and
|
|
10
|
+
# limitations under the License.
|
|
11
|
+
|
|
12
|
+
"""Timer-related helpers for the durabletask workflow SDK.
|
|
13
|
+
|
|
14
|
+
This module keeps all timer / TimerOrigin concerns in one place, separate from
|
|
15
|
+
the generic action/event helpers in ``helpers.py``.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from datetime import datetime
|
|
19
|
+
from typing import Optional, Union
|
|
20
|
+
|
|
21
|
+
import dapr.ext.workflow._durabletask.internal.protos as pb
|
|
22
|
+
from google.protobuf import timestamp_pb2
|
|
23
|
+
|
|
24
|
+
TimerOrigin = Union[
|
|
25
|
+
pb.TimerOriginCreateTimer,
|
|
26
|
+
pb.TimerOriginExternalEvent,
|
|
27
|
+
pb.TimerOriginActivityRetry,
|
|
28
|
+
pb.TimerOriginChildWorkflowRetry,
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
_ORIGIN_FIELD: dict[type, str] = {
|
|
32
|
+
pb.TimerOriginCreateTimer: 'createTimer',
|
|
33
|
+
pb.TimerOriginExternalEvent: 'externalEvent',
|
|
34
|
+
pb.TimerOriginActivityRetry: 'activityRetry',
|
|
35
|
+
pb.TimerOriginChildWorkflowRetry: 'childWorkflowRetry',
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# Sentinel fireAt used for "optional" TimerOriginExternalEvent timers that back
|
|
39
|
+
# an indefinite wait_for_external_event. The sentinel is
|
|
40
|
+
# 9999-12-31T23:59:59.999999999Z (nanosecond precision — Python's ``datetime``
|
|
41
|
+
# is only microsecond-precision, so we build the Timestamp directly).
|
|
42
|
+
OPTIONAL_TIMER_FIRE_AT: timestamp_pb2.Timestamp = timestamp_pb2.Timestamp(
|
|
43
|
+
seconds=253402300799, nanos=999999999
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _origin_kwargs(origin: Optional[TimerOrigin]) -> dict:
|
|
48
|
+
"""Build keyword args that set the correct origin oneof field on a
|
|
49
|
+
``CreateTimerAction`` / ``TimerCreatedEvent`` proto."""
|
|
50
|
+
if origin is None:
|
|
51
|
+
return {}
|
|
52
|
+
return {_ORIGIN_FIELD[type(origin)]: origin}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _to_timestamp(
|
|
56
|
+
fire_at: Union[datetime, timestamp_pb2.Timestamp],
|
|
57
|
+
) -> timestamp_pb2.Timestamp:
|
|
58
|
+
"""Normalize a ``fire_at`` argument to a protobuf ``Timestamp``."""
|
|
59
|
+
if isinstance(fire_at, timestamp_pb2.Timestamp):
|
|
60
|
+
return fire_at
|
|
61
|
+
ts = timestamp_pb2.Timestamp()
|
|
62
|
+
ts.FromDatetime(fire_at)
|
|
63
|
+
return ts
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _fire_at_matches_sentinel(ts: timestamp_pb2.Timestamp) -> bool:
|
|
67
|
+
"""Return True iff ``ts`` exactly matches :data:`OPTIONAL_TIMER_FIRE_AT`.
|
|
68
|
+
|
|
69
|
+
Both ``seconds`` and ``nanos`` are proto3 scalars that are always present
|
|
70
|
+
(default 0 when unset), so unconditional field access is safe.
|
|
71
|
+
"""
|
|
72
|
+
return ts.seconds == OPTIONAL_TIMER_FIRE_AT.seconds and ts.nanos == OPTIONAL_TIMER_FIRE_AT.nanos
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def is_optional_timer_action(action: pb.WorkflowAction) -> bool:
|
|
76
|
+
"""Returns True if the action is an optional TimerOriginExternalEvent timer
|
|
77
|
+
with the sentinel fireAt — i.e. created by an indefinite wait_for_external_event.
|
|
78
|
+
|
|
79
|
+
Pre-patch histories (from prior SDK versions that didn't schedule a timer
|
|
80
|
+
for indefinite waits) won't carry a matching TimerCreatedEvent; the replay
|
|
81
|
+
logic uses this check to drop the optional action and shift sequence ids.
|
|
82
|
+
"""
|
|
83
|
+
if not action.HasField('createTimer'):
|
|
84
|
+
return False
|
|
85
|
+
timer = action.createTimer
|
|
86
|
+
if timer.WhichOneof('origin') != 'externalEvent':
|
|
87
|
+
return False
|
|
88
|
+
return _fire_at_matches_sentinel(timer.fireAt)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def is_optional_timer_event(event: pb.HistoryEvent) -> bool:
|
|
92
|
+
"""Returns True if a TimerCreatedEvent is the optional sentinel timer.
|
|
93
|
+
|
|
94
|
+
For replay compatibility, treat a timerCreated event with the sentinel
|
|
95
|
+
fireAt as optional even if the proto3 ``origin`` oneof is unset (e.g. when
|
|
96
|
+
reading histories emitted by older sidecars that didn't populate it). When
|
|
97
|
+
``origin`` *is* populated, it must match TimerOriginExternalEvent.
|
|
98
|
+
"""
|
|
99
|
+
if not event.HasField('timerCreated'):
|
|
100
|
+
return False
|
|
101
|
+
timer = event.timerCreated
|
|
102
|
+
if not _fire_at_matches_sentinel(timer.fireAt):
|
|
103
|
+
return False
|
|
104
|
+
origin = timer.WhichOneof('origin')
|
|
105
|
+
return origin in (None, 'externalEvent')
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def new_create_timer_action(
|
|
109
|
+
timer_id: int,
|
|
110
|
+
fire_at: Union[datetime, timestamp_pb2.Timestamp],
|
|
111
|
+
origin: Optional[TimerOrigin] = None,
|
|
112
|
+
) -> pb.WorkflowAction:
|
|
113
|
+
ts = _to_timestamp(fire_at)
|
|
114
|
+
return pb.WorkflowAction(
|
|
115
|
+
id=timer_id,
|
|
116
|
+
createTimer=pb.CreateTimerAction(fireAt=ts, **_origin_kwargs(origin)),
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def new_timer_created_event(
|
|
121
|
+
timer_id: int,
|
|
122
|
+
fire_at: Union[datetime, timestamp_pb2.Timestamp],
|
|
123
|
+
origin: Optional[TimerOrigin] = None,
|
|
124
|
+
) -> pb.HistoryEvent:
|
|
125
|
+
ts = _to_timestamp(fire_at)
|
|
126
|
+
return pb.HistoryEvent(
|
|
127
|
+
eventId=timer_id,
|
|
128
|
+
timestamp=timestamp_pb2.Timestamp(),
|
|
129
|
+
timerCreated=pb.TimerCreatedEvent(fireAt=ts, **_origin_kwargs(origin)),
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def new_timer_fired_event(
|
|
134
|
+
timer_id: int,
|
|
135
|
+
fire_at: Union[datetime, timestamp_pb2.Timestamp],
|
|
136
|
+
) -> pb.HistoryEvent:
|
|
137
|
+
ts = _to_timestamp(fire_at)
|
|
138
|
+
return pb.HistoryEvent(
|
|
139
|
+
eventId=-1,
|
|
140
|
+
timestamp=timestamp_pb2.Timestamp(),
|
|
141
|
+
timerFired=pb.TimerFiredEvent(fireAt=ts, timerId=timer_id),
|
|
142
|
+
)
|
|
@@ -166,21 +166,35 @@ class OrchestrationContext(ABC):
|
|
|
166
166
|
"""
|
|
167
167
|
pass
|
|
168
168
|
|
|
169
|
-
# TODO: Add a timeout parameter, which allows the task to be canceled if the event is
|
|
170
|
-
# not received within the specified timeout. This requires support for task cancellation.
|
|
171
169
|
@abstractmethod
|
|
172
|
-
def wait_for_external_event(
|
|
170
|
+
def wait_for_external_event(
|
|
171
|
+
self, name: str, *, timeout: Optional[Union[datetime, timedelta]] = None
|
|
172
|
+
) -> Task:
|
|
173
173
|
"""Wait asynchronously for an event to be raised with the name `name`.
|
|
174
174
|
|
|
175
175
|
Parameters
|
|
176
176
|
----------
|
|
177
177
|
name : str
|
|
178
178
|
The event name of the event that the task is waiting for.
|
|
179
|
+
timeout : datetime | timedelta | None
|
|
180
|
+
Controls how long to wait for the event. Accepts only ``datetime``
|
|
181
|
+
or ``timedelta`` — a plain numeric ``0`` is **not** a valid value
|
|
182
|
+
(use ``timedelta(0)`` explicitly). Three shapes:
|
|
183
|
+
|
|
184
|
+
* ``None`` (default) or a *negative* ``timedelta`` — wait indefinitely.
|
|
185
|
+
An optional sentinel timer is scheduled internally for runtime
|
|
186
|
+
tracking, but ``TimeoutError`` is never raised on its own.
|
|
187
|
+
* ``timedelta(0)`` — do not wait at all. The returned task fails
|
|
188
|
+
immediately with ``TimeoutError``.
|
|
189
|
+
* A future ``datetime`` or a positive ``timedelta`` — wait until
|
|
190
|
+
that deadline / for that duration; ``TimeoutError`` is raised if
|
|
191
|
+
the event has not been received in time.
|
|
179
192
|
|
|
180
193
|
Returns
|
|
181
194
|
-------
|
|
182
195
|
Task[TOutput]
|
|
183
|
-
A Durable Task that completes when the event is received
|
|
196
|
+
A Durable Task that completes when the event is received or fails
|
|
197
|
+
with ``TimeoutError`` if the timeout fires first.
|
|
184
198
|
"""
|
|
185
199
|
pass
|
|
186
200
|
|
|
@@ -284,7 +298,7 @@ class Task(ABC, Generic[T]):
|
|
|
284
298
|
"""Abstract base class for asynchronous tasks in a durable orchestration."""
|
|
285
299
|
|
|
286
300
|
_result: T
|
|
287
|
-
_exception: Optional[
|
|
301
|
+
_exception: Optional[Exception]
|
|
288
302
|
_parent: Optional[CompositeTask[T]]
|
|
289
303
|
|
|
290
304
|
def __init__(self) -> None:
|
|
@@ -311,7 +325,7 @@ class Task(ABC, Generic[T]):
|
|
|
311
325
|
raise self._exception
|
|
312
326
|
return self._result
|
|
313
327
|
|
|
314
|
-
def get_exception(self) ->
|
|
328
|
+
def get_exception(self) -> Exception:
|
|
315
329
|
"""Returns the exception that caused the task to fail."""
|
|
316
330
|
if self._exception is None:
|
|
317
331
|
raise ValueError('The task has not failed.')
|
|
@@ -400,6 +414,23 @@ class CompletableTask(Task[T]):
|
|
|
400
414
|
if self._parent is not None:
|
|
401
415
|
self._parent.on_child_completed(self)
|
|
402
416
|
|
|
417
|
+
def cancel(self, exc: Exception) -> None:
|
|
418
|
+
"""Mark this task as completed with the given exception.
|
|
419
|
+
|
|
420
|
+
Used for non-runtime failures such as a zero-timeout
|
|
421
|
+
wait_for_external_event being canceled before any history event arrives.
|
|
422
|
+
|
|
423
|
+
Idempotent: a noop if the task has already completed (success or
|
|
424
|
+
failure), which matches the common semantics of ``cancel()`` in
|
|
425
|
+
asyncio / threading APIs.
|
|
426
|
+
"""
|
|
427
|
+
if self._is_complete:
|
|
428
|
+
return
|
|
429
|
+
self._exception = exc
|
|
430
|
+
self._is_complete = True
|
|
431
|
+
if self._parent is not None:
|
|
432
|
+
self._parent.on_child_completed(self)
|
|
433
|
+
|
|
403
434
|
|
|
404
435
|
class RetryableTask(CompletableTask[T]):
|
|
405
436
|
"""A task that can be retried according to a retry policy."""
|
|
@@ -497,6 +528,54 @@ class WhenAnyTask(CompositeTask[Task]):
|
|
|
497
528
|
self._parent.on_child_completed(self)
|
|
498
529
|
|
|
499
530
|
|
|
531
|
+
class ExternalEventWithTimeoutTask(CompositeTask[T]):
|
|
532
|
+
"""A task that waits for an external event with a timeout.
|
|
533
|
+
|
|
534
|
+
Completes with the event data if the event arrives first, or raises
|
|
535
|
+
``TimeoutError`` if the timer fires first.
|
|
536
|
+
|
|
537
|
+
When the timer wins, the optional ``on_timeout`` callback is invoked so the
|
|
538
|
+
caller can unregister the stale event task from ``_pending_events``, ensuring
|
|
539
|
+
that a late ``eventRaised`` for the same name is buffered rather than consumed
|
|
540
|
+
by the now-obsolete waiter.
|
|
541
|
+
"""
|
|
542
|
+
|
|
543
|
+
def __init__(
|
|
544
|
+
self,
|
|
545
|
+
event_task: CompletableTask,
|
|
546
|
+
timer_task: TimerTask,
|
|
547
|
+
event_name: str,
|
|
548
|
+
timeout: Optional[Union[datetime, timedelta]] = None,
|
|
549
|
+
on_timeout: Optional[Callable[[], None]] = None,
|
|
550
|
+
):
|
|
551
|
+
self._event_task = event_task
|
|
552
|
+
self._timer_task = timer_task
|
|
553
|
+
self._event_name = event_name
|
|
554
|
+
self._timeout = timeout
|
|
555
|
+
self._on_timeout = on_timeout
|
|
556
|
+
super().__init__([event_task, timer_task])
|
|
557
|
+
|
|
558
|
+
def on_child_completed(self, completed_task: Task):
|
|
559
|
+
if self.is_complete:
|
|
560
|
+
return
|
|
561
|
+
if completed_task is self._event_task:
|
|
562
|
+
if completed_task.is_failed:
|
|
563
|
+
self._exception = completed_task.get_exception()
|
|
564
|
+
else:
|
|
565
|
+
self._result = completed_task.get_result()
|
|
566
|
+
self._is_complete = True
|
|
567
|
+
elif completed_task is self._timer_task:
|
|
568
|
+
if self._on_timeout is not None:
|
|
569
|
+
self._on_timeout()
|
|
570
|
+
after = f' after {self._timeout!r}' if self._timeout is not None else ''
|
|
571
|
+
self._exception = TimeoutError(
|
|
572
|
+
f'Timed out{after} waiting for external event {self._event_name!r}'
|
|
573
|
+
)
|
|
574
|
+
self._is_complete = True
|
|
575
|
+
if self._is_complete and self._parent is not None:
|
|
576
|
+
self._parent.on_child_completed(self)
|
|
577
|
+
|
|
578
|
+
|
|
500
579
|
def when_all(tasks: list[Task[T]]) -> WhenAllTask[T]:
|
|
501
580
|
"""Returns a task that completes when all of the provided tasks complete or when one of the tasks fail."""
|
|
502
581
|
return WhenAllTask(tasks)
|
|
@@ -30,7 +30,7 @@ import dapr.ext.workflow._durabletask.internal.shared as shared
|
|
|
30
30
|
import grpc
|
|
31
31
|
from dapr.ext.workflow._durabletask import deterministic, task
|
|
32
32
|
from dapr.ext.workflow._durabletask.internal.grpc_interceptor import DefaultClientInterceptorImpl
|
|
33
|
-
from google.protobuf import empty_pb2
|
|
33
|
+
from google.protobuf import empty_pb2, timestamp_pb2
|
|
34
34
|
|
|
35
35
|
TInput = TypeVar('TInput')
|
|
36
36
|
TOutput = TypeVar('TOutput')
|
|
@@ -1068,6 +1068,11 @@ class _RuntimeOrchestrationContext(
|
|
|
1068
1068
|
task = next(generator) # this starts the generator
|
|
1069
1069
|
# TODO: Check if the task is null?
|
|
1070
1070
|
self._previous_task = task
|
|
1071
|
+
# If the first yielded task is already complete (e.g. wait_for_external_event
|
|
1072
|
+
# with timeout=0 returns an immediately-canceled task), drive the generator
|
|
1073
|
+
# forward now so the orchestrator doesn't get stuck waiting for an event.
|
|
1074
|
+
if self._previous_task is not None and self._previous_task.is_complete:
|
|
1075
|
+
self.resume()
|
|
1071
1076
|
|
|
1072
1077
|
def resume(self):
|
|
1073
1078
|
if self._generator is None:
|
|
@@ -1183,6 +1188,40 @@ class _RuntimeOrchestrationContext(
|
|
|
1183
1188
|
self._sequence_number += 1
|
|
1184
1189
|
return self._sequence_number
|
|
1185
1190
|
|
|
1191
|
+
def _drop_optional_pending_at(self, action_id: int) -> bool:
|
|
1192
|
+
"""Drop the pending optional timer action at ``action_id`` and shift every
|
|
1193
|
+
pending action and pending task with id greater than ``action_id`` down by
|
|
1194
|
+
one, also decrementing the sequence counter.
|
|
1195
|
+
|
|
1196
|
+
Returns True if the action at ``action_id`` was an optional timer and was
|
|
1197
|
+
dropped; False otherwise (caller should fall through to the normal
|
|
1198
|
+
non-determinism error path).
|
|
1199
|
+
|
|
1200
|
+
This preserves sequence-id determinism when replaying a pre-patch history
|
|
1201
|
+
where an indefinite wait_for_external_event did not reserve a sequence
|
|
1202
|
+
number for its optional timer.
|
|
1203
|
+
"""
|
|
1204
|
+
action = self._pending_actions.get(action_id)
|
|
1205
|
+
if action is None or not ph.is_optional_timer_action(action):
|
|
1206
|
+
return False
|
|
1207
|
+
|
|
1208
|
+
del self._pending_actions[action_id]
|
|
1209
|
+
self._pending_tasks.pop(action_id, None)
|
|
1210
|
+
|
|
1211
|
+
# Shift every id > action_id down by one.
|
|
1212
|
+
higher_action_ids = sorted(k for k in self._pending_actions if k > action_id)
|
|
1213
|
+
for old_id in higher_action_ids:
|
|
1214
|
+
a = self._pending_actions.pop(old_id)
|
|
1215
|
+
a.id = old_id - 1
|
|
1216
|
+
self._pending_actions[old_id - 1] = a
|
|
1217
|
+
higher_task_ids = sorted(k for k in self._pending_tasks if k > action_id)
|
|
1218
|
+
for old_id in higher_task_ids:
|
|
1219
|
+
t = self._pending_tasks.pop(old_id)
|
|
1220
|
+
self._pending_tasks[old_id - 1] = t
|
|
1221
|
+
|
|
1222
|
+
self._sequence_number -= 1
|
|
1223
|
+
return True
|
|
1224
|
+
|
|
1186
1225
|
@property
|
|
1187
1226
|
def app_id(self) -> str:
|
|
1188
1227
|
return self._app_id
|
|
@@ -1216,17 +1255,21 @@ class _RuntimeOrchestrationContext(
|
|
|
1216
1255
|
self._encoded_custom_status = custom_status
|
|
1217
1256
|
|
|
1218
1257
|
def create_timer(self, fire_at: Union[datetime, timedelta]) -> task.Task:
|
|
1219
|
-
return self.create_timer_internal(
|
|
1258
|
+
return self.create_timer_internal(
|
|
1259
|
+
fire_at,
|
|
1260
|
+
origin=pb.TimerOriginCreateTimer(),
|
|
1261
|
+
)
|
|
1220
1262
|
|
|
1221
1263
|
def create_timer_internal(
|
|
1222
1264
|
self,
|
|
1223
|
-
fire_at: Union[datetime, timedelta],
|
|
1265
|
+
fire_at: Union[datetime, timedelta, timestamp_pb2.Timestamp],
|
|
1224
1266
|
retryable_task: Optional[task.RetryableTask] = None,
|
|
1225
|
-
|
|
1267
|
+
origin: Optional[ph.TimerOrigin] = None,
|
|
1268
|
+
) -> task.TimerTask:
|
|
1226
1269
|
id = self.next_sequence_number()
|
|
1227
1270
|
if isinstance(fire_at, timedelta):
|
|
1228
1271
|
fire_at = self.current_utc_datetime + fire_at
|
|
1229
|
-
action = ph.new_create_timer_action(id, fire_at)
|
|
1272
|
+
action = ph.new_create_timer_action(id, fire_at, origin=origin)
|
|
1230
1273
|
self._pending_actions[id] = action
|
|
1231
1274
|
|
|
1232
1275
|
timer_task: task.TimerTask = task.TimerTask()
|
|
@@ -1345,7 +1388,12 @@ class _RuntimeOrchestrationContext(
|
|
|
1345
1388
|
)
|
|
1346
1389
|
self._pending_tasks[id] = fn_task
|
|
1347
1390
|
|
|
1348
|
-
def wait_for_external_event(
|
|
1391
|
+
def wait_for_external_event(
|
|
1392
|
+
self,
|
|
1393
|
+
name: str,
|
|
1394
|
+
*,
|
|
1395
|
+
timeout: Optional[Union[datetime, timedelta]] = None,
|
|
1396
|
+
) -> task.Task:
|
|
1349
1397
|
# Check to see if this event has already been received, in which case we
|
|
1350
1398
|
# can return it immediately. Otherwise, record out intent to receive an
|
|
1351
1399
|
# event with the given name so that we can resume the generator when it
|
|
@@ -1365,7 +1413,64 @@ class _RuntimeOrchestrationContext(
|
|
|
1365
1413
|
task_list = []
|
|
1366
1414
|
self._pending_events[event_name] = task_list
|
|
1367
1415
|
task_list.append(external_event_task)
|
|
1368
|
-
|
|
1416
|
+
|
|
1417
|
+
if external_event_task.is_complete:
|
|
1418
|
+
return external_event_task
|
|
1419
|
+
|
|
1420
|
+
# Three timeout shapes:
|
|
1421
|
+
# - timedelta(0): immediately-canceled task (no timer)
|
|
1422
|
+
# - positive: normal TimerOriginExternalEvent timer
|
|
1423
|
+
# - None or negative: indefinite wait — an OPTIONAL timer is scheduled
|
|
1424
|
+
# with a sentinel fireAt. See ph.OPTIONAL_TIMER_FIRE_AT
|
|
1425
|
+
# and the replay-shift logic for how older histories
|
|
1426
|
+
# (which didn't schedule the timer) are tolerated.
|
|
1427
|
+
if isinstance(timeout, timedelta) and timeout == timedelta(0):
|
|
1428
|
+
# Remove the task we just registered in _pending_events so the event
|
|
1429
|
+
# doesn't try to complete it later.
|
|
1430
|
+
pending = self._pending_events.get(event_name)
|
|
1431
|
+
if pending and external_event_task in pending:
|
|
1432
|
+
pending.remove(external_event_task)
|
|
1433
|
+
if not pending:
|
|
1434
|
+
del self._pending_events[event_name]
|
|
1435
|
+
external_event_task.cancel(
|
|
1436
|
+
TimeoutError(
|
|
1437
|
+
f'Wait for external event {name!r} canceled immediately due to zero timeout'
|
|
1438
|
+
)
|
|
1439
|
+
)
|
|
1440
|
+
return external_event_task
|
|
1441
|
+
|
|
1442
|
+
is_indefinite = timeout is None or (
|
|
1443
|
+
isinstance(timeout, timedelta) and timeout < timedelta(0)
|
|
1444
|
+
)
|
|
1445
|
+
fire_at: Union[datetime, timedelta, timestamp_pb2.Timestamp]
|
|
1446
|
+
if is_indefinite:
|
|
1447
|
+
fire_at = ph.OPTIONAL_TIMER_FIRE_AT
|
|
1448
|
+
else:
|
|
1449
|
+
# Narrowed by ``is_indefinite``: timeout is a positive timedelta or a datetime here.
|
|
1450
|
+
assert timeout is not None
|
|
1451
|
+
fire_at = timeout
|
|
1452
|
+
|
|
1453
|
+
timer_task = self.create_timer_internal(
|
|
1454
|
+
fire_at,
|
|
1455
|
+
origin=pb.TimerOriginExternalEvent(name=name),
|
|
1456
|
+
)
|
|
1457
|
+
|
|
1458
|
+
def _unregister_stale_event_task() -> None:
|
|
1459
|
+
"""Remove the event task from _pending_events so late eventRaised
|
|
1460
|
+
messages are buffered instead of consumed by this timed-out waiter."""
|
|
1461
|
+
pending = self._pending_events.get(event_name)
|
|
1462
|
+
if pending and external_event_task in pending:
|
|
1463
|
+
pending.remove(external_event_task)
|
|
1464
|
+
if not pending:
|
|
1465
|
+
del self._pending_events[event_name]
|
|
1466
|
+
|
|
1467
|
+
return task.ExternalEventWithTimeoutTask(
|
|
1468
|
+
external_event_task,
|
|
1469
|
+
timer_task,
|
|
1470
|
+
event_name=name,
|
|
1471
|
+
timeout=None if is_indefinite else timeout,
|
|
1472
|
+
on_timeout=_unregister_stale_event_task,
|
|
1473
|
+
)
|
|
1369
1474
|
|
|
1370
1475
|
def continue_as_new(self, new_input, *, save_events: bool = False) -> None:
|
|
1371
1476
|
if self._is_complete:
|
|
@@ -1543,6 +1648,29 @@ class _OrchestrationExecutor:
|
|
|
1543
1648
|
# This history event confirms that the timer was successfully scheduled.
|
|
1544
1649
|
# Remove the timerCreated event from the pending action list so we don't schedule it again.
|
|
1545
1650
|
timer_id = event.eventId
|
|
1651
|
+
# Asymmetric case: pending is an optional timer but the incoming
|
|
1652
|
+
# TimerCreated is a different (non-optional) timer — e.g., a user
|
|
1653
|
+
# CreateTimer emitted by pre-patch code right after an indefinite
|
|
1654
|
+
# wait_for_external_event. Drop the optional and shift so the
|
|
1655
|
+
# real timer matches at the same id.
|
|
1656
|
+
pending = ctx._pending_actions.get(timer_id)
|
|
1657
|
+
if (
|
|
1658
|
+
pending is not None
|
|
1659
|
+
and ph.is_optional_timer_action(pending)
|
|
1660
|
+
and not ph.is_optional_timer_event(event)
|
|
1661
|
+
):
|
|
1662
|
+
ctx._drop_optional_pending_at(timer_id)
|
|
1663
|
+
pending = ctx._pending_actions.get(timer_id)
|
|
1664
|
+
# Reverse asymmetric: the incoming TimerCreated is an optional timer
|
|
1665
|
+
# from an older code version, but the current code has a different
|
|
1666
|
+
# action at this id (or none at all). This happens when a patch adds
|
|
1667
|
+
# new actions before the wait_for_external_event that originally
|
|
1668
|
+
# produced the timer. Silently drop the stale optional event; the
|
|
1669
|
+
# pending action stays in place to match its own future event.
|
|
1670
|
+
if ph.is_optional_timer_event(event) and (
|
|
1671
|
+
pending is None or not ph.is_optional_timer_action(pending)
|
|
1672
|
+
):
|
|
1673
|
+
return
|
|
1546
1674
|
action = ctx._pending_actions.pop(timer_id, None)
|
|
1547
1675
|
if not action:
|
|
1548
1676
|
raise _get_non_determinism_error(timer_id, task.get_name(ctx.create_timer))
|
|
@@ -1580,6 +1708,13 @@ class _OrchestrationExecutor:
|
|
|
1580
1708
|
# This history event confirms that the activity execution was successfully scheduled.
|
|
1581
1709
|
# Remove the taskScheduled event from the pending action list so we don't schedule it again.
|
|
1582
1710
|
task_id = event.eventId
|
|
1711
|
+
# If the pending action at this id is an optional timer from an
|
|
1712
|
+
# indefinite wait_for_external_event that wasn't present in the
|
|
1713
|
+
# pre-patch history, drop it and shift so this schedule matches.
|
|
1714
|
+
if task_id in ctx._pending_actions and ph.is_optional_timer_action(
|
|
1715
|
+
ctx._pending_actions[task_id]
|
|
1716
|
+
):
|
|
1717
|
+
ctx._drop_optional_pending_at(task_id)
|
|
1583
1718
|
action = ctx._pending_actions.pop(task_id, None)
|
|
1584
1719
|
activity_task = ctx._pending_tasks.get(task_id, None)
|
|
1585
1720
|
if not action:
|
|
@@ -1642,7 +1777,13 @@ class _OrchestrationExecutor:
|
|
|
1642
1777
|
ctx.resume()
|
|
1643
1778
|
else:
|
|
1644
1779
|
activity_task.increment_attempt_count()
|
|
1645
|
-
ctx.create_timer_internal(
|
|
1780
|
+
ctx.create_timer_internal(
|
|
1781
|
+
next_delay,
|
|
1782
|
+
activity_task,
|
|
1783
|
+
origin=pb.TimerOriginActivityRetry(
|
|
1784
|
+
taskExecutionId=activity_task._task_execution_id,
|
|
1785
|
+
),
|
|
1786
|
+
)
|
|
1646
1787
|
elif isinstance(activity_task, task.CompletableTask):
|
|
1647
1788
|
activity_task.fail(
|
|
1648
1789
|
f'{ctx.instance_id}: Activity task #{task_id} failed: {event.taskFailed.failureDetails.errorMessage}',
|
|
@@ -1655,6 +1796,11 @@ class _OrchestrationExecutor:
|
|
|
1655
1796
|
# This history event confirms that the sub-orchestration execution was successfully scheduled.
|
|
1656
1797
|
# Remove the childWorkflowInstanceCreated event from the pending action list so we don't schedule it again.
|
|
1657
1798
|
task_id = event.eventId
|
|
1799
|
+
# If the pending action at this id is an optional timer, drop+shift.
|
|
1800
|
+
if task_id in ctx._pending_actions and ph.is_optional_timer_action(
|
|
1801
|
+
ctx._pending_actions[task_id]
|
|
1802
|
+
):
|
|
1803
|
+
ctx._drop_optional_pending_at(task_id)
|
|
1658
1804
|
action = ctx._pending_actions.pop(task_id, None)
|
|
1659
1805
|
if not action:
|
|
1660
1806
|
raise _get_non_determinism_error(
|
|
@@ -1717,7 +1863,13 @@ class _OrchestrationExecutor:
|
|
|
1717
1863
|
ctx.resume()
|
|
1718
1864
|
else:
|
|
1719
1865
|
sub_orch_task.increment_attempt_count()
|
|
1720
|
-
ctx.create_timer_internal(
|
|
1866
|
+
ctx.create_timer_internal(
|
|
1867
|
+
next_delay,
|
|
1868
|
+
sub_orch_task,
|
|
1869
|
+
origin=pb.TimerOriginChildWorkflowRetry(
|
|
1870
|
+
instanceId=sub_orch_task._instance_id,
|
|
1871
|
+
),
|
|
1872
|
+
)
|
|
1721
1873
|
elif isinstance(sub_orch_task, task.CompletableTask):
|
|
1722
1874
|
sub_orch_task.fail(
|
|
1723
1875
|
f'Sub-orchestration task #{task_id} failed: {failedEvent.failureDetails.errorMessage}',
|
|
@@ -145,9 +145,14 @@ class DaprWorkflowContext(WorkflowContext):
|
|
|
145
145
|
wf, input=input, instance_id=instance_id, retry_policy=retry_policy.obj, app_id=app_id
|
|
146
146
|
)
|
|
147
147
|
|
|
148
|
-
def wait_for_external_event(
|
|
148
|
+
def wait_for_external_event(
|
|
149
|
+
self,
|
|
150
|
+
name: str,
|
|
151
|
+
*,
|
|
152
|
+
timeout: Optional[Union[datetime, timedelta]] = None,
|
|
153
|
+
) -> task.Task:
|
|
149
154
|
self._logger.debug(f'{self.instance_id}: Waiting for external event {name}')
|
|
150
|
-
return self.__obj.wait_for_external_event(name)
|
|
155
|
+
return self.__obj.wait_for_external_event(name, timeout=timeout)
|
|
151
156
|
|
|
152
157
|
def continue_as_new(self, new_input: Any, *, save_events: bool = False) -> None:
|
|
153
158
|
self._logger.debug(f'{self.instance_id}: Continuing as new')
|
|
@@ -162,18 +162,37 @@ class WorkflowContext(ABC):
|
|
|
162
162
|
pass
|
|
163
163
|
|
|
164
164
|
@abstractmethod
|
|
165
|
-
def wait_for_external_event(
|
|
165
|
+
def wait_for_external_event(
|
|
166
|
+
self,
|
|
167
|
+
name: str,
|
|
168
|
+
*,
|
|
169
|
+
timeout: Optional[Union[datetime, timedelta]] = None,
|
|
170
|
+
) -> task.Task:
|
|
166
171
|
"""Wait asynchronously for an event to be raised with the name `name`.
|
|
167
172
|
|
|
168
173
|
Parameters
|
|
169
174
|
----------
|
|
170
175
|
name : str
|
|
171
176
|
The event name of the event that the task is waiting for.
|
|
177
|
+
timeout : datetime | timedelta | None
|
|
178
|
+
Controls how long to wait for the event. Accepts only ``datetime``
|
|
179
|
+
or ``timedelta`` — a plain numeric ``0`` is **not** a valid value
|
|
180
|
+
(use ``timedelta(0)`` explicitly). Three shapes:
|
|
181
|
+
|
|
182
|
+
* ``None`` (default) or a *negative* ``timedelta`` — wait indefinitely.
|
|
183
|
+
An optional sentinel timer is scheduled internally for runtime
|
|
184
|
+
tracking, but ``TimeoutError`` is never raised on its own.
|
|
185
|
+
* ``timedelta(0)`` — do not wait at all. The returned task fails
|
|
186
|
+
immediately with ``TimeoutError``.
|
|
187
|
+
* A future ``datetime`` or a positive ``timedelta`` — wait until
|
|
188
|
+
that deadline / for that duration; ``TimeoutError`` is raised if
|
|
189
|
+
the event has not been received in time.
|
|
172
190
|
|
|
173
191
|
Returns
|
|
174
192
|
-------
|
|
175
193
|
Task[TOutput]
|
|
176
|
-
A Durable Task that completes when the event is received
|
|
194
|
+
A Durable Task that completes when the event is received or fails
|
|
195
|
+
with ``TimeoutError`` if the timeout fires first.
|
|
177
196
|
"""
|
|
178
197
|
pass
|
|
179
198
|
|
|
@@ -46,6 +46,7 @@ dapr/ext/workflow/_durabletask/internal/runtime_state_pb2.py
|
|
|
46
46
|
dapr/ext/workflow/_durabletask/internal/runtime_state_pb2.pyi
|
|
47
47
|
dapr/ext/workflow/_durabletask/internal/runtime_state_pb2_grpc.py
|
|
48
48
|
dapr/ext/workflow/_durabletask/internal/shared.py
|
|
49
|
+
dapr/ext/workflow/_durabletask/internal/timer.py
|
|
49
50
|
dapr/ext/workflow/aio/__init__.py
|
|
50
51
|
dapr/ext/workflow/aio/dapr_workflow_client.py
|
|
51
52
|
dapr/ext/workflow/logger/__init__.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|