temporalio 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (469) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +4035 -0
  3. data/Cargo.toml +25 -0
  4. data/Gemfile +20 -0
  5. data/LICENSE +16 -15
  6. data/README.md +455 -195
  7. data/Rakefile +387 -0
  8. data/ext/Cargo.toml +25 -0
  9. data/lib/temporalio/activity/complete_async_error.rb +11 -0
  10. data/lib/temporalio/activity/context.rb +82 -77
  11. data/lib/temporalio/activity/definition.rb +77 -0
  12. data/lib/temporalio/activity/info.rb +42 -46
  13. data/lib/temporalio/activity.rb +49 -65
  14. data/lib/temporalio/api/batch/v1/message.rb +31 -0
  15. data/lib/temporalio/api/cloud/cloudservice/v1/request_response.rb +93 -0
  16. data/lib/temporalio/api/cloud/cloudservice/v1/service.rb +25 -0
  17. data/lib/temporalio/api/cloud/cloudservice.rb +3 -0
  18. data/lib/temporalio/api/cloud/identity/v1/message.rb +36 -0
  19. data/lib/temporalio/api/cloud/namespace/v1/message.rb +35 -0
  20. data/lib/temporalio/api/cloud/operation/v1/message.rb +27 -0
  21. data/lib/temporalio/api/cloud/region/v1/message.rb +23 -0
  22. data/lib/temporalio/api/command/v1/message.rb +46 -0
  23. data/lib/temporalio/api/common/v1/grpc_status.rb +23 -0
  24. data/lib/temporalio/api/common/v1/message.rb +41 -0
  25. data/lib/temporalio/api/enums/v1/batch_operation.rb +22 -0
  26. data/lib/temporalio/api/enums/v1/command_type.rb +21 -0
  27. data/lib/temporalio/api/enums/v1/common.rb +26 -0
  28. data/lib/temporalio/api/enums/v1/event_type.rb +21 -0
  29. data/lib/temporalio/api/enums/v1/failed_cause.rb +26 -0
  30. data/lib/temporalio/api/enums/v1/namespace.rb +23 -0
  31. data/lib/temporalio/api/enums/v1/query.rb +22 -0
  32. data/lib/temporalio/api/enums/v1/reset.rb +23 -0
  33. data/lib/temporalio/api/enums/v1/schedule.rb +21 -0
  34. data/lib/temporalio/api/enums/v1/task_queue.rb +25 -0
  35. data/lib/temporalio/api/enums/v1/update.rb +22 -0
  36. data/lib/temporalio/api/enums/v1/workflow.rb +30 -0
  37. data/lib/temporalio/api/errordetails/v1/message.rb +42 -0
  38. data/lib/temporalio/api/export/v1/message.rb +24 -0
  39. data/lib/temporalio/api/failure/v1/message.rb +35 -0
  40. data/lib/temporalio/api/filter/v1/message.rb +27 -0
  41. data/lib/temporalio/api/history/v1/message.rb +90 -0
  42. data/lib/temporalio/api/namespace/v1/message.rb +31 -0
  43. data/lib/temporalio/api/nexus/v1/message.rb +40 -0
  44. data/lib/temporalio/api/operatorservice/v1/request_response.rb +49 -0
  45. data/lib/temporalio/api/operatorservice/v1/service.rb +23 -0
  46. data/lib/temporalio/api/operatorservice.rb +3 -0
  47. data/lib/temporalio/api/protocol/v1/message.rb +23 -0
  48. data/lib/temporalio/api/query/v1/message.rb +27 -0
  49. data/lib/temporalio/api/replication/v1/message.rb +26 -0
  50. data/lib/temporalio/api/schedule/v1/message.rb +42 -0
  51. data/lib/temporalio/api/sdk/v1/enhanced_stack_trace.rb +25 -0
  52. data/lib/temporalio/api/sdk/v1/task_complete_metadata.rb +21 -0
  53. data/lib/temporalio/api/sdk/v1/user_metadata.rb +23 -0
  54. data/lib/temporalio/api/sdk/v1/workflow_metadata.rb +23 -0
  55. data/lib/temporalio/api/taskqueue/v1/message.rb +45 -0
  56. data/lib/temporalio/api/update/v1/message.rb +33 -0
  57. data/lib/temporalio/api/version/v1/message.rb +26 -0
  58. data/lib/temporalio/api/workflow/v1/message.rb +43 -0
  59. data/lib/temporalio/api/workflowservice/v1/request_response.rb +189 -0
  60. data/lib/temporalio/api/workflowservice/v1/service.rb +23 -0
  61. data/lib/temporalio/api/workflowservice.rb +3 -0
  62. data/lib/temporalio/api.rb +13 -0
  63. data/lib/temporalio/cancellation.rb +150 -0
  64. data/lib/temporalio/client/activity_id_reference.rb +32 -0
  65. data/lib/temporalio/client/async_activity_handle.rb +110 -0
  66. data/lib/temporalio/client/connection/cloud_service.rb +648 -0
  67. data/lib/temporalio/client/connection/operator_service.rb +249 -0
  68. data/lib/temporalio/client/connection/service.rb +41 -0
  69. data/lib/temporalio/client/connection/workflow_service.rb +1218 -0
  70. data/lib/temporalio/client/connection.rb +270 -0
  71. data/lib/temporalio/client/interceptor.rb +316 -0
  72. data/lib/temporalio/client/workflow_execution.rb +103 -0
  73. data/lib/temporalio/client/workflow_execution_count.rb +36 -0
  74. data/lib/temporalio/client/workflow_execution_status.rb +18 -0
  75. data/lib/temporalio/client/workflow_handle.rb +380 -177
  76. data/lib/temporalio/client/workflow_query_reject_condition.rb +14 -0
  77. data/lib/temporalio/client/workflow_update_handle.rb +67 -0
  78. data/lib/temporalio/client/workflow_update_wait_stage.rb +17 -0
  79. data/lib/temporalio/client.rb +366 -93
  80. data/lib/temporalio/common_enums.rb +24 -0
  81. data/lib/temporalio/converters/data_converter.rb +102 -0
  82. data/lib/temporalio/converters/failure_converter.rb +200 -0
  83. data/lib/temporalio/converters/payload_codec.rb +26 -0
  84. data/lib/temporalio/converters/payload_converter/binary_null.rb +34 -0
  85. data/lib/temporalio/converters/payload_converter/binary_plain.rb +35 -0
  86. data/lib/temporalio/converters/payload_converter/binary_protobuf.rb +42 -0
  87. data/lib/temporalio/converters/payload_converter/composite.rb +62 -0
  88. data/lib/temporalio/converters/payload_converter/encoding.rb +35 -0
  89. data/lib/temporalio/converters/payload_converter/json_plain.rb +44 -0
  90. data/lib/temporalio/converters/payload_converter/json_protobuf.rb +41 -0
  91. data/lib/temporalio/converters/payload_converter.rb +73 -0
  92. data/lib/temporalio/converters.rb +9 -0
  93. data/lib/temporalio/error/failure.rb +119 -94
  94. data/lib/temporalio/error.rb +147 -0
  95. data/lib/temporalio/internal/bridge/api/activity_result/activity_result.rb +34 -0
  96. data/lib/temporalio/internal/bridge/api/activity_task/activity_task.rb +31 -0
  97. data/lib/temporalio/internal/bridge/api/child_workflow/child_workflow.rb +33 -0
  98. data/lib/temporalio/internal/bridge/api/common/common.rb +26 -0
  99. data/lib/temporalio/internal/bridge/api/core_interface.rb +36 -0
  100. data/lib/temporalio/internal/bridge/api/external_data/external_data.rb +27 -0
  101. data/lib/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rb +52 -0
  102. data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +54 -0
  103. data/lib/temporalio/internal/bridge/api/workflow_completion/workflow_completion.rb +30 -0
  104. data/lib/temporalio/internal/bridge/api.rb +3 -0
  105. data/lib/temporalio/internal/bridge/client.rb +90 -0
  106. data/lib/temporalio/internal/bridge/runtime.rb +53 -0
  107. data/lib/temporalio/internal/bridge/testing.rb +46 -0
  108. data/lib/temporalio/internal/bridge/worker.rb +83 -0
  109. data/lib/temporalio/internal/bridge.rb +36 -0
  110. data/lib/temporalio/internal/client/implementation.rb +525 -0
  111. data/lib/temporalio/internal/proto_utils.rb +54 -0
  112. data/lib/temporalio/internal/worker/activity_worker.rb +345 -0
  113. data/lib/temporalio/internal/worker/multi_runner.rb +169 -0
  114. data/lib/temporalio/internal.rb +7 -0
  115. data/lib/temporalio/retry_policy.rb +39 -80
  116. data/lib/temporalio/runtime.rb +259 -13
  117. data/lib/temporalio/scoped_logger.rb +96 -0
  118. data/lib/temporalio/search_attributes.rb +300 -0
  119. data/lib/temporalio/testing/activity_environment.rb +132 -0
  120. data/lib/temporalio/testing/workflow_environment.rb +113 -88
  121. data/lib/temporalio/testing.rb +4 -169
  122. data/lib/temporalio/version.rb +3 -1
  123. data/lib/temporalio/worker/activity_executor/fiber.rb +49 -0
  124. data/lib/temporalio/worker/activity_executor/thread_pool.rb +254 -0
  125. data/lib/temporalio/worker/activity_executor.rb +55 -0
  126. data/lib/temporalio/worker/interceptor.rb +88 -0
  127. data/lib/temporalio/worker/tuner.rb +151 -0
  128. data/lib/temporalio/worker.rb +385 -163
  129. data/lib/temporalio/workflow_history.rb +22 -0
  130. data/lib/temporalio.rb +2 -7
  131. data/temporalio.gemspec +20 -38
  132. metadata +131 -596
  133. data/bridge/Cargo.lock +0 -2997
  134. data/bridge/Cargo.toml +0 -29
  135. data/bridge/sdk-core/ARCHITECTURE.md +0 -76
  136. data/bridge/sdk-core/Cargo.toml +0 -2
  137. data/bridge/sdk-core/LICENSE.txt +0 -23
  138. data/bridge/sdk-core/README.md +0 -117
  139. data/bridge/sdk-core/arch_docs/diagrams/README.md +0 -10
  140. data/bridge/sdk-core/arch_docs/diagrams/sticky_queues.puml +0 -40
  141. data/bridge/sdk-core/arch_docs/diagrams/workflow_internals.svg +0 -1
  142. data/bridge/sdk-core/arch_docs/sticky_queues.md +0 -51
  143. data/bridge/sdk-core/client/Cargo.toml +0 -40
  144. data/bridge/sdk-core/client/LICENSE.txt +0 -23
  145. data/bridge/sdk-core/client/src/lib.rs +0 -1462
  146. data/bridge/sdk-core/client/src/metrics.rs +0 -174
  147. data/bridge/sdk-core/client/src/raw.rs +0 -932
  148. data/bridge/sdk-core/client/src/retry.rs +0 -763
  149. data/bridge/sdk-core/client/src/workflow_handle/mod.rs +0 -185
  150. data/bridge/sdk-core/core/Cargo.toml +0 -129
  151. data/bridge/sdk-core/core/LICENSE.txt +0 -23
  152. data/bridge/sdk-core/core/benches/workflow_replay.rs +0 -76
  153. data/bridge/sdk-core/core/src/abstractions.rs +0 -355
  154. data/bridge/sdk-core/core/src/core_tests/activity_tasks.rs +0 -1049
  155. data/bridge/sdk-core/core/src/core_tests/child_workflows.rs +0 -221
  156. data/bridge/sdk-core/core/src/core_tests/determinism.rs +0 -270
  157. data/bridge/sdk-core/core/src/core_tests/local_activities.rs +0 -1046
  158. data/bridge/sdk-core/core/src/core_tests/mod.rs +0 -100
  159. data/bridge/sdk-core/core/src/core_tests/queries.rs +0 -893
  160. data/bridge/sdk-core/core/src/core_tests/replay_flag.rs +0 -65
  161. data/bridge/sdk-core/core/src/core_tests/workers.rs +0 -257
  162. data/bridge/sdk-core/core/src/core_tests/workflow_cancels.rs +0 -124
  163. data/bridge/sdk-core/core/src/core_tests/workflow_tasks.rs +0 -2433
  164. data/bridge/sdk-core/core/src/ephemeral_server/mod.rs +0 -609
  165. data/bridge/sdk-core/core/src/internal_flags.rs +0 -136
  166. data/bridge/sdk-core/core/src/lib.rs +0 -289
  167. data/bridge/sdk-core/core/src/pollers/mod.rs +0 -54
  168. data/bridge/sdk-core/core/src/pollers/poll_buffer.rs +0 -297
  169. data/bridge/sdk-core/core/src/protosext/mod.rs +0 -428
  170. data/bridge/sdk-core/core/src/replay/mod.rs +0 -215
  171. data/bridge/sdk-core/core/src/retry_logic.rs +0 -202
  172. data/bridge/sdk-core/core/src/telemetry/log_export.rs +0 -190
  173. data/bridge/sdk-core/core/src/telemetry/metrics.rs +0 -462
  174. data/bridge/sdk-core/core/src/telemetry/mod.rs +0 -423
  175. data/bridge/sdk-core/core/src/telemetry/prometheus_server.rs +0 -83
  176. data/bridge/sdk-core/core/src/test_help/mod.rs +0 -939
  177. data/bridge/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +0 -536
  178. data/bridge/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +0 -89
  179. data/bridge/sdk-core/core/src/worker/activities/local_activities.rs +0 -1278
  180. data/bridge/sdk-core/core/src/worker/activities.rs +0 -557
  181. data/bridge/sdk-core/core/src/worker/client/mocks.rs +0 -107
  182. data/bridge/sdk-core/core/src/worker/client.rs +0 -389
  183. data/bridge/sdk-core/core/src/worker/mod.rs +0 -677
  184. data/bridge/sdk-core/core/src/worker/workflow/bridge.rs +0 -35
  185. data/bridge/sdk-core/core/src/worker/workflow/driven_workflow.rs +0 -99
  186. data/bridge/sdk-core/core/src/worker/workflow/history_update.rs +0 -1111
  187. data/bridge/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +0 -964
  188. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +0 -294
  189. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +0 -168
  190. data/bridge/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +0 -918
  191. data/bridge/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +0 -137
  192. data/bridge/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +0 -158
  193. data/bridge/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +0 -130
  194. data/bridge/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +0 -1525
  195. data/bridge/sdk-core/core/src/worker/workflow/machines/mod.rs +0 -324
  196. data/bridge/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +0 -179
  197. data/bridge/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +0 -659
  198. data/bridge/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +0 -439
  199. data/bridge/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +0 -435
  200. data/bridge/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +0 -175
  201. data/bridge/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +0 -249
  202. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +0 -85
  203. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +0 -1280
  204. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +0 -269
  205. data/bridge/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +0 -213
  206. data/bridge/sdk-core/core/src/worker/workflow/managed_run.rs +0 -1305
  207. data/bridge/sdk-core/core/src/worker/workflow/mod.rs +0 -1276
  208. data/bridge/sdk-core/core/src/worker/workflow/run_cache.rs +0 -128
  209. data/bridge/sdk-core/core/src/worker/workflow/wft_extraction.rs +0 -125
  210. data/bridge/sdk-core/core/src/worker/workflow/wft_poller.rs +0 -85
  211. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +0 -117
  212. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +0 -24
  213. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream.rs +0 -715
  214. data/bridge/sdk-core/core-api/Cargo.toml +0 -33
  215. data/bridge/sdk-core/core-api/LICENSE.txt +0 -23
  216. data/bridge/sdk-core/core-api/src/errors.rs +0 -62
  217. data/bridge/sdk-core/core-api/src/lib.rs +0 -113
  218. data/bridge/sdk-core/core-api/src/telemetry.rs +0 -141
  219. data/bridge/sdk-core/core-api/src/worker.rs +0 -161
  220. data/bridge/sdk-core/etc/deps.svg +0 -162
  221. data/bridge/sdk-core/etc/dynamic-config.yaml +0 -2
  222. data/bridge/sdk-core/etc/otel-collector-config.yaml +0 -36
  223. data/bridge/sdk-core/etc/prometheus.yaml +0 -6
  224. data/bridge/sdk-core/etc/regen-depgraph.sh +0 -5
  225. data/bridge/sdk-core/fsm/Cargo.toml +0 -18
  226. data/bridge/sdk-core/fsm/LICENSE.txt +0 -23
  227. data/bridge/sdk-core/fsm/README.md +0 -3
  228. data/bridge/sdk-core/fsm/rustfsm_procmacro/Cargo.toml +0 -27
  229. data/bridge/sdk-core/fsm/rustfsm_procmacro/LICENSE.txt +0 -23
  230. data/bridge/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +0 -650
  231. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/progress.rs +0 -8
  232. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dupe_transitions_fail.rs +0 -18
  233. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dupe_transitions_fail.stderr +0 -12
  234. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dynamic_dest_pass.rs +0 -41
  235. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/forgot_name_fail.rs +0 -14
  236. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/forgot_name_fail.stderr +0 -11
  237. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/handler_arg_pass.rs +0 -32
  238. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/handler_pass.rs +0 -31
  239. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/medium_complex_pass.rs +0 -46
  240. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.rs +0 -29
  241. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +0 -12
  242. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/simple_pass.rs +0 -32
  243. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/struct_event_variant_fail.rs +0 -18
  244. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/struct_event_variant_fail.stderr +0 -5
  245. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_more_item_event_variant_fail.rs +0 -11
  246. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_more_item_event_variant_fail.stderr +0 -5
  247. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_zero_item_event_variant_fail.rs +0 -11
  248. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_zero_item_event_variant_fail.stderr +0 -5
  249. data/bridge/sdk-core/fsm/rustfsm_trait/Cargo.toml +0 -14
  250. data/bridge/sdk-core/fsm/rustfsm_trait/LICENSE.txt +0 -23
  251. data/bridge/sdk-core/fsm/rustfsm_trait/src/lib.rs +0 -254
  252. data/bridge/sdk-core/fsm/src/lib.rs +0 -2
  253. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-16_history.bin +0 -0
  254. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-23_history.bin +0 -0
  255. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-85_history.bin +0 -0
  256. data/bridge/sdk-core/histories/fail_wf_task.bin +0 -0
  257. data/bridge/sdk-core/histories/timer_workflow_history.bin +0 -0
  258. data/bridge/sdk-core/integ-with-otel.sh +0 -7
  259. data/bridge/sdk-core/protos/api_upstream/README.md +0 -9
  260. data/bridge/sdk-core/protos/api_upstream/api-linter.yaml +0 -40
  261. data/bridge/sdk-core/protos/api_upstream/buf.yaml +0 -9
  262. data/bridge/sdk-core/protos/api_upstream/build/go.mod +0 -7
  263. data/bridge/sdk-core/protos/api_upstream/build/go.sum +0 -5
  264. data/bridge/sdk-core/protos/api_upstream/build/tools.go +0 -29
  265. data/bridge/sdk-core/protos/api_upstream/dependencies/gogoproto/gogo.proto +0 -141
  266. data/bridge/sdk-core/protos/api_upstream/go.mod +0 -6
  267. data/bridge/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +0 -89
  268. data/bridge/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +0 -248
  269. data/bridge/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +0 -123
  270. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +0 -47
  271. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +0 -52
  272. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +0 -56
  273. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +0 -170
  274. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +0 -123
  275. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +0 -51
  276. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/query.proto +0 -50
  277. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +0 -41
  278. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +0 -60
  279. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +0 -59
  280. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +0 -56
  281. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +0 -122
  282. data/bridge/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +0 -108
  283. data/bridge/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +0 -114
  284. data/bridge/sdk-core/protos/api_upstream/temporal/api/filter/v1/message.proto +0 -56
  285. data/bridge/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +0 -787
  286. data/bridge/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +0 -99
  287. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +0 -124
  288. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +0 -80
  289. data/bridge/sdk-core/protos/api_upstream/temporal/api/protocol/v1/message.proto +0 -57
  290. data/bridge/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +0 -61
  291. data/bridge/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +0 -55
  292. data/bridge/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +0 -379
  293. data/bridge/sdk-core/protos/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +0 -63
  294. data/bridge/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +0 -108
  295. data/bridge/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +0 -111
  296. data/bridge/sdk-core/protos/api_upstream/temporal/api/version/v1/message.proto +0 -59
  297. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +0 -146
  298. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +0 -1199
  299. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +0 -415
  300. data/bridge/sdk-core/protos/grpc/health/v1/health.proto +0 -63
  301. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +0 -79
  302. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +0 -80
  303. data/bridge/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +0 -78
  304. data/bridge/sdk-core/protos/local/temporal/sdk/core/common/common.proto +0 -16
  305. data/bridge/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +0 -31
  306. data/bridge/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +0 -31
  307. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +0 -270
  308. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +0 -305
  309. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +0 -35
  310. data/bridge/sdk-core/protos/testsrv_upstream/api-linter.yaml +0 -38
  311. data/bridge/sdk-core/protos/testsrv_upstream/buf.yaml +0 -13
  312. data/bridge/sdk-core/protos/testsrv_upstream/dependencies/gogoproto/gogo.proto +0 -141
  313. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +0 -63
  314. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +0 -90
  315. data/bridge/sdk-core/rustfmt.toml +0 -1
  316. data/bridge/sdk-core/sdk/Cargo.toml +0 -48
  317. data/bridge/sdk-core/sdk/LICENSE.txt +0 -23
  318. data/bridge/sdk-core/sdk/src/activity_context.rs +0 -230
  319. data/bridge/sdk-core/sdk/src/app_data.rs +0 -37
  320. data/bridge/sdk-core/sdk/src/interceptors.rs +0 -50
  321. data/bridge/sdk-core/sdk/src/lib.rs +0 -861
  322. data/bridge/sdk-core/sdk/src/payload_converter.rs +0 -11
  323. data/bridge/sdk-core/sdk/src/workflow_context/options.rs +0 -295
  324. data/bridge/sdk-core/sdk/src/workflow_context.rs +0 -694
  325. data/bridge/sdk-core/sdk/src/workflow_future.rs +0 -500
  326. data/bridge/sdk-core/sdk-core-protos/Cargo.toml +0 -33
  327. data/bridge/sdk-core/sdk-core-protos/LICENSE.txt +0 -23
  328. data/bridge/sdk-core/sdk-core-protos/build.rs +0 -142
  329. data/bridge/sdk-core/sdk-core-protos/src/constants.rs +0 -7
  330. data/bridge/sdk-core/sdk-core-protos/src/history_builder.rs +0 -557
  331. data/bridge/sdk-core/sdk-core-protos/src/history_info.rs +0 -234
  332. data/bridge/sdk-core/sdk-core-protos/src/lib.rs +0 -2088
  333. data/bridge/sdk-core/sdk-core-protos/src/task_token.rs +0 -48
  334. data/bridge/sdk-core/sdk-core-protos/src/utilities.rs +0 -14
  335. data/bridge/sdk-core/test-utils/Cargo.toml +0 -38
  336. data/bridge/sdk-core/test-utils/src/canned_histories.rs +0 -1389
  337. data/bridge/sdk-core/test-utils/src/histfetch.rs +0 -28
  338. data/bridge/sdk-core/test-utils/src/lib.rs +0 -709
  339. data/bridge/sdk-core/test-utils/src/wf_input_saver.rs +0 -50
  340. data/bridge/sdk-core/test-utils/src/workflows.rs +0 -29
  341. data/bridge/sdk-core/tests/fuzzy_workflow.rs +0 -130
  342. data/bridge/sdk-core/tests/heavy_tests.rs +0 -265
  343. data/bridge/sdk-core/tests/integ_tests/client_tests.rs +0 -36
  344. data/bridge/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +0 -150
  345. data/bridge/sdk-core/tests/integ_tests/heartbeat_tests.rs +0 -223
  346. data/bridge/sdk-core/tests/integ_tests/metrics_tests.rs +0 -239
  347. data/bridge/sdk-core/tests/integ_tests/polling_tests.rs +0 -90
  348. data/bridge/sdk-core/tests/integ_tests/queries_tests.rs +0 -314
  349. data/bridge/sdk-core/tests/integ_tests/visibility_tests.rs +0 -151
  350. data/bridge/sdk-core/tests/integ_tests/workflow_tests/activities.rs +0 -902
  351. data/bridge/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +0 -61
  352. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +0 -60
  353. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +0 -51
  354. data/bridge/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +0 -51
  355. data/bridge/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +0 -64
  356. data/bridge/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +0 -47
  357. data/bridge/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +0 -669
  358. data/bridge/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +0 -54
  359. data/bridge/sdk-core/tests/integ_tests/workflow_tests/patches.rs +0 -92
  360. data/bridge/sdk-core/tests/integ_tests/workflow_tests/replay.rs +0 -228
  361. data/bridge/sdk-core/tests/integ_tests/workflow_tests/resets.rs +0 -94
  362. data/bridge/sdk-core/tests/integ_tests/workflow_tests/signals.rs +0 -171
  363. data/bridge/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +0 -85
  364. data/bridge/sdk-core/tests/integ_tests/workflow_tests/timers.rs +0 -120
  365. data/bridge/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +0 -77
  366. data/bridge/sdk-core/tests/integ_tests/workflow_tests.rs +0 -596
  367. data/bridge/sdk-core/tests/main.rs +0 -103
  368. data/bridge/sdk-core/tests/runner.rs +0 -132
  369. data/bridge/sdk-core/tests/wf_input_replay.rs +0 -32
  370. data/bridge/src/connection.rs +0 -202
  371. data/bridge/src/lib.rs +0 -494
  372. data/bridge/src/runtime.rs +0 -54
  373. data/bridge/src/test_server.rs +0 -153
  374. data/bridge/src/worker.rs +0 -197
  375. data/ext/Rakefile +0 -9
  376. data/lib/gen/dependencies/gogoproto/gogo_pb.rb +0 -14
  377. data/lib/gen/temporal/api/batch/v1/message_pb.rb +0 -50
  378. data/lib/gen/temporal/api/command/v1/message_pb.rb +0 -160
  379. data/lib/gen/temporal/api/common/v1/message_pb.rb +0 -73
  380. data/lib/gen/temporal/api/enums/v1/batch_operation_pb.rb +0 -33
  381. data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +0 -37
  382. data/lib/gen/temporal/api/enums/v1/common_pb.rb +0 -42
  383. data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +0 -68
  384. data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +0 -79
  385. data/lib/gen/temporal/api/enums/v1/namespace_pb.rb +0 -37
  386. data/lib/gen/temporal/api/enums/v1/query_pb.rb +0 -31
  387. data/lib/gen/temporal/api/enums/v1/reset_pb.rb +0 -24
  388. data/lib/gen/temporal/api/enums/v1/schedule_pb.rb +0 -28
  389. data/lib/gen/temporal/api/enums/v1/task_queue_pb.rb +0 -30
  390. data/lib/gen/temporal/api/enums/v1/update_pb.rb +0 -25
  391. data/lib/gen/temporal/api/enums/v1/workflow_pb.rb +0 -89
  392. data/lib/gen/temporal/api/errordetails/v1/message_pb.rb +0 -84
  393. data/lib/gen/temporal/api/failure/v1/message_pb.rb +0 -83
  394. data/lib/gen/temporal/api/filter/v1/message_pb.rb +0 -40
  395. data/lib/gen/temporal/api/history/v1/message_pb.rb +0 -498
  396. data/lib/gen/temporal/api/namespace/v1/message_pb.rb +0 -64
  397. data/lib/gen/temporal/api/operatorservice/v1/request_response_pb.rb +0 -88
  398. data/lib/gen/temporal/api/operatorservice/v1/service_pb.rb +0 -20
  399. data/lib/gen/temporal/api/protocol/v1/message_pb.rb +0 -30
  400. data/lib/gen/temporal/api/query/v1/message_pb.rb +0 -38
  401. data/lib/gen/temporal/api/replication/v1/message_pb.rb +0 -37
  402. data/lib/gen/temporal/api/schedule/v1/message_pb.rb +0 -149
  403. data/lib/gen/temporal/api/sdk/v1/task_complete_metadata_pb.rb +0 -23
  404. data/lib/gen/temporal/api/taskqueue/v1/message_pb.rb +0 -73
  405. data/lib/gen/temporal/api/testservice/v1/request_response_pb.rb +0 -49
  406. data/lib/gen/temporal/api/testservice/v1/service_pb.rb +0 -21
  407. data/lib/gen/temporal/api/update/v1/message_pb.rb +0 -72
  408. data/lib/gen/temporal/api/version/v1/message_pb.rb +0 -41
  409. data/lib/gen/temporal/api/workflow/v1/message_pb.rb +0 -111
  410. data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +0 -798
  411. data/lib/gen/temporal/api/workflowservice/v1/service_pb.rb +0 -20
  412. data/lib/gen/temporal/sdk/core/activity_result/activity_result_pb.rb +0 -62
  413. data/lib/gen/temporal/sdk/core/activity_task/activity_task_pb.rb +0 -61
  414. data/lib/gen/temporal/sdk/core/child_workflow/child_workflow_pb.rb +0 -61
  415. data/lib/gen/temporal/sdk/core/common/common_pb.rb +0 -26
  416. data/lib/gen/temporal/sdk/core/core_interface_pb.rb +0 -40
  417. data/lib/gen/temporal/sdk/core/external_data/external_data_pb.rb +0 -31
  418. data/lib/gen/temporal/sdk/core/workflow_activation/workflow_activation_pb.rb +0 -171
  419. data/lib/gen/temporal/sdk/core/workflow_commands/workflow_commands_pb.rb +0 -200
  420. data/lib/gen/temporal/sdk/core/workflow_completion/workflow_completion_pb.rb +0 -41
  421. data/lib/temporalio/bridge/connect_options.rb +0 -15
  422. data/lib/temporalio/bridge/error.rb +0 -8
  423. data/lib/temporalio/bridge/retry_config.rb +0 -24
  424. data/lib/temporalio/bridge/tls_options.rb +0 -19
  425. data/lib/temporalio/bridge.rb +0 -14
  426. data/lib/temporalio/client/implementation.rb +0 -340
  427. data/lib/temporalio/connection/retry_config.rb +0 -44
  428. data/lib/temporalio/connection/service.rb +0 -20
  429. data/lib/temporalio/connection/test_service.rb +0 -92
  430. data/lib/temporalio/connection/tls_options.rb +0 -51
  431. data/lib/temporalio/connection/workflow_service.rb +0 -731
  432. data/lib/temporalio/connection.rb +0 -86
  433. data/lib/temporalio/data_converter.rb +0 -191
  434. data/lib/temporalio/error/workflow_failure.rb +0 -19
  435. data/lib/temporalio/errors.rb +0 -40
  436. data/lib/temporalio/failure_converter/base.rb +0 -26
  437. data/lib/temporalio/failure_converter/basic.rb +0 -319
  438. data/lib/temporalio/failure_converter.rb +0 -7
  439. data/lib/temporalio/interceptor/activity_inbound.rb +0 -22
  440. data/lib/temporalio/interceptor/activity_outbound.rb +0 -24
  441. data/lib/temporalio/interceptor/chain.rb +0 -28
  442. data/lib/temporalio/interceptor/client.rb +0 -127
  443. data/lib/temporalio/interceptor.rb +0 -22
  444. data/lib/temporalio/payload_codec/base.rb +0 -32
  445. data/lib/temporalio/payload_converter/base.rb +0 -24
  446. data/lib/temporalio/payload_converter/bytes.rb +0 -27
  447. data/lib/temporalio/payload_converter/composite.rb +0 -49
  448. data/lib/temporalio/payload_converter/encoding_base.rb +0 -35
  449. data/lib/temporalio/payload_converter/json.rb +0 -26
  450. data/lib/temporalio/payload_converter/nil.rb +0 -26
  451. data/lib/temporalio/payload_converter.rb +0 -14
  452. data/lib/temporalio/retry_state.rb +0 -35
  453. data/lib/temporalio/testing/time_skipping_handle.rb +0 -32
  454. data/lib/temporalio/testing/time_skipping_interceptor.rb +0 -23
  455. data/lib/temporalio/timeout_type.rb +0 -29
  456. data/lib/temporalio/worker/activity_runner.rb +0 -114
  457. data/lib/temporalio/worker/activity_worker.rb +0 -164
  458. data/lib/temporalio/worker/reactor.rb +0 -46
  459. data/lib/temporalio/worker/runner.rb +0 -63
  460. data/lib/temporalio/worker/sync_worker.rb +0 -124
  461. data/lib/temporalio/worker/thread_pool_executor.rb +0 -51
  462. data/lib/temporalio/workflow/async.rb +0 -46
  463. data/lib/temporalio/workflow/execution_info.rb +0 -54
  464. data/lib/temporalio/workflow/execution_status.rb +0 -36
  465. data/lib/temporalio/workflow/future.rb +0 -138
  466. data/lib/temporalio/workflow/id_reuse_policy.rb +0 -36
  467. data/lib/temporalio/workflow/info.rb +0 -76
  468. data/lib/temporalio/workflow/query_reject_condition.rb +0 -33
  469. data/lib/thermite_patch.rb +0 -23
@@ -1,1280 +0,0 @@
1
- mod local_acts;
2
-
3
- use super::{
4
- cancel_external_state_machine::new_external_cancel,
5
- cancel_workflow_state_machine::cancel_workflow,
6
- complete_workflow_state_machine::complete_workflow,
7
- continue_as_new_workflow_state_machine::continue_as_new,
8
- fail_workflow_state_machine::fail_workflow, local_activity_state_machine::new_local_activity,
9
- patch_state_machine::has_change, signal_external_state_machine::new_external_signal,
10
- timer_state_machine::new_timer, upsert_search_attributes_state_machine::upsert_search_attrs,
11
- workflow_machines::local_acts::LocalActivityData,
12
- workflow_task_state_machine::WorkflowTaskMachine, Machines, NewMachineWithCommand,
13
- TemporalStateMachine,
14
- };
15
- use crate::{
16
- internal_flags::InternalFlags,
17
- protosext::{HistoryEventExt, ValidScheduleLA},
18
- telemetry::{metrics::MetricsContext, VecDisplayer},
19
- worker::{
20
- workflow::{
21
- history_update::NextWFT,
22
- machines::{
23
- activity_state_machine::ActivityMachine,
24
- child_workflow_state_machine::ChildWorkflowMachine,
25
- modify_workflow_properties_state_machine::modify_workflow_properties,
26
- HistEventData,
27
- },
28
- CommandID, DrivenWorkflow, HistoryUpdate, InternalFlagsRef, LocalResolution,
29
- OutgoingJob, RunBasics, WFCommand, WFMachinesError, WorkflowFetcher,
30
- WorkflowStartedInfo,
31
- },
32
- ExecutingLAId, LocalActRequest, LocalActivityExecutionResult, LocalActivityResolution,
33
- },
34
- };
35
- use siphasher::sip::SipHasher13;
36
- use slotmap::{SlotMap, SparseSecondaryMap};
37
- use std::{
38
- borrow::{Borrow, BorrowMut},
39
- cell::RefCell,
40
- collections::{HashMap, VecDeque},
41
- convert::TryInto,
42
- hash::{Hash, Hasher},
43
- rc::Rc,
44
- time::{Duration, Instant, SystemTime},
45
- };
46
- use temporal_sdk_core_protos::{
47
- coresdk::{
48
- common::NamespacedWorkflowExecution,
49
- workflow_activation,
50
- workflow_activation::{
51
- workflow_activation_job, NotifyHasPatch, UpdateRandomSeed, WorkflowActivation,
52
- },
53
- workflow_commands::{
54
- request_cancel_external_workflow_execution as cancel_we, ContinueAsNewWorkflowExecution,
55
- },
56
- },
57
- temporal::api::{
58
- command::v1::{command::Attributes as ProtoCmdAttrs, Command as ProtoCommand},
59
- enums::v1::EventType,
60
- history::v1::{history_event, HistoryEvent},
61
- sdk::v1::WorkflowTaskCompletedMetadata,
62
- },
63
- };
64
-
65
- type Result<T, E = WFMachinesError> = std::result::Result<T, E>;
66
-
67
- slotmap::new_key_type! { struct MachineKey; }
68
- /// Handles all the logic for driving a workflow. It orchestrates many state machines that together
69
- /// comprise the logic of an executing workflow. One instance will exist per currently executing
70
- /// (or cached) workflow on the worker.
71
- pub(crate) struct WorkflowMachines {
72
- /// The last recorded history we received from the server for this workflow run. This must be
73
- /// kept because the lang side polls & completes for every workflow task, but we do not need
74
- /// to poll the server that often during replay.
75
- last_history_from_server: HistoryUpdate,
76
- /// EventId of the last handled WorkflowTaskStarted event
77
- current_started_event_id: i64,
78
- /// The event id of the next workflow task started event that the machines need to process.
79
- /// Eventually, this number should reach the started id in the latest history update, but
80
- /// we must incrementally apply the history while communicating with lang.
81
- next_started_event_id: i64,
82
- /// The event id of the most recent event processed. It's possible in some situations (ex legacy
83
- /// queries) to receive a history with no new workflow tasks. If the last history we processed
84
- /// also had no new tasks, we need a way to know not to apply the same events over again.
85
- pub last_processed_event: i64,
86
- /// True if the workflow is replaying from history
87
- pub replaying: bool,
88
- /// Namespace this workflow exists in
89
- pub namespace: String,
90
- /// Workflow identifier
91
- pub workflow_id: String,
92
- /// Workflow type identifier. (Function name, class, etc)
93
- pub workflow_type: String,
94
- /// Identifies the current run
95
- pub run_id: String,
96
- /// The time the workflow execution began, as told by the WEStarted event
97
- workflow_start_time: Option<SystemTime>,
98
- /// The time the workflow execution finished, as determined by when the machines handled
99
- /// a terminal workflow command. If this is `Some`, you know the workflow is ended.
100
- workflow_end_time: Option<SystemTime>,
101
- /// The WFT start time if it has been established
102
- wft_start_time: Option<SystemTime>,
103
- /// The current workflow time if it has been established. This may differ from the WFT start
104
- /// time since local activities may advance the clock
105
- current_wf_time: Option<SystemTime>,
106
- /// The internal flags which have been seen so far during this run's execution and thus are
107
- /// usable during replay.
108
- observed_internal_flags: InternalFlagsRef,
109
-
110
- all_machines: SlotMap<MachineKey, Machines>,
111
- /// If a machine key is in this map, that machine was created internally by core, not as a
112
- /// command from lang.
113
- machine_is_core_created: SparseSecondaryMap<MachineKey, ()>,
114
-
115
- /// A mapping for accessing machines associated to a particular event, where the key is the id
116
- /// of the initiating event for that machine.
117
- machines_by_event_id: HashMap<i64, MachineKey>,
118
-
119
- /// Maps command ids as created by workflow authors to their associated machines.
120
- id_to_machine: HashMap<CommandID, MachineKey>,
121
-
122
- /// Queued commands which have been produced by machines and await processing / being sent to
123
- /// the server.
124
- commands: VecDeque<CommandAndMachine>,
125
- /// Commands generated by the currently processing workflow task, which will eventually be
126
- /// transferred to `commands` (and hence eventually sent to the server)
127
- current_wf_task_commands: VecDeque<CommandAndMachine>,
128
-
129
- /// Information about patch markers we have already seen while replaying history
130
- encountered_change_markers: HashMap<String, ChangeInfo>,
131
-
132
- /// Contains extra local-activity related data
133
- local_activity_data: LocalActivityData,
134
-
135
- /// The workflow that is being driven by this instance of the machines
136
- drive_me: DrivenWorkflow,
137
-
138
- /// Is set to true once we've seen the final event in workflow history, to avoid accidentally
139
- /// re-applying the final workflow task.
140
- pub have_seen_terminal_event: bool,
141
-
142
- /// Metrics context
143
- pub metrics: MetricsContext,
144
- }
145
-
146
- #[derive(Debug, derive_more::Display)]
147
- #[display(fmt = "Cmd&Machine({command})")]
148
- struct CommandAndMachine {
149
- command: MachineAssociatedCommand,
150
- machine: MachineKey,
151
- }
152
-
153
- #[derive(Debug, derive_more::Display)]
154
- enum MachineAssociatedCommand {
155
- Real(Box<ProtoCommand>),
156
- #[display(fmt = "FakeLocalActivityMarker({_0})")]
157
- FakeLocalActivityMarker(u32),
158
- }
159
-
160
- #[derive(Debug, Clone, Copy)]
161
- struct ChangeInfo {
162
- created_command: bool,
163
- }
164
-
165
- /// Returned by [TemporalStateMachine]s when handling events
166
- #[derive(Debug, derive_more::Display)]
167
- #[must_use]
168
- #[allow(clippy::large_enum_variant)]
169
- pub(super) enum MachineResponse {
170
- #[display(fmt = "PushWFJob({_0})")]
171
- PushWFJob(OutgoingJob),
172
-
173
- /// Pushes a new command into the list that will be sent to server once we respond with the
174
- /// workflow task completion
175
- IssueNewCommand(ProtoCommand),
176
- /// The machine requests the creation of another *different* machine. This acts as if lang
177
- /// had replied to the activation with a command, but we use a special set of IDs to avoid
178
- /// collisions.
179
- #[display(fmt = "NewCoreOriginatedCommand({_0:?})")]
180
- NewCoreOriginatedCommand(ProtoCmdAttrs),
181
- #[display(fmt = "IssueFakeLocalActivityMarker({_0})")]
182
- IssueFakeLocalActivityMarker(u32),
183
- #[display(fmt = "TriggerWFTaskStarted")]
184
- TriggerWFTaskStarted {
185
- task_started_event_id: i64,
186
- time: SystemTime,
187
- },
188
- #[display(fmt = "UpdateRunIdOnWorkflowReset({run_id})")]
189
- UpdateRunIdOnWorkflowReset { run_id: String },
190
-
191
- /// Queue a local activity to be processed by the worker
192
- #[display(fmt = "QueueLocalActivity")]
193
- QueueLocalActivity(ValidScheduleLA),
194
- /// Request cancellation of an executing local activity
195
- #[display(fmt = "RequestCancelLocalActivity({_0})")]
196
- RequestCancelLocalActivity(u32),
197
- /// Indicates we are abandoning the indicated LA, so we can remove it from "outstanding" LAs
198
- /// and we will not try to WFT heartbeat because of it.
199
- #[display(fmt = "AbandonLocalActivity({_0:?})")]
200
- AbandonLocalActivity(u32),
201
-
202
- /// Set the workflow time to the provided time
203
- #[display(fmt = "UpdateWFTime({_0:?})")]
204
- UpdateWFTime(Option<SystemTime>),
205
- }
206
-
207
- impl<T> From<T> for MachineResponse
208
- where
209
- T: Into<workflow_activation_job::Variant>,
210
- {
211
- fn from(v: T) -> Self {
212
- Self::PushWFJob(v.into().into())
213
- }
214
- }
215
-
216
- impl WorkflowMachines {
217
- pub(crate) fn new(basics: RunBasics, driven_wf: DrivenWorkflow) -> Self {
218
- let replaying = basics.history.previous_wft_started_id > 0;
219
- let mut observed_internal_flags = InternalFlags::new(basics.capabilities);
220
- // Peek ahead to determine used patches in the first WFT.
221
- if let Some(attrs) = basics.history.peek_next_wft_completed(0) {
222
- observed_internal_flags.add_from_complete(attrs);
223
- };
224
- Self {
225
- last_history_from_server: basics.history,
226
- namespace: basics.namespace,
227
- workflow_id: basics.workflow_id,
228
- workflow_type: basics.workflow_type,
229
- run_id: basics.run_id,
230
- drive_me: driven_wf,
231
- replaying,
232
- metrics: basics.metrics,
233
- // In an ideal world one could say ..Default::default() here and it'd still work.
234
- current_started_event_id: 0,
235
- next_started_event_id: 0,
236
- last_processed_event: 0,
237
- workflow_start_time: None,
238
- workflow_end_time: None,
239
- wft_start_time: None,
240
- current_wf_time: None,
241
- observed_internal_flags: Rc::new(RefCell::new(observed_internal_flags)),
242
- all_machines: Default::default(),
243
- machine_is_core_created: Default::default(),
244
- machines_by_event_id: Default::default(),
245
- id_to_machine: Default::default(),
246
- commands: Default::default(),
247
- current_wf_task_commands: Default::default(),
248
- encountered_change_markers: Default::default(),
249
- local_activity_data: LocalActivityData::default(),
250
- have_seen_terminal_event: false,
251
- }
252
- }
253
-
254
- /// Returns true if workflow has seen a terminal command
255
- pub(crate) const fn workflow_is_finished(&self) -> bool {
256
- self.workflow_end_time.is_some()
257
- }
258
-
259
- /// Returns the total time it took to execute the workflow. Returns `None` if workflow is
260
- /// incomplete, or time went backwards.
261
- pub(crate) fn total_runtime(&self) -> Option<Duration> {
262
- self.workflow_start_time
263
- .zip(self.workflow_end_time)
264
- .and_then(|(st, et)| et.duration_since(st).ok())
265
- }
266
-
267
- pub(crate) fn new_history_from_server(&mut self, update: HistoryUpdate) -> Result<()> {
268
- self.last_history_from_server = update;
269
- self.replaying = self.last_history_from_server.previous_wft_started_id > 0;
270
- self.apply_next_wft_from_history()?;
271
- Ok(())
272
- }
273
-
274
- /// Let this workflow know that something we've been waiting locally on has resolved, like a
275
- /// local activity or side effect
276
- ///
277
- /// Returns true if the resolution did anything. EX: If the activity is already canceled and
278
- /// used the TryCancel or Abandon modes, the resolution is uninteresting.
279
- pub(crate) fn local_resolution(&mut self, resolution: LocalResolution) -> Result<bool> {
280
- let mut result_important = true;
281
- match resolution {
282
- LocalResolution::LocalActivity(LocalActivityResolution {
283
- seq,
284
- result,
285
- runtime,
286
- attempt,
287
- backoff,
288
- original_schedule_time,
289
- }) => {
290
- let act_id = CommandID::LocalActivity(seq);
291
- let mk = self.get_machine_key(act_id)?;
292
- let mach = self.machine_mut(mk);
293
- if let Machines::LocalActivityMachine(ref mut lam) = *mach {
294
- let resps =
295
- lam.try_resolve(result, runtime, attempt, backoff, original_schedule_time)?;
296
- if resps.is_empty() {
297
- result_important = false;
298
- }
299
- self.process_machine_responses(mk, resps)?;
300
- } else {
301
- return Err(WFMachinesError::Nondeterminism(format!(
302
- "Command matching activity with seq num {seq} existed but was not a \
303
- local activity!"
304
- )));
305
- }
306
- self.local_activity_data.done_executing(seq);
307
- }
308
- }
309
- Ok(result_important)
310
- }
311
-
312
- /// Drain all queued local activities that need executing or cancellation
313
- pub(crate) fn drain_queued_local_activities(&mut self) -> Vec<LocalActRequest> {
314
- self.local_activity_data
315
- .take_all_reqs(&self.workflow_type, &self.workflow_id, &self.run_id)
316
- }
317
-
318
- /// Returns the number of local activities we know we need to execute but have not yet finished
319
- pub(crate) fn outstanding_local_activity_count(&self) -> usize {
320
- self.local_activity_data.outstanding_la_count()
321
- }
322
-
323
- /// Returns start info for the workflow if it has started
324
- pub(crate) fn get_started_info(&self) -> Option<&WorkflowStartedInfo> {
325
- self.drive_me.get_started_info()
326
- }
327
-
328
- /// Fetches commands which are ready for processing from the state machines, generally to be
329
- /// sent off to the server. They are not removed from the internal queue, that happens when
330
- /// corresponding history events from the server are being handled.
331
- pub(crate) fn get_commands(&self) -> Vec<ProtoCommand> {
332
- self.commands
333
- .iter()
334
- .filter_map(|c| {
335
- if !self.machine(c.machine).is_final_state() {
336
- match &c.command {
337
- MachineAssociatedCommand::Real(cmd) => Some((**cmd).clone()),
338
- MachineAssociatedCommand::FakeLocalActivityMarker(_) => None,
339
- }
340
- } else {
341
- None
342
- }
343
- })
344
- .collect()
345
- }
346
-
347
- /// Returns the next activation that needs to be performed by the lang sdk. Things like unblock
348
- /// timer, etc. This does *not* cause any advancement of the state machines, it merely drains
349
- /// from the outgoing queue of activation jobs.
350
- ///
351
- /// The job list may be empty, in which case it is expected the caller handles what to do in a
352
- /// "no work" situation. Possibly, it may know about some work the machines don't, like queries.
353
- pub(crate) fn get_wf_activation(&mut self) -> WorkflowActivation {
354
- let jobs = self.drive_me.drain_jobs();
355
- WorkflowActivation {
356
- timestamp: self.current_wf_time.map(Into::into),
357
- is_replaying: self.replaying,
358
- run_id: self.run_id.clone(),
359
- history_length: self.last_processed_event as u32,
360
- jobs,
361
- available_internal_flags: (*self.observed_internal_flags)
362
- .borrow()
363
- .all_lang()
364
- .iter()
365
- .copied()
366
- .collect(),
367
- }
368
- }
369
-
370
- pub(crate) fn has_pending_jobs(&self) -> bool {
371
- !self.drive_me.peek_pending_jobs().is_empty()
372
- }
373
-
374
- pub(crate) fn has_pending_la_resolutions(&self) -> bool {
375
- self.drive_me
376
- .peek_pending_jobs()
377
- .iter()
378
- .any(|v| v.is_la_resolution)
379
- }
380
-
381
- pub(crate) fn get_metadata_for_wft_complete(&self) -> WorkflowTaskCompletedMetadata {
382
- (*self.observed_internal_flags)
383
- .borrow_mut()
384
- .gather_for_wft_complete()
385
- }
386
-
387
- pub(crate) fn add_lang_used_flags(&self, flags: Vec<u32>) {
388
- (*self.observed_internal_flags)
389
- .borrow_mut()
390
- .add_lang_used(flags);
391
- }
392
-
393
- /// Iterate the state machines, which consists of grabbing any pending outgoing commands from
394
- /// the workflow code, handling them, and preparing them to be sent off to the server.
395
- pub(crate) fn iterate_machines(&mut self) -> Result<()> {
396
- let results = self.drive_me.fetch_workflow_iteration_output();
397
- self.handle_driven_results(results)?;
398
- self.prepare_commands()?;
399
- if self.workflow_is_finished() {
400
- if let Some(rt) = self.total_runtime() {
401
- self.metrics.wf_e2e_latency(rt);
402
- }
403
- }
404
- Ok(())
405
- }
406
-
407
- /// Returns true if machines are ready to apply the next WFT sequence, false if events will need
408
- /// to be fetched in order to create a complete update with the entire next WFT sequence.
409
- pub(crate) fn ready_to_apply_next_wft(&self) -> bool {
410
- self.last_history_from_server
411
- .can_take_next_wft_sequence(self.current_started_event_id)
412
- }
413
-
414
- /// Apply the next (unapplied) entire workflow task from history to these machines. Will replay
415
- /// any events that need to be replayed until caught up to the newest WFT.
416
- pub(crate) fn apply_next_wft_from_history(&mut self) -> Result<usize> {
417
- // If we have already seen the terminal event for the entire workflow in a previous WFT,
418
- // then we don't need to do anything here, and in fact we need to avoid re-applying the
419
- // final WFT.
420
- if self.have_seen_terminal_event {
421
- return Ok(0);
422
- }
423
-
424
- // Update observed patches with any that were used in the task
425
- if let Some(next_complete) = self
426
- .last_history_from_server
427
- .peek_next_wft_completed(self.last_processed_event)
428
- {
429
- (*self.observed_internal_flags)
430
- .borrow_mut()
431
- .add_from_complete(next_complete);
432
- }
433
-
434
- let last_handled_wft_started_id = self.current_started_event_id;
435
- let (events, has_final_event) = match self
436
- .last_history_from_server
437
- .take_next_wft_sequence(last_handled_wft_started_id)
438
- {
439
- NextWFT::ReplayOver => (vec![], true),
440
- NextWFT::WFT(mut evts, has_final_event) => {
441
- // Do not re-process events we have already processed
442
- evts.retain(|e| e.event_id > self.last_processed_event);
443
- (evts, has_final_event)
444
- }
445
- NextWFT::NeedFetch => {
446
- return Err(WFMachinesError::Fatal(
447
- "Need to fetch history events to continue applying workflow task, but this \
448
- should be prevented ahead of time! This is a Core SDK bug."
449
- .to_string(),
450
- ));
451
- }
452
- };
453
- let num_events_to_process = events.len();
454
-
455
- // We're caught up on reply if there are no new events to process
456
- if events.is_empty() {
457
- self.replaying = false;
458
- }
459
- let replay_start = Instant::now();
460
-
461
- if let Some(last_event) = events.last() {
462
- if last_event.event_type == EventType::WorkflowTaskStarted as i32 {
463
- self.next_started_event_id = last_event.event_id;
464
- }
465
- }
466
-
467
- let mut saw_completed = false;
468
- let mut history = events.into_iter().peekable();
469
- while let Some(event) = history.next() {
470
- if event.event_id != self.last_processed_event + 1 {
471
- return Err(WFMachinesError::Fatal(format!(
472
- "History is out of order. Last processed event: {}, event id: {}",
473
- self.last_processed_event, event.event_id
474
- )));
475
- }
476
- let next_event = history.peek();
477
- let eid = event.event_id;
478
-
479
- // This definition of replaying here is that we are no longer replaying as soon as we
480
- // see new events that have never been seen or produced by the SDK.
481
- //
482
- // Specifically, replay ends once we have seen the last command-event which was produced
483
- // as a result of the last completed WFT. Thus, replay would be false for things like
484
- // signals which were received and after the last completion, and thus generated the
485
- // current WFT being handled.
486
- if self.replaying && has_final_event && saw_completed && !event.is_command_event() {
487
- // Replay is finished
488
- self.replaying = false;
489
- }
490
- if event.event_type() == EventType::WorkflowTaskCompleted {
491
- saw_completed = true;
492
- }
493
-
494
- self.handle_event(
495
- HistEventData {
496
- event,
497
- replaying: self.replaying,
498
- current_task_is_last_in_history: has_final_event,
499
- },
500
- next_event.is_some() || !has_final_event,
501
- )?;
502
- self.last_processed_event = eid;
503
- }
504
-
505
- // Scan through to the next WFT, searching for any patch / la markers, so that we can
506
- // pre-resolve them.
507
- let mut wake_las = vec![];
508
- for e in self
509
- .last_history_from_server
510
- .peek_next_wft_sequence(last_handled_wft_started_id)
511
- {
512
- if let Some((patch_id, _)) = e.get_patch_marker_details() {
513
- self.encountered_change_markers.insert(
514
- patch_id.clone(),
515
- ChangeInfo {
516
- created_command: false,
517
- },
518
- );
519
- // Found a patch marker
520
- self.drive_me.send_job(
521
- workflow_activation_job::Variant::NotifyHasPatch(NotifyHasPatch { patch_id })
522
- .into(),
523
- );
524
- } else if e.is_local_activity_marker() {
525
- if let Some(la_dat) = e.clone().into_local_activity_marker_details() {
526
- if let Ok(mk) =
527
- self.get_machine_key(CommandID::LocalActivity(la_dat.marker_dat.seq))
528
- {
529
- wake_las.push((mk, la_dat));
530
- } else {
531
- self.local_activity_data.insert_peeked_marker(la_dat);
532
- }
533
- } else {
534
- return Err(WFMachinesError::Fatal(format!(
535
- "Local activity marker was unparsable: {e:?}"
536
- )));
537
- }
538
- }
539
- }
540
- for (mk, la_dat) in wake_las {
541
- let mach = self.machine_mut(mk);
542
- if let Machines::LocalActivityMachine(ref mut lam) = *mach {
543
- if lam.will_accept_resolve_marker() {
544
- let resps = lam.try_resolve_with_dat(la_dat.into())?;
545
- self.process_machine_responses(mk, resps)?;
546
- } else {
547
- self.local_activity_data.insert_peeked_marker(la_dat);
548
- }
549
- }
550
- }
551
-
552
- if !self.replaying {
553
- self.metrics.wf_task_replay_latency(replay_start.elapsed());
554
- }
555
-
556
- Ok(num_events_to_process)
557
- }
558
-
559
- /// Handle a single event from the workflow history. `has_next_event` should be false if `event`
560
- /// is the last event in the history.
561
- ///
562
- /// This function will attempt to apply the event to the workflow state machines. If there is
563
- /// not a matching machine for the event, a nondeterminism error is returned. Otherwise, the
564
- /// event is applied to the machine, which may also return a nondeterminism error if the machine
565
- /// does not match the expected type. A fatal error may be returned if the machine is in an
566
- /// invalid state.
567
- #[instrument(skip(self, event_dat), fields(event=%event_dat))]
568
- fn handle_event(&mut self, event_dat: HistEventData, has_next_event: bool) -> Result<()> {
569
- let event = &event_dat.event;
570
- if event.is_final_wf_execution_event() {
571
- self.have_seen_terminal_event = true;
572
- }
573
- if matches!(
574
- event.event_type(),
575
- EventType::WorkflowExecutionTerminated | EventType::WorkflowExecutionTimedOut
576
- ) {
577
- return if has_next_event {
578
- Err(WFMachinesError::Fatal(
579
- "Machines were fed a history which has an event after workflow execution was \
580
- terminated!"
581
- .to_string(),
582
- ))
583
- } else {
584
- Ok(())
585
- };
586
- }
587
- if event.event_type() == EventType::Unspecified || event.attributes.is_none() {
588
- return if !event.worker_may_ignore {
589
- Err(WFMachinesError::Fatal(format!(
590
- "Event type is unspecified! This history is invalid. Event detail: {event:?}"
591
- )))
592
- } else {
593
- debug!("Event is ignorable");
594
- Ok(())
595
- };
596
- }
597
-
598
- if event.is_command_event() {
599
- self.handle_command_event(event_dat)?;
600
- return Ok(());
601
- }
602
-
603
- if let Some(initial_cmd_id) = event.get_initial_command_event_id() {
604
- // We remove the machine while we it handles events, then return it, to avoid
605
- // borrowing from ourself mutably.
606
- let maybe_machine = self.machines_by_event_id.remove(&initial_cmd_id);
607
- match maybe_machine {
608
- Some(sm) => {
609
- self.submachine_handle_event(sm, event_dat)?;
610
- // Restore machine if not in it's final state
611
- if !self.machine(sm).is_final_state() {
612
- self.machines_by_event_id.insert(initial_cmd_id, sm);
613
- }
614
- }
615
- None => {
616
- return Err(WFMachinesError::Nondeterminism(format!(
617
- "During event handling, this event had an initial command ID but we \
618
- could not find a matching command for it: {event:?}"
619
- )));
620
- }
621
- }
622
- } else {
623
- self.handle_non_stateful_event(event_dat)?;
624
- }
625
-
626
- Ok(())
627
- }
628
-
629
- /// A command event is an event which is generated from a command emitted as a result of
630
- /// performing a workflow task. Each command has a corresponding event. For example
631
- /// ScheduleActivityTaskCommand is recorded to the history as ActivityTaskScheduledEvent.
632
- ///
633
- /// Command events always follow WorkflowTaskCompletedEvent.
634
- ///
635
- /// The handling consists of verifying that the next command in the commands queue is associated
636
- /// with a state machine, which is then notified about the event and the command is removed from
637
- /// the commands queue.
638
- fn handle_command_event(&mut self, event_dat: HistEventData) -> Result<()> {
639
- let event = &event_dat.event;
640
- if event.is_local_activity_marker() {
641
- let deets = event.extract_local_activity_marker_data().ok_or_else(|| {
642
- WFMachinesError::Fatal(format!("Local activity marker was unparsable: {event:?}"))
643
- })?;
644
- let cmdid = CommandID::LocalActivity(deets.seq);
645
- let mkey = self.get_machine_key(cmdid)?;
646
- if let Machines::LocalActivityMachine(lam) = self.machine(mkey) {
647
- if lam.marker_should_get_special_handling()? {
648
- self.submachine_handle_event(mkey, event_dat)?;
649
- return Ok(());
650
- }
651
- } else {
652
- return Err(WFMachinesError::Fatal(format!(
653
- "Encountered local activity marker but the associated machine was of the \
654
- wrong type! {event:?}"
655
- )));
656
- }
657
- }
658
-
659
- let event_id = event.event_id;
660
-
661
- let consumed_cmd = loop {
662
- if let Some(peek_machine) = self.commands.front() {
663
- let mach = self.machine(peek_machine.machine);
664
- match change_marker_handling(event, mach)? {
665
- ChangeMarkerOutcome::SkipEvent => return Ok(()),
666
- ChangeMarkerOutcome::SkipCommand => {
667
- self.commands.pop_front();
668
- continue;
669
- }
670
- ChangeMarkerOutcome::Normal => {}
671
- }
672
- }
673
-
674
- let maybe_command = self.commands.pop_front();
675
- let command = if let Some(c) = maybe_command {
676
- c
677
- } else {
678
- return Err(WFMachinesError::Nondeterminism(format!(
679
- "No command scheduled for event {event}"
680
- )));
681
- };
682
-
683
- let canceled_before_sent = self
684
- .machine(command.machine)
685
- .was_cancelled_before_sent_to_server();
686
-
687
- if !canceled_before_sent {
688
- // Feed the machine the event
689
- self.submachine_handle_event(command.machine, event_dat)?;
690
- break command;
691
- }
692
- };
693
-
694
- if !self.machine(consumed_cmd.machine).is_final_state() {
695
- self.machines_by_event_id
696
- .insert(event_id, consumed_cmd.machine);
697
- }
698
-
699
- Ok(())
700
- }
701
-
702
- fn handle_non_stateful_event(&mut self, event_dat: HistEventData) -> Result<()> {
703
- trace!(
704
- event = %event_dat.event,
705
- "handling non-stateful event"
706
- );
707
- let event_id = event_dat.event.event_id;
708
- match EventType::from_i32(event_dat.event.event_type) {
709
- Some(EventType::WorkflowExecutionStarted) => {
710
- if let Some(history_event::Attributes::WorkflowExecutionStartedEventAttributes(
711
- attrs,
712
- )) = event_dat.event.attributes
713
- {
714
- if let Some(st) = event_dat.event.event_time.clone() {
715
- let as_systime: SystemTime = st.try_into()?;
716
- self.workflow_start_time = Some(as_systime);
717
- // Set the workflow time to be the event time of the first event, so that
718
- // if there is a query issued before first WFT started event, there is some
719
- // workflow time set.
720
- self.set_current_time(as_systime);
721
- }
722
- // Notify the lang sdk that it's time to kick off a workflow
723
- self.drive_me.start(
724
- self.workflow_id.clone(),
725
- str_to_randomness_seed(&attrs.original_execution_run_id),
726
- event_dat.event.event_time.unwrap_or_default(),
727
- attrs,
728
- );
729
- } else {
730
- return Err(WFMachinesError::Fatal(format!(
731
- "WorkflowExecutionStarted event did not have appropriate attributes: {event_dat}"
732
- )));
733
- }
734
- }
735
- Some(EventType::WorkflowTaskScheduled) => {
736
- let wf_task_sm = WorkflowTaskMachine::new(self.next_started_event_id);
737
- let key = self.all_machines.insert(wf_task_sm.into());
738
- self.submachine_handle_event(key, event_dat)?;
739
- self.machines_by_event_id.insert(event_id, key);
740
- }
741
- Some(EventType::WorkflowExecutionSignaled) => {
742
- if let Some(history_event::Attributes::WorkflowExecutionSignaledEventAttributes(
743
- attrs,
744
- )) = event_dat.event.attributes
745
- {
746
- self.drive_me
747
- .send_job(workflow_activation::SignalWorkflow::from(attrs).into());
748
- } else {
749
- // err
750
- }
751
- }
752
- Some(EventType::WorkflowExecutionCancelRequested) => {
753
- if let Some(
754
- history_event::Attributes::WorkflowExecutionCancelRequestedEventAttributes(
755
- attrs,
756
- ),
757
- ) = event_dat.event.attributes
758
- {
759
- self.drive_me
760
- .send_job(workflow_activation::CancelWorkflow::from(attrs).into());
761
- } else {
762
- // err
763
- }
764
- }
765
- _ => {
766
- return Err(WFMachinesError::Fatal(format!(
767
- "The event is not a non-stateful event, but we tried to handle it as one: {event_dat}"
768
- )));
769
- }
770
- }
771
- Ok(())
772
- }
773
-
774
- fn set_current_time(&mut self, time: SystemTime) -> SystemTime {
775
- if self.current_wf_time.map_or(true, |t| t < time) {
776
- self.current_wf_time = Some(time);
777
- }
778
- self.current_wf_time
779
- .expect("We have just ensured this is populated")
780
- }
781
-
782
- /// Wrapper for calling [TemporalStateMachine::handle_event] which appropriately takes action
783
- /// on the returned machine responses
784
- fn submachine_handle_event(&mut self, sm: MachineKey, event: HistEventData) -> Result<()> {
785
- let machine_responses = self.machine_mut(sm).handle_event(event)?;
786
- self.process_machine_responses(sm, machine_responses)?;
787
- Ok(())
788
- }
789
-
790
- /// Transfer commands from `current_wf_task_commands` to `commands`, so they may be sent off
791
- /// to the server. While doing so, [TemporalStateMachine::handle_command] is called on the
792
- /// machine associated with the command.
793
- fn prepare_commands(&mut self) -> Result<()> {
794
- // It's possible we might prepare commands more than once before completing a WFT. (Because
795
- // of local activities, of course). Some commands might have since been cancelled that we
796
- // already prepared. Rip them out of the outgoing command list if so.
797
- self.commands.retain(|c| {
798
- !self
799
- .all_machines
800
- .get(c.machine)
801
- .expect("Machine must exist")
802
- .was_cancelled_before_sent_to_server()
803
- });
804
-
805
- while let Some(c) = self.current_wf_task_commands.pop_front() {
806
- if !self
807
- .machine(c.machine)
808
- .was_cancelled_before_sent_to_server()
809
- {
810
- match &c.command {
811
- MachineAssociatedCommand::Real(cmd) => {
812
- let machine_responses = self
813
- .machine_mut(c.machine)
814
- .handle_command(cmd.command_type())?;
815
- self.process_machine_responses(c.machine, machine_responses)?;
816
- }
817
- MachineAssociatedCommand::FakeLocalActivityMarker(_) => {}
818
- }
819
- self.commands.push_back(c);
820
- }
821
- }
822
- debug!(commands = %self.commands.display(), "prepared commands");
823
- Ok(())
824
- }
825
-
826
- /// After a machine handles either an event or a command, it produces [MachineResponses] which
827
- /// this function uses to drive sending jobs to lang, triggering new workflow tasks, etc.
828
- fn process_machine_responses(
829
- &mut self,
830
- smk: MachineKey,
831
- machine_responses: Vec<MachineResponse>,
832
- ) -> Result<()> {
833
- let sm = self.machine(smk);
834
- if !machine_responses.is_empty() {
835
- trace!(responses = %machine_responses.display(), machine_name = %sm.name(),
836
- "Machine produced responses");
837
- }
838
- self.process_machine_resps_impl(smk, machine_responses)
839
- }
840
-
841
- fn process_machine_resps_impl(
842
- &mut self,
843
- smk: MachineKey,
844
- machine_responses: Vec<MachineResponse>,
845
- ) -> Result<()> {
846
- for response in machine_responses {
847
- match response {
848
- MachineResponse::PushWFJob(a) => {
849
- // We don't need to notify lang about jobs created by core-internal machines
850
- if !self.machine_is_core_created.contains_key(smk) {
851
- self.drive_me.send_job(a);
852
- }
853
- }
854
- MachineResponse::TriggerWFTaskStarted {
855
- task_started_event_id,
856
- time,
857
- } => {
858
- self.task_started(task_started_event_id, time)?;
859
- }
860
- MachineResponse::UpdateRunIdOnWorkflowReset { run_id: new_run_id } => {
861
- self.drive_me.send_job(
862
- workflow_activation_job::Variant::UpdateRandomSeed(UpdateRandomSeed {
863
- randomness_seed: str_to_randomness_seed(&new_run_id),
864
- })
865
- .into(),
866
- );
867
- }
868
- MachineResponse::IssueNewCommand(c) => {
869
- self.current_wf_task_commands.push_back(CommandAndMachine {
870
- command: MachineAssociatedCommand::Real(Box::new(c)),
871
- machine: smk,
872
- })
873
- }
874
- MachineResponse::NewCoreOriginatedCommand(attrs) => match attrs {
875
- ProtoCmdAttrs::RequestCancelExternalWorkflowExecutionCommandAttributes(
876
- attrs,
877
- ) => {
878
- let we = NamespacedWorkflowExecution {
879
- namespace: attrs.namespace,
880
- workflow_id: attrs.workflow_id,
881
- run_id: attrs.run_id,
882
- };
883
- self.add_cmd_to_wf_task(
884
- new_external_cancel(0, we, attrs.child_workflow_only, attrs.reason),
885
- CommandIdKind::CoreInternal,
886
- );
887
- }
888
- c => {
889
- return Err(WFMachinesError::Fatal(format!(
890
- "A machine requested to create a new command of an unsupported type: {c:?}"
891
- )))
892
- }
893
- },
894
- MachineResponse::IssueFakeLocalActivityMarker(seq) => {
895
- self.current_wf_task_commands.push_back(CommandAndMachine {
896
- command: MachineAssociatedCommand::FakeLocalActivityMarker(seq),
897
- machine: smk,
898
- });
899
- }
900
- MachineResponse::QueueLocalActivity(act) => {
901
- self.local_activity_data.enqueue(act);
902
- }
903
- MachineResponse::RequestCancelLocalActivity(seq) => {
904
- // We might already know about the status from a pre-resolution. Apply it if so.
905
- // We need to do this because otherwise we might need to perform additional
906
- // activations during replay that didn't happen during execution, just like
907
- // we sometimes pre-resolve activities when first requested.
908
- if let Some(preres) = self.local_activity_data.take_preresolution(seq) {
909
- if let Machines::LocalActivityMachine(lam) = self.machine_mut(smk) {
910
- let more_responses = lam.try_resolve_with_dat(preres)?;
911
- self.process_machine_responses(smk, more_responses)?;
912
- } else {
913
- panic!("A non local-activity machine returned a request cancel LA response");
914
- }
915
- }
916
- // If it's in the request queue, just rip it out.
917
- else if let Some(removed_act) =
918
- self.local_activity_data.remove_from_queue(seq)
919
- {
920
- // We removed it. Notify the machine that the activity cancelled.
921
- if let Machines::LocalActivityMachine(lam) = self.machine_mut(smk) {
922
- let more_responses = lam.try_resolve(
923
- LocalActivityExecutionResult::empty_cancel(),
924
- Duration::from_secs(0),
925
- removed_act.attempt,
926
- None,
927
- removed_act.original_schedule_time,
928
- )?;
929
- self.process_machine_responses(smk, more_responses)?;
930
- } else {
931
- panic!("A non local-activity machine returned a request cancel LA response");
932
- }
933
- } else {
934
- // Finally, if we know about the LA at all, it's currently running, so
935
- // queue the cancel request to be given to the LA manager.
936
- self.local_activity_data.enqueue_cancel(ExecutingLAId {
937
- run_id: self.run_id.clone(),
938
- seq_num: seq,
939
- });
940
- }
941
- }
942
- MachineResponse::AbandonLocalActivity(seq) => {
943
- self.local_activity_data.done_executing(seq);
944
- }
945
- MachineResponse::UpdateWFTime(t) => {
946
- if let Some(t) = t {
947
- self.set_current_time(t);
948
- }
949
- }
950
- }
951
- }
952
- Ok(())
953
- }
954
-
955
- /// Called when a workflow task started event has triggered. Ensures we are tracking the ID
956
- /// of the current started event as well as workflow time properly.
957
- fn task_started(&mut self, task_started_event_id: i64, time: SystemTime) -> Result<()> {
958
- self.current_started_event_id = task_started_event_id;
959
- self.wft_start_time = Some(time);
960
- self.set_current_time(time);
961
-
962
- // Notify local activity machines that we started a non-replay WFT, which will allow any
963
- // which were waiting for a marker to instead decide to execute the LA since it clearly
964
- // will not be resolved via marker.
965
- if !self.replaying {
966
- let mut resps = vec![];
967
- for (k, mach) in self.all_machines.iter_mut() {
968
- if let Machines::LocalActivityMachine(lam) = mach {
969
- resps.push((k, lam.encountered_non_replay_wft()?));
970
- }
971
- }
972
- for (mkey, resp_set) in resps {
973
- self.process_machine_responses(mkey, resp_set)?;
974
- }
975
- }
976
- Ok(())
977
- }
978
-
979
- /// Handles results of the workflow activation, delegating work to the appropriate state
980
- /// machine. Returns a list of workflow jobs that should be queued in the pending activation for
981
- /// the next poll. This list will be populated only if state machine produced lang activations
982
- /// as part of command processing. For example some types of activity cancellation need to
983
- /// immediately unblock lang side without having it to poll for an actual workflow task from the
984
- /// server.
985
- fn handle_driven_results(&mut self, results: Vec<WFCommand>) -> Result<()> {
986
- for cmd in results {
987
- match cmd {
988
- WFCommand::AddTimer(attrs) => {
989
- let seq = attrs.seq;
990
- self.add_cmd_to_wf_task(new_timer(attrs), CommandID::Timer(seq).into());
991
- }
992
- WFCommand::UpsertSearchAttributes(attrs) => {
993
- self.add_cmd_to_wf_task(
994
- upsert_search_attrs(attrs),
995
- CommandIdKind::NeverResolves,
996
- );
997
- }
998
- WFCommand::CancelTimer(attrs) => {
999
- self.process_cancellation(CommandID::Timer(attrs.seq))?;
1000
- }
1001
- WFCommand::AddActivity(attrs) => {
1002
- let seq = attrs.seq;
1003
- self.add_cmd_to_wf_task(
1004
- ActivityMachine::new_scheduled(attrs, self.observed_internal_flags.clone()),
1005
- CommandID::Activity(seq).into(),
1006
- );
1007
- }
1008
- WFCommand::AddLocalActivity(attrs) => {
1009
- let seq = attrs.seq;
1010
- let attrs: ValidScheduleLA = ValidScheduleLA::from_schedule_la(
1011
- attrs,
1012
- self.get_started_info()
1013
- .as_ref()
1014
- .and_then(|x| x.workflow_execution_timeout),
1015
- )
1016
- .map_err(|e| {
1017
- WFMachinesError::Fatal(format!(
1018
- "Invalid schedule local activity request (seq {seq}): {e}"
1019
- ))
1020
- })?;
1021
- let (la, mach_resp) = new_local_activity(
1022
- attrs,
1023
- self.replaying,
1024
- self.local_activity_data.take_preresolution(seq),
1025
- self.current_wf_time,
1026
- self.observed_internal_flags.clone(),
1027
- )?;
1028
- let machkey = self.all_machines.insert(la.into());
1029
- self.id_to_machine
1030
- .insert(CommandID::LocalActivity(seq), machkey);
1031
- self.process_machine_responses(machkey, mach_resp)?;
1032
- }
1033
- WFCommand::RequestCancelActivity(attrs) => {
1034
- self.process_cancellation(CommandID::Activity(attrs.seq))?;
1035
- }
1036
- WFCommand::RequestCancelLocalActivity(attrs) => {
1037
- self.process_cancellation(CommandID::LocalActivity(attrs.seq))?;
1038
- }
1039
- WFCommand::CompleteWorkflow(attrs) => {
1040
- self.metrics.wf_completed();
1041
- self.add_terminal_command(complete_workflow(attrs));
1042
- }
1043
- WFCommand::FailWorkflow(attrs) => {
1044
- self.metrics.wf_failed();
1045
- self.add_terminal_command(fail_workflow(attrs));
1046
- }
1047
- WFCommand::ContinueAsNew(attrs) => {
1048
- self.metrics.wf_continued_as_new();
1049
- let attrs = self.augment_continue_as_new_with_current_values(attrs);
1050
- self.add_terminal_command(continue_as_new(attrs));
1051
- }
1052
- WFCommand::CancelWorkflow(attrs) => {
1053
- self.metrics.wf_canceled();
1054
- self.add_terminal_command(cancel_workflow(attrs));
1055
- }
1056
- WFCommand::SetPatchMarker(attrs) => {
1057
- // Do not create commands for change IDs that we have already created commands
1058
- // for.
1059
- if !matches!(self.encountered_change_markers.get(&attrs.patch_id),
1060
- Some(ChangeInfo {created_command}) if *created_command)
1061
- {
1062
- self.add_cmd_to_wf_task(
1063
- has_change(attrs.patch_id.clone(), self.replaying, attrs.deprecated),
1064
- CommandIdKind::NeverResolves,
1065
- );
1066
-
1067
- if let Some(ci) = self.encountered_change_markers.get_mut(&attrs.patch_id) {
1068
- ci.created_command = true;
1069
- } else {
1070
- self.encountered_change_markers.insert(
1071
- attrs.patch_id,
1072
- ChangeInfo {
1073
- created_command: true,
1074
- },
1075
- );
1076
- }
1077
- }
1078
- }
1079
- WFCommand::AddChildWorkflow(attrs) => {
1080
- let seq = attrs.seq;
1081
- self.add_cmd_to_wf_task(
1082
- ChildWorkflowMachine::new_scheduled(
1083
- attrs,
1084
- self.observed_internal_flags.clone(),
1085
- ),
1086
- CommandID::ChildWorkflowStart(seq).into(),
1087
- );
1088
- }
1089
- WFCommand::CancelChild(attrs) => self.process_cancellation(
1090
- CommandID::ChildWorkflowStart(attrs.child_workflow_seq),
1091
- )?,
1092
- WFCommand::RequestCancelExternalWorkflow(attrs) => {
1093
- let (we, only_child) = match attrs.target {
1094
- None => {
1095
- return Err(WFMachinesError::Fatal(
1096
- "Cancel external workflow command had empty target field"
1097
- .to_string(),
1098
- ))
1099
- }
1100
- Some(cancel_we::Target::ChildWorkflowId(wfid)) => (
1101
- NamespacedWorkflowExecution {
1102
- namespace: self.namespace.clone(),
1103
- workflow_id: wfid,
1104
- run_id: "".to_string(),
1105
- },
1106
- true,
1107
- ),
1108
- Some(cancel_we::Target::WorkflowExecution(we)) => (we, false),
1109
- };
1110
- self.add_cmd_to_wf_task(
1111
- new_external_cancel(
1112
- attrs.seq,
1113
- we,
1114
- only_child,
1115
- format!("Cancel requested by workflow with run id {}", self.run_id),
1116
- ),
1117
- CommandID::CancelExternal(attrs.seq).into(),
1118
- );
1119
- }
1120
- WFCommand::SignalExternalWorkflow(attrs) => {
1121
- let seq = attrs.seq;
1122
- self.add_cmd_to_wf_task(
1123
- new_external_signal(attrs, &self.namespace)?,
1124
- CommandID::SignalExternal(seq).into(),
1125
- );
1126
- }
1127
- WFCommand::CancelSignalWorkflow(attrs) => {
1128
- self.process_cancellation(CommandID::SignalExternal(attrs.seq))?;
1129
- }
1130
- WFCommand::QueryResponse(_) => {
1131
- // Nothing to do here, queries are handled above the machine level
1132
- unimplemented!("Query responses should not make it down into the machines")
1133
- }
1134
- WFCommand::ModifyWorkflowProperties(attrs) => {
1135
- self.add_cmd_to_wf_task(
1136
- modify_workflow_properties(attrs),
1137
- CommandIdKind::NeverResolves,
1138
- );
1139
- }
1140
- WFCommand::NoCommandsFromLang => (),
1141
- }
1142
- }
1143
- Ok(())
1144
- }
1145
-
1146
- /// Given a command id to attempt to cancel, try to cancel it and return any jobs that should
1147
- /// be included in the activation
1148
- fn process_cancellation(&mut self, id: CommandID) -> Result<()> {
1149
- let m_key = self.get_machine_key(id)?;
1150
- let mach = self.machine_mut(m_key);
1151
- let machine_resps = mach.cancel()?;
1152
- debug!(machine_responses = %machine_resps.display(), cmd_id = ?id,
1153
- "Cancel request responses");
1154
- self.process_machine_resps_impl(m_key, machine_resps)
1155
- }
1156
-
1157
- fn get_machine_key(&self, id: CommandID) -> Result<MachineKey> {
1158
- Ok(*self.id_to_machine.get(&id).ok_or_else(|| {
1159
- WFMachinesError::Fatal(format!("Missing associated machine for {id:?}"))
1160
- })?)
1161
- }
1162
-
1163
- fn add_terminal_command(&mut self, machine: NewMachineWithCommand) {
1164
- let cwfm = self.add_new_command_machine(machine);
1165
- self.workflow_end_time = Some(SystemTime::now());
1166
- self.current_wf_task_commands.push_back(cwfm);
1167
- }
1168
-
1169
- /// Add a new command/machines for that command to the current workflow task
1170
- fn add_cmd_to_wf_task(&mut self, machine: NewMachineWithCommand, id: CommandIdKind) {
1171
- let mach = self.add_new_command_machine(machine);
1172
- if let CommandIdKind::LangIssued(id) = id {
1173
- self.id_to_machine.insert(id, mach.machine);
1174
- }
1175
- if matches!(id, CommandIdKind::CoreInternal) {
1176
- self.machine_is_core_created.insert(mach.machine, ());
1177
- }
1178
- self.current_wf_task_commands.push_back(mach);
1179
- }
1180
-
1181
- fn add_new_command_machine(&mut self, machine: NewMachineWithCommand) -> CommandAndMachine {
1182
- let k = self.all_machines.insert(machine.machine);
1183
- CommandAndMachine {
1184
- command: MachineAssociatedCommand::Real(Box::new(machine.command)),
1185
- machine: k,
1186
- }
1187
- }
1188
-
1189
- fn machine(&self, m: MachineKey) -> &Machines {
1190
- self.all_machines
1191
- .get(m)
1192
- .expect("Machine must exist")
1193
- .borrow()
1194
- }
1195
-
1196
- fn machine_mut(&mut self, m: MachineKey) -> &mut Machines {
1197
- self.all_machines
1198
- .get_mut(m)
1199
- .expect("Machine must exist")
1200
- .borrow_mut()
1201
- }
1202
-
1203
- fn augment_continue_as_new_with_current_values(
1204
- &self,
1205
- mut attrs: ContinueAsNewWorkflowExecution,
1206
- ) -> ContinueAsNewWorkflowExecution {
1207
- if let Some(started_info) = self.drive_me.get_started_info() {
1208
- if attrs.memo.is_empty() {
1209
- attrs.memo = started_info
1210
- .memo
1211
- .clone()
1212
- .map(Into::into)
1213
- .unwrap_or_default();
1214
- }
1215
- if attrs.search_attributes.is_empty() {
1216
- attrs.search_attributes = started_info
1217
- .search_attrs
1218
- .clone()
1219
- .map(Into::into)
1220
- .unwrap_or_default();
1221
- }
1222
- if attrs.retry_policy.is_none() {
1223
- attrs.retry_policy = started_info.retry_policy.clone();
1224
- }
1225
- }
1226
- attrs
1227
- }
1228
- }
1229
-
1230
- fn str_to_randomness_seed(run_id: &str) -> u64 {
1231
- // This was originally `DefaultHasher` but that is potentially unstable across Rust releases.
1232
- // This must forever be `SipHasher13` now or we risk breaking history compat.
1233
- let mut s = SipHasher13::new();
1234
- run_id.hash(&mut s);
1235
- s.finish()
1236
- }
1237
-
1238
- enum ChangeMarkerOutcome {
1239
- SkipEvent,
1240
- SkipCommand,
1241
- Normal,
1242
- }
1243
-
1244
- /// Special handling for patch markers, when handling command events as in
1245
- /// [WorkflowMachines::handle_command_event]
1246
- fn change_marker_handling(event: &HistoryEvent, mach: &Machines) -> Result<ChangeMarkerOutcome> {
1247
- if !mach.matches_event(event) {
1248
- // Version markers can be skipped in the event they are deprecated
1249
- if let Some((patch_name, deprecated)) = event.get_patch_marker_details() {
1250
- // Is deprecated. We can simply ignore this event, as deprecated change
1251
- // markers are allowed without matching changed calls.
1252
- if deprecated {
1253
- debug!("Deprecated patch marker tried against wrong machine, skipping.");
1254
- return Ok(ChangeMarkerOutcome::SkipEvent);
1255
- }
1256
- return Err(WFMachinesError::Nondeterminism(format!(
1257
- "Non-deprecated patch marker encountered for change {patch_name}, \
1258
- but there is no corresponding change command!"
1259
- )));
1260
- }
1261
- // Patch machines themselves may also not *have* matching markers, where non-deprecated
1262
- // calls take the old path, and deprecated calls assume history is produced by a new-code
1263
- // worker.
1264
- if matches!(mach, Machines::PatchMachine(_)) {
1265
- debug!("Skipping non-matching event against patch machine");
1266
- return Ok(ChangeMarkerOutcome::SkipCommand);
1267
- }
1268
- }
1269
- Ok(ChangeMarkerOutcome::Normal)
1270
- }
1271
-
1272
- #[derive(derive_more::From)]
1273
- enum CommandIdKind {
1274
- /// A normal command, requested by lang
1275
- LangIssued(CommandID),
1276
- /// A command created internally
1277
- CoreInternal,
1278
- /// A command which is fire-and-forget (ex: Upsert search attribs)
1279
- NeverResolves,
1280
- }