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.
Files changed (66) hide show
  1. {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
  2. {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
  3. {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
  4. {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
  5. {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
  6. {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
  7. dapr_ext_workflow_dev-1.17.0.dev103/dapr/ext/workflow/_durabletask/internal/timer.py +142 -0
  8. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/task.py +85 -6
  9. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/worker.py +161 -9
  10. {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
  11. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/workflow_context.py +21 -2
  12. {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
  13. {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
  14. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/LICENSE +0 -0
  15. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/README.rst +0 -0
  16. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/__init__.py +0 -0
  17. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/__init__.py +0 -0
  18. {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
  19. {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
  20. {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
  21. {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
  22. {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
  23. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/client.py +0 -0
  24. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/_durabletask/deterministic.py +0 -0
  25. {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
  26. {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
  27. {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
  28. {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
  29. {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
  30. {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
  31. {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
  32. {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
  33. {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
  34. {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
  35. {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
  36. {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
  37. {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
  38. {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
  39. {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
  40. {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
  41. {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
  42. {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
  43. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/aio/__init__.py +0 -0
  44. {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
  45. {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
  46. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/logger/__init__.py +0 -0
  47. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/logger/logger.py +0 -0
  48. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/logger/options.py +0 -0
  49. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/py.typed +0 -0
  50. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/retry_policy.py +0 -0
  51. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/util.py +0 -0
  52. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/version.py +0 -0
  53. {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
  54. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/workflow_runtime.py +0 -0
  55. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/dapr/ext/workflow/workflow_state.py +0 -0
  56. {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
  57. {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
  58. {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
  59. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/setup.cfg +0 -0
  60. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/setup.py +0 -0
  61. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/tests/test_dapr_workflow_context.py +0 -0
  62. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/tests/test_workflow_activity_context.py +0 -0
  63. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/tests/test_workflow_client.py +0 -0
  64. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/tests/test_workflow_client_aio.py +0 -0
  65. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/tests/test_workflow_runtime.py +0 -0
  66. {dapr_ext_workflow_dev-1.17.0.dev102 → dapr_ext_workflow_dev-1.17.0.dev103}/tests/test_workflow_util.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dapr-ext-workflow-dev
3
- Version: 1.17.0.dev102
3
+ Version: 1.17.0.dev103
4
4
  Summary: The developmental release for Dapr Workflow Authoring.
5
5
  Home-page: https://dapr.io/
6
6
  Author: Dapr Authors
@@ -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\"\xa5\x02\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\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')
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['_TIMERCREATEDEVENT']._serialized_start=1943
65
- _globals['_TIMERCREATEDEVENT']._serialized_end=2236
66
- _globals['_TIMERFIREDEVENT']._serialized_start=2238
67
- _globals['_TIMERFIREDEVENT']._serialized_end=2316
68
- _globals['_WORKFLOWSTARTEDEVENT']._serialized_start=2318
69
- _globals['_WORKFLOWSTARTEDEVENT']._serialized_end=2392
70
- _globals['_WORKFLOWCOMPLETEDEVENT']._serialized_start=2394
71
- _globals['_WORKFLOWCOMPLETEDEVENT']._serialized_end=2418
72
- _globals['_EVENTSENTEVENT']._serialized_start=2420
73
- _globals['_EVENTSENTEVENT']._serialized_end=2515
74
- _globals['_EVENTRAISEDEVENT']._serialized_start=2517
75
- _globals['_EVENTRAISEDEVENT']._serialized_end=2594
76
- _globals['_CONTINUEASNEWEVENT']._serialized_start=2596
77
- _globals['_CONTINUEASNEWEVENT']._serialized_end=2661
78
- _globals['_EXECUTIONSUSPENDEDEVENT']._serialized_start=2663
79
- _globals['_EXECUTIONSUSPENDEDEVENT']._serialized_end=2733
80
- _globals['_EXECUTIONRESUMEDEVENT']._serialized_start=2735
81
- _globals['_EXECUTIONRESUMEDEVENT']._serialized_end=2803
82
- _globals['_EXECUTIONSTALLEDEVENT']._serialized_start=2805
83
- _globals['_EXECUTIONSTALLEDEVENT']._serialized_end=2902
84
- _globals['_HISTORYEVENT']._serialized_start=2905
85
- _globals['_HISTORYEVENT']._serialized_end=4097
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\"\xc9\x01\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\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')
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=740
45
- _globals['_SENDEVENTACTION']._serialized_start=742
46
- _globals['_SENDEVENTACTION']._serialized_end=854
47
- _globals['_COMPLETEWORKFLOWACTION']._serialized_start=857
48
- _globals['_COMPLETEWORKFLOWACTION']._serialized_end=1155
49
- _globals['_TERMINATEWORKFLOWACTION']._serialized_start=1157
50
- _globals['_TERMINATEWORKFLOWACTION']._serialized_end=1265
51
- _globals['_WORKFLOWVERSIONNOTAVAILABLEACTION']._serialized_start=1267
52
- _globals['_WORKFLOWVERSIONNOTAVAILABLEACTION']._serialized_end=1302
53
- _globals['_WORKFLOWACTION']._serialized_start=1305
54
- _globals['_WORKFLOWACTION']._serialized_end=1775
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(self, name: str) -> Task:
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[TaskFailedError]
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) -> TaskFailedError:
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(fire_at)
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
- ) -> task.Task:
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(self, name: str) -> task.Task:
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
- return external_event_task
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(next_delay, activity_task)
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(next_delay, sub_orch_task)
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(self, name: str) -> task.Task:
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(self, name: str) -> task.Task:
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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dapr-ext-workflow-dev
3
- Version: 1.17.0.dev102
3
+ Version: 1.17.0.dev103
4
4
  Summary: The developmental release for Dapr Workflow Authoring.
5
5
  Home-page: https://dapr.io/
6
6
  Author: Dapr Authors
@@ -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