temporalio 0.0.0 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (327) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +301 -0
  3. data/bridge/Cargo.lock +2888 -0
  4. data/bridge/Cargo.toml +27 -0
  5. data/bridge/sdk-core/ARCHITECTURE.md +76 -0
  6. data/bridge/sdk-core/Cargo.lock +2606 -0
  7. data/bridge/sdk-core/Cargo.toml +2 -0
  8. data/bridge/sdk-core/LICENSE.txt +23 -0
  9. data/bridge/sdk-core/README.md +104 -0
  10. data/bridge/sdk-core/arch_docs/diagrams/README.md +10 -0
  11. data/bridge/sdk-core/arch_docs/diagrams/sticky_queues.puml +40 -0
  12. data/bridge/sdk-core/arch_docs/diagrams/workflow_internals.svg +1 -0
  13. data/bridge/sdk-core/arch_docs/sticky_queues.md +51 -0
  14. data/bridge/sdk-core/client/Cargo.toml +40 -0
  15. data/bridge/sdk-core/client/LICENSE.txt +23 -0
  16. data/bridge/sdk-core/client/src/lib.rs +1286 -0
  17. data/bridge/sdk-core/client/src/metrics.rs +165 -0
  18. data/bridge/sdk-core/client/src/raw.rs +932 -0
  19. data/bridge/sdk-core/client/src/retry.rs +751 -0
  20. data/bridge/sdk-core/client/src/workflow_handle/mod.rs +185 -0
  21. data/bridge/sdk-core/core/Cargo.toml +116 -0
  22. data/bridge/sdk-core/core/LICENSE.txt +23 -0
  23. data/bridge/sdk-core/core/benches/workflow_replay.rs +76 -0
  24. data/bridge/sdk-core/core/src/abstractions.rs +166 -0
  25. data/bridge/sdk-core/core/src/core_tests/activity_tasks.rs +1014 -0
  26. data/bridge/sdk-core/core/src/core_tests/child_workflows.rs +221 -0
  27. data/bridge/sdk-core/core/src/core_tests/determinism.rs +107 -0
  28. data/bridge/sdk-core/core/src/core_tests/local_activities.rs +925 -0
  29. data/bridge/sdk-core/core/src/core_tests/mod.rs +100 -0
  30. data/bridge/sdk-core/core/src/core_tests/queries.rs +894 -0
  31. data/bridge/sdk-core/core/src/core_tests/replay_flag.rs +65 -0
  32. data/bridge/sdk-core/core/src/core_tests/workers.rs +259 -0
  33. data/bridge/sdk-core/core/src/core_tests/workflow_cancels.rs +124 -0
  34. data/bridge/sdk-core/core/src/core_tests/workflow_tasks.rs +2090 -0
  35. data/bridge/sdk-core/core/src/ephemeral_server/mod.rs +515 -0
  36. data/bridge/sdk-core/core/src/lib.rs +282 -0
  37. data/bridge/sdk-core/core/src/pollers/mod.rs +54 -0
  38. data/bridge/sdk-core/core/src/pollers/poll_buffer.rs +297 -0
  39. data/bridge/sdk-core/core/src/protosext/mod.rs +428 -0
  40. data/bridge/sdk-core/core/src/replay/mod.rs +215 -0
  41. data/bridge/sdk-core/core/src/retry_logic.rs +202 -0
  42. data/bridge/sdk-core/core/src/telemetry/log_export.rs +190 -0
  43. data/bridge/sdk-core/core/src/telemetry/metrics.rs +428 -0
  44. data/bridge/sdk-core/core/src/telemetry/mod.rs +407 -0
  45. data/bridge/sdk-core/core/src/telemetry/prometheus_server.rs +78 -0
  46. data/bridge/sdk-core/core/src/test_help/mod.rs +889 -0
  47. data/bridge/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +580 -0
  48. data/bridge/sdk-core/core/src/worker/activities/local_activities.rs +1048 -0
  49. data/bridge/sdk-core/core/src/worker/activities.rs +481 -0
  50. data/bridge/sdk-core/core/src/worker/client/mocks.rs +87 -0
  51. data/bridge/sdk-core/core/src/worker/client.rs +373 -0
  52. data/bridge/sdk-core/core/src/worker/mod.rs +570 -0
  53. data/bridge/sdk-core/core/src/worker/workflow/bridge.rs +37 -0
  54. data/bridge/sdk-core/core/src/worker/workflow/driven_workflow.rs +101 -0
  55. data/bridge/sdk-core/core/src/worker/workflow/history_update.rs +532 -0
  56. data/bridge/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +907 -0
  57. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +294 -0
  58. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +167 -0
  59. data/bridge/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +858 -0
  60. data/bridge/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +136 -0
  61. data/bridge/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +157 -0
  62. data/bridge/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +129 -0
  63. data/bridge/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +1450 -0
  64. data/bridge/sdk-core/core/src/worker/workflow/machines/mod.rs +316 -0
  65. data/bridge/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +178 -0
  66. data/bridge/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +708 -0
  67. data/bridge/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +439 -0
  68. data/bridge/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +435 -0
  69. data/bridge/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +175 -0
  70. data/bridge/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +242 -0
  71. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +96 -0
  72. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +1200 -0
  73. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +272 -0
  74. data/bridge/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +198 -0
  75. data/bridge/sdk-core/core/src/worker/workflow/managed_run.rs +655 -0
  76. data/bridge/sdk-core/core/src/worker/workflow/mod.rs +1200 -0
  77. data/bridge/sdk-core/core/src/worker/workflow/run_cache.rs +145 -0
  78. data/bridge/sdk-core/core/src/worker/workflow/wft_poller.rs +88 -0
  79. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream.rs +985 -0
  80. data/bridge/sdk-core/core-api/Cargo.toml +32 -0
  81. data/bridge/sdk-core/core-api/LICENSE.txt +23 -0
  82. data/bridge/sdk-core/core-api/src/errors.rs +95 -0
  83. data/bridge/sdk-core/core-api/src/lib.rs +109 -0
  84. data/bridge/sdk-core/core-api/src/telemetry.rs +147 -0
  85. data/bridge/sdk-core/core-api/src/worker.rs +148 -0
  86. data/bridge/sdk-core/etc/deps.svg +162 -0
  87. data/bridge/sdk-core/etc/dynamic-config.yaml +2 -0
  88. data/bridge/sdk-core/etc/otel-collector-config.yaml +36 -0
  89. data/bridge/sdk-core/etc/prometheus.yaml +6 -0
  90. data/bridge/sdk-core/etc/regen-depgraph.sh +5 -0
  91. data/bridge/sdk-core/fsm/Cargo.toml +18 -0
  92. data/bridge/sdk-core/fsm/LICENSE.txt +23 -0
  93. data/bridge/sdk-core/fsm/README.md +3 -0
  94. data/bridge/sdk-core/fsm/rustfsm_procmacro/Cargo.toml +27 -0
  95. data/bridge/sdk-core/fsm/rustfsm_procmacro/LICENSE.txt +23 -0
  96. data/bridge/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +647 -0
  97. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/progress.rs +8 -0
  98. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dupe_transitions_fail.rs +18 -0
  99. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dupe_transitions_fail.stderr +12 -0
  100. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dynamic_dest_pass.rs +41 -0
  101. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/forgot_name_fail.rs +14 -0
  102. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/forgot_name_fail.stderr +11 -0
  103. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/handler_arg_pass.rs +32 -0
  104. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/handler_pass.rs +31 -0
  105. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/medium_complex_pass.rs +46 -0
  106. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.rs +29 -0
  107. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +12 -0
  108. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/simple_pass.rs +32 -0
  109. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/struct_event_variant_fail.rs +18 -0
  110. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/struct_event_variant_fail.stderr +5 -0
  111. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_more_item_event_variant_fail.rs +11 -0
  112. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_more_item_event_variant_fail.stderr +5 -0
  113. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_zero_item_event_variant_fail.rs +11 -0
  114. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_zero_item_event_variant_fail.stderr +5 -0
  115. data/bridge/sdk-core/fsm/rustfsm_trait/Cargo.toml +14 -0
  116. data/bridge/sdk-core/fsm/rustfsm_trait/LICENSE.txt +23 -0
  117. data/bridge/sdk-core/fsm/rustfsm_trait/src/lib.rs +249 -0
  118. data/bridge/sdk-core/fsm/src/lib.rs +2 -0
  119. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-23_history.bin +0 -0
  120. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-85_history.bin +0 -0
  121. data/bridge/sdk-core/histories/fail_wf_task.bin +0 -0
  122. data/bridge/sdk-core/histories/timer_workflow_history.bin +0 -0
  123. data/bridge/sdk-core/integ-with-otel.sh +7 -0
  124. data/bridge/sdk-core/protos/api_upstream/README.md +9 -0
  125. data/bridge/sdk-core/protos/api_upstream/api-linter.yaml +40 -0
  126. data/bridge/sdk-core/protos/api_upstream/buf.yaml +9 -0
  127. data/bridge/sdk-core/protos/api_upstream/build/go.mod +7 -0
  128. data/bridge/sdk-core/protos/api_upstream/build/go.sum +5 -0
  129. data/bridge/sdk-core/protos/api_upstream/build/tools.go +29 -0
  130. data/bridge/sdk-core/protos/api_upstream/dependencies/gogoproto/gogo.proto +141 -0
  131. data/bridge/sdk-core/protos/api_upstream/go.mod +6 -0
  132. data/bridge/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +89 -0
  133. data/bridge/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +260 -0
  134. data/bridge/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +112 -0
  135. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +47 -0
  136. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +57 -0
  137. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +56 -0
  138. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +170 -0
  139. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +118 -0
  140. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/interaction_type.proto +39 -0
  141. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +51 -0
  142. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/query.proto +50 -0
  143. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +41 -0
  144. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +60 -0
  145. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +59 -0
  146. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +40 -0
  147. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +122 -0
  148. data/bridge/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +108 -0
  149. data/bridge/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +114 -0
  150. data/bridge/sdk-core/protos/api_upstream/temporal/api/filter/v1/message.proto +56 -0
  151. data/bridge/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +758 -0
  152. data/bridge/sdk-core/protos/api_upstream/temporal/api/interaction/v1/message.proto +87 -0
  153. data/bridge/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +97 -0
  154. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +121 -0
  155. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +80 -0
  156. data/bridge/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +61 -0
  157. data/bridge/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +55 -0
  158. data/bridge/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +379 -0
  159. data/bridge/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +108 -0
  160. data/bridge/sdk-core/protos/api_upstream/temporal/api/version/v1/message.proto +59 -0
  161. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +146 -0
  162. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +1168 -0
  163. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +415 -0
  164. data/bridge/sdk-core/protos/grpc/health/v1/health.proto +63 -0
  165. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +78 -0
  166. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +79 -0
  167. data/bridge/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +77 -0
  168. data/bridge/sdk-core/protos/local/temporal/sdk/core/common/common.proto +15 -0
  169. data/bridge/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +30 -0
  170. data/bridge/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +30 -0
  171. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +263 -0
  172. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +304 -0
  173. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +29 -0
  174. data/bridge/sdk-core/protos/testsrv_upstream/api-linter.yaml +38 -0
  175. data/bridge/sdk-core/protos/testsrv_upstream/buf.yaml +13 -0
  176. data/bridge/sdk-core/protos/testsrv_upstream/dependencies/gogoproto/gogo.proto +141 -0
  177. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +63 -0
  178. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +90 -0
  179. data/bridge/sdk-core/rustfmt.toml +1 -0
  180. data/bridge/sdk-core/sdk/Cargo.toml +47 -0
  181. data/bridge/sdk-core/sdk/LICENSE.txt +23 -0
  182. data/bridge/sdk-core/sdk/src/activity_context.rs +230 -0
  183. data/bridge/sdk-core/sdk/src/app_data.rs +37 -0
  184. data/bridge/sdk-core/sdk/src/interceptors.rs +50 -0
  185. data/bridge/sdk-core/sdk/src/lib.rs +794 -0
  186. data/bridge/sdk-core/sdk/src/payload_converter.rs +11 -0
  187. data/bridge/sdk-core/sdk/src/workflow_context/options.rs +295 -0
  188. data/bridge/sdk-core/sdk/src/workflow_context.rs +694 -0
  189. data/bridge/sdk-core/sdk/src/workflow_future.rs +499 -0
  190. data/bridge/sdk-core/sdk-core-protos/Cargo.toml +30 -0
  191. data/bridge/sdk-core/sdk-core-protos/LICENSE.txt +23 -0
  192. data/bridge/sdk-core/sdk-core-protos/build.rs +107 -0
  193. data/bridge/sdk-core/sdk-core-protos/src/constants.rs +7 -0
  194. data/bridge/sdk-core/sdk-core-protos/src/history_builder.rs +544 -0
  195. data/bridge/sdk-core/sdk-core-protos/src/history_info.rs +230 -0
  196. data/bridge/sdk-core/sdk-core-protos/src/lib.rs +1970 -0
  197. data/bridge/sdk-core/sdk-core-protos/src/task_token.rs +38 -0
  198. data/bridge/sdk-core/sdk-core-protos/src/utilities.rs +14 -0
  199. data/bridge/sdk-core/test-utils/Cargo.toml +36 -0
  200. data/bridge/sdk-core/test-utils/src/canned_histories.rs +1579 -0
  201. data/bridge/sdk-core/test-utils/src/histfetch.rs +28 -0
  202. data/bridge/sdk-core/test-utils/src/lib.rs +650 -0
  203. data/bridge/sdk-core/tests/integ_tests/client_tests.rs +36 -0
  204. data/bridge/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +128 -0
  205. data/bridge/sdk-core/tests/integ_tests/heartbeat_tests.rs +221 -0
  206. data/bridge/sdk-core/tests/integ_tests/metrics_tests.rs +37 -0
  207. data/bridge/sdk-core/tests/integ_tests/polling_tests.rs +133 -0
  208. data/bridge/sdk-core/tests/integ_tests/queries_tests.rs +437 -0
  209. data/bridge/sdk-core/tests/integ_tests/visibility_tests.rs +93 -0
  210. data/bridge/sdk-core/tests/integ_tests/workflow_tests/activities.rs +878 -0
  211. data/bridge/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +61 -0
  212. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +59 -0
  213. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +58 -0
  214. data/bridge/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +50 -0
  215. data/bridge/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +60 -0
  216. data/bridge/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +54 -0
  217. data/bridge/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +788 -0
  218. data/bridge/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +53 -0
  219. data/bridge/sdk-core/tests/integ_tests/workflow_tests/patches.rs +113 -0
  220. data/bridge/sdk-core/tests/integ_tests/workflow_tests/replay.rs +223 -0
  221. data/bridge/sdk-core/tests/integ_tests/workflow_tests/resets.rs +93 -0
  222. data/bridge/sdk-core/tests/integ_tests/workflow_tests/signals.rs +167 -0
  223. data/bridge/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +99 -0
  224. data/bridge/sdk-core/tests/integ_tests/workflow_tests/timers.rs +131 -0
  225. data/bridge/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +75 -0
  226. data/bridge/sdk-core/tests/integ_tests/workflow_tests.rs +597 -0
  227. data/bridge/sdk-core/tests/load_tests.rs +191 -0
  228. data/bridge/sdk-core/tests/main.rs +113 -0
  229. data/bridge/sdk-core/tests/runner.rs +93 -0
  230. data/bridge/src/connection.rs +186 -0
  231. data/bridge/src/lib.rs +239 -0
  232. data/bridge/src/runtime.rs +54 -0
  233. data/bridge/src/worker.rs +124 -0
  234. data/ext/Rakefile +9 -0
  235. data/lib/bridge.so +0 -0
  236. data/lib/gen/dependencies/gogoproto/gogo_pb.rb +14 -0
  237. data/lib/gen/temporal/api/batch/v1/message_pb.rb +50 -0
  238. data/lib/gen/temporal/api/command/v1/message_pb.rb +174 -0
  239. data/lib/gen/temporal/api/common/v1/message_pb.rb +69 -0
  240. data/lib/gen/temporal/api/enums/v1/batch_operation_pb.rb +33 -0
  241. data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +39 -0
  242. data/lib/gen/temporal/api/enums/v1/common_pb.rb +42 -0
  243. data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +68 -0
  244. data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +77 -0
  245. data/lib/gen/temporal/api/enums/v1/interaction_type_pb.rb +25 -0
  246. data/lib/gen/temporal/api/enums/v1/namespace_pb.rb +37 -0
  247. data/lib/gen/temporal/api/enums/v1/query_pb.rb +31 -0
  248. data/lib/gen/temporal/api/enums/v1/reset_pb.rb +24 -0
  249. data/lib/gen/temporal/api/enums/v1/schedule_pb.rb +28 -0
  250. data/lib/gen/temporal/api/enums/v1/task_queue_pb.rb +30 -0
  251. data/lib/gen/temporal/api/enums/v1/update_pb.rb +23 -0
  252. data/lib/gen/temporal/api/enums/v1/workflow_pb.rb +89 -0
  253. data/lib/gen/temporal/api/errordetails/v1/message_pb.rb +84 -0
  254. data/lib/gen/temporal/api/failure/v1/message_pb.rb +83 -0
  255. data/lib/gen/temporal/api/filter/v1/message_pb.rb +40 -0
  256. data/lib/gen/temporal/api/history/v1/message_pb.rb +490 -0
  257. data/lib/gen/temporal/api/interaction/v1/message_pb.rb +49 -0
  258. data/lib/gen/temporal/api/namespace/v1/message_pb.rb +63 -0
  259. data/lib/gen/temporal/api/operatorservice/v1/request_response_pb.rb +85 -0
  260. data/lib/gen/temporal/api/operatorservice/v1/service_pb.rb +20 -0
  261. data/lib/gen/temporal/api/query/v1/message_pb.rb +38 -0
  262. data/lib/gen/temporal/api/replication/v1/message_pb.rb +37 -0
  263. data/lib/gen/temporal/api/schedule/v1/message_pb.rb +149 -0
  264. data/lib/gen/temporal/api/taskqueue/v1/message_pb.rb +73 -0
  265. data/lib/gen/temporal/api/version/v1/message_pb.rb +41 -0
  266. data/lib/gen/temporal/api/workflow/v1/message_pb.rb +111 -0
  267. data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +788 -0
  268. data/lib/gen/temporal/api/workflowservice/v1/service_pb.rb +20 -0
  269. data/lib/gen/temporal/sdk/core/activity_result/activity_result_pb.rb +58 -0
  270. data/lib/gen/temporal/sdk/core/activity_task/activity_task_pb.rb +57 -0
  271. data/lib/gen/temporal/sdk/core/bridge/bridge_pb.rb +222 -0
  272. data/lib/gen/temporal/sdk/core/child_workflow/child_workflow_pb.rb +57 -0
  273. data/lib/gen/temporal/sdk/core/common/common_pb.rb +22 -0
  274. data/lib/gen/temporal/sdk/core/core_interface_pb.rb +34 -0
  275. data/lib/gen/temporal/sdk/core/external_data/external_data_pb.rb +27 -0
  276. data/lib/gen/temporal/sdk/core/workflow_activation/workflow_activation_pb.rb +165 -0
  277. data/lib/gen/temporal/sdk/core/workflow_commands/workflow_commands_pb.rb +196 -0
  278. data/lib/gen/temporal/sdk/core/workflow_completion/workflow_completion_pb.rb +34 -0
  279. data/lib/temporalio/activity/context.rb +97 -0
  280. data/lib/temporalio/activity/info.rb +67 -0
  281. data/lib/temporalio/activity.rb +85 -0
  282. data/lib/temporalio/bridge/error.rb +8 -0
  283. data/lib/temporalio/bridge.rb +14 -0
  284. data/lib/temporalio/client/implementation.rb +340 -0
  285. data/lib/temporalio/client/workflow_handle.rb +243 -0
  286. data/lib/temporalio/client.rb +131 -0
  287. data/lib/temporalio/connection.rb +751 -0
  288. data/lib/temporalio/data_converter.rb +191 -0
  289. data/lib/temporalio/error/failure.rb +194 -0
  290. data/lib/temporalio/error/workflow_failure.rb +19 -0
  291. data/lib/temporalio/errors.rb +40 -0
  292. data/lib/temporalio/failure_converter/base.rb +26 -0
  293. data/lib/temporalio/failure_converter/basic.rb +319 -0
  294. data/lib/temporalio/failure_converter.rb +7 -0
  295. data/lib/temporalio/interceptor/chain.rb +28 -0
  296. data/lib/temporalio/interceptor/client.rb +123 -0
  297. data/lib/temporalio/payload_codec/base.rb +32 -0
  298. data/lib/temporalio/payload_converter/base.rb +24 -0
  299. data/lib/temporalio/payload_converter/bytes.rb +27 -0
  300. data/lib/temporalio/payload_converter/composite.rb +49 -0
  301. data/lib/temporalio/payload_converter/encoding_base.rb +35 -0
  302. data/lib/temporalio/payload_converter/json.rb +26 -0
  303. data/lib/temporalio/payload_converter/nil.rb +26 -0
  304. data/lib/temporalio/payload_converter.rb +14 -0
  305. data/lib/temporalio/retry_policy.rb +82 -0
  306. data/lib/temporalio/retry_state.rb +35 -0
  307. data/lib/temporalio/runtime.rb +25 -0
  308. data/lib/temporalio/timeout_type.rb +29 -0
  309. data/lib/temporalio/version.rb +3 -0
  310. data/lib/temporalio/worker/activity_runner.rb +92 -0
  311. data/lib/temporalio/worker/activity_worker.rb +138 -0
  312. data/lib/temporalio/worker/reactor.rb +46 -0
  313. data/lib/temporalio/worker/runner.rb +63 -0
  314. data/lib/temporalio/worker/sync_worker.rb +88 -0
  315. data/lib/temporalio/worker/thread_pool_executor.rb +51 -0
  316. data/lib/temporalio/worker.rb +198 -0
  317. data/lib/temporalio/workflow/execution_info.rb +54 -0
  318. data/lib/temporalio/workflow/execution_status.rb +36 -0
  319. data/lib/temporalio/workflow/id_reuse_policy.rb +36 -0
  320. data/lib/temporalio/workflow/query_reject_condition.rb +33 -0
  321. data/lib/temporalio.rb +12 -1
  322. data/lib/thermite_patch.rb +23 -0
  323. data/temporalio.gemspec +45 -0
  324. metadata +566 -9
  325. data/lib/temporal/version.rb +0 -3
  326. data/lib/temporal.rb +0 -4
  327. data/temporal.gemspec +0 -20
@@ -0,0 +1,858 @@
1
+ use super::{
2
+ workflow_machines::MachineResponse, Cancellable, EventInfo, NewMachineWithCommand,
3
+ OnEventWrapper, WFMachinesAdapter, WFMachinesError,
4
+ };
5
+ use rustfsm::{fsm, MachineError, TransitionResult};
6
+ use std::convert::{TryFrom, TryInto};
7
+ use temporal_sdk_core_protos::{
8
+ coresdk::{
9
+ child_workflow::{
10
+ self as wfr, child_workflow_result::Status as ChildWorkflowStatus,
11
+ ChildWorkflowCancellationType, ChildWorkflowResult,
12
+ },
13
+ workflow_activation::{
14
+ resolve_child_workflow_execution_start, ResolveChildWorkflowExecution,
15
+ ResolveChildWorkflowExecutionStart, ResolveChildWorkflowExecutionStartCancelled,
16
+ ResolveChildWorkflowExecutionStartFailure, ResolveChildWorkflowExecutionStartSuccess,
17
+ },
18
+ workflow_commands::StartChildWorkflowExecution,
19
+ },
20
+ temporal::api::{
21
+ command::v1::{Command, RequestCancelExternalWorkflowExecutionCommandAttributes},
22
+ common::v1::{Payload, Payloads, WorkflowExecution, WorkflowType},
23
+ enums::v1::{
24
+ CommandType, EventType, RetryState, StartChildWorkflowExecutionFailedCause, TimeoutType,
25
+ },
26
+ failure::v1::{self as failure, failure::FailureInfo, Failure},
27
+ history::v1::{
28
+ history_event, ChildWorkflowExecutionCompletedEventAttributes,
29
+ ChildWorkflowExecutionFailedEventAttributes,
30
+ ChildWorkflowExecutionStartedEventAttributes, HistoryEvent,
31
+ StartChildWorkflowExecutionFailedEventAttributes,
32
+ },
33
+ },
34
+ };
35
+
36
+ fsm! {
37
+ pub(super) name ChildWorkflowMachine;
38
+ command ChildWorkflowCommand;
39
+ error WFMachinesError;
40
+ shared_state SharedState;
41
+
42
+ Created --(Schedule, on_schedule) --> StartCommandCreated;
43
+ StartCommandCreated --(CommandStartChildWorkflowExecution) --> StartCommandCreated;
44
+ StartCommandCreated --(StartChildWorkflowExecutionInitiated(i64),
45
+ shared on_start_child_workflow_execution_initiated) --> StartEventRecorded;
46
+ StartCommandCreated --(Cancel, shared on_cancelled) --> Cancelled;
47
+
48
+ StartEventRecorded --(ChildWorkflowExecutionStarted(ChildWorkflowExecutionStartedEvent),
49
+ shared on_child_workflow_execution_started) --> Started;
50
+ StartEventRecorded --(StartChildWorkflowExecutionFailed(StartChildWorkflowExecutionFailedCause),
51
+ on_start_child_workflow_execution_failed) --> StartFailed;
52
+
53
+ Started --(ChildWorkflowExecutionCompleted(Option<Payloads>),
54
+ on_child_workflow_execution_completed) --> Completed;
55
+ Started --(ChildWorkflowExecutionFailed(ChildWorkflowExecutionFailedEventAttributes),
56
+ shared on_child_workflow_execution_failed) --> Failed;
57
+ Started --(ChildWorkflowExecutionTimedOut(RetryState),
58
+ shared on_child_workflow_execution_timed_out) --> TimedOut;
59
+ Started --(ChildWorkflowExecutionCancelled,
60
+ on_child_workflow_execution_cancelled) --> Cancelled;
61
+ Started --(ChildWorkflowExecutionTerminated,
62
+ shared on_child_workflow_execution_terminated) --> Terminated;
63
+ // If cancelled after started, we need to issue a cancel external workflow command, and then
64
+ // the child workflow will resolve somehow, so we want to go back to started and wait for that
65
+ // resolution.
66
+ Started --(Cancel, shared on_cancelled) --> Started;
67
+ // Abandon & try cancel modes may immediately move to cancelled
68
+ Started --(Cancel, shared on_cancelled) --> Cancelled;
69
+ Started --(CommandRequestCancelExternalWorkflowExecution) --> Started;
70
+
71
+ // Ignore any spurious cancellations after resolution
72
+ Cancelled --(Cancel) --> Cancelled;
73
+ Failed --(Cancel) --> Failed;
74
+ StartFailed --(Cancel) --> StartFailed;
75
+ TimedOut --(Cancel) --> TimedOut;
76
+ Completed --(Cancel) --> Completed;
77
+ }
78
+
79
+ pub struct ChildWorkflowExecutionStartedEvent {
80
+ workflow_execution: WorkflowExecution,
81
+ started_event_id: i64,
82
+ }
83
+
84
+ #[derive(Debug, derive_more::Display)]
85
+ pub(super) enum ChildWorkflowCommand {
86
+ #[display(fmt = "Start")]
87
+ Start(WorkflowExecution),
88
+ #[display(fmt = "Complete")]
89
+ Complete(Option<Payloads>),
90
+ #[display(fmt = "Fail")]
91
+ Fail(Failure),
92
+ #[display(fmt = "Cancel")]
93
+ Cancel,
94
+ #[display(fmt = "StartFail")]
95
+ StartFail(StartChildWorkflowExecutionFailedCause),
96
+ #[display(fmt = "StartCancel")]
97
+ StartCancel(Failure),
98
+ #[display(fmt = "CancelAfterStarted")]
99
+ IssueCancelAfterStarted { reason: String },
100
+ }
101
+
102
+ #[derive(Default, Clone)]
103
+ pub(super) struct Cancelled {}
104
+
105
+ #[derive(Default, Clone)]
106
+ pub(super) struct Completed {}
107
+
108
+ #[derive(Default, Clone)]
109
+ pub(super) struct Created {}
110
+
111
+ impl Created {
112
+ pub(super) fn on_schedule(self) -> ChildWorkflowMachineTransition<StartCommandCreated> {
113
+ TransitionResult::default()
114
+ }
115
+ }
116
+
117
+ #[derive(Default, Clone)]
118
+ pub(super) struct Failed {}
119
+
120
+ #[derive(Default, Clone)]
121
+ pub(super) struct StartCommandCreated {}
122
+
123
+ impl StartCommandCreated {
124
+ pub(super) fn on_start_child_workflow_execution_initiated(
125
+ self,
126
+ state: SharedState,
127
+ initiated_event_id: i64,
128
+ ) -> ChildWorkflowMachineTransition<StartEventRecorded> {
129
+ ChildWorkflowMachineTransition::ok_shared(
130
+ vec![],
131
+ StartEventRecorded::default(),
132
+ SharedState {
133
+ initiated_event_id,
134
+ ..state
135
+ },
136
+ )
137
+ }
138
+
139
+ pub(super) fn on_cancelled(
140
+ self,
141
+ state: SharedState,
142
+ ) -> ChildWorkflowMachineTransition<Cancelled> {
143
+ let state = SharedState {
144
+ cancelled_before_sent: true,
145
+ ..state
146
+ };
147
+ ChildWorkflowMachineTransition::ok_shared(
148
+ vec![ChildWorkflowCommand::StartCancel(Failure {
149
+ message: "Child Workflow execution cancelled before scheduled".to_owned(),
150
+ cause: Some(Box::new(Failure {
151
+ failure_info: Some(FailureInfo::CanceledFailureInfo(
152
+ failure::CanceledFailureInfo {
153
+ ..Default::default()
154
+ },
155
+ )),
156
+ ..Default::default()
157
+ })),
158
+ failure_info: failure_info_from_state(&state, RetryState::NonRetryableFailure),
159
+ ..Default::default()
160
+ })],
161
+ Cancelled::default(),
162
+ state,
163
+ )
164
+ }
165
+ }
166
+
167
+ #[derive(Default, Clone)]
168
+ pub(super) struct StartEventRecorded {}
169
+
170
+ impl StartEventRecorded {
171
+ pub(super) fn on_child_workflow_execution_started(
172
+ self,
173
+ state: SharedState,
174
+ event: ChildWorkflowExecutionStartedEvent,
175
+ ) -> ChildWorkflowMachineTransition<Started> {
176
+ ChildWorkflowMachineTransition::ok_shared(
177
+ vec![ChildWorkflowCommand::Start(
178
+ event.workflow_execution.clone(),
179
+ )],
180
+ Started::default(),
181
+ SharedState {
182
+ started_event_id: event.started_event_id,
183
+ run_id: event.workflow_execution.run_id,
184
+ ..state
185
+ },
186
+ )
187
+ }
188
+ pub(super) fn on_start_child_workflow_execution_failed(
189
+ self,
190
+ cause: StartChildWorkflowExecutionFailedCause,
191
+ ) -> ChildWorkflowMachineTransition<StartFailed> {
192
+ ChildWorkflowMachineTransition::ok(
193
+ vec![ChildWorkflowCommand::StartFail(cause)],
194
+ StartFailed::default(),
195
+ )
196
+ }
197
+ }
198
+
199
+ #[derive(Default, Clone)]
200
+ pub(super) struct StartFailed {}
201
+
202
+ #[derive(Default, Clone)]
203
+ pub(super) struct Started {}
204
+
205
+ impl Started {
206
+ fn on_child_workflow_execution_completed(
207
+ self,
208
+ result: Option<Payloads>,
209
+ ) -> ChildWorkflowMachineTransition<Completed> {
210
+ ChildWorkflowMachineTransition::ok(
211
+ vec![ChildWorkflowCommand::Complete(result)],
212
+ Completed::default(),
213
+ )
214
+ }
215
+ fn on_child_workflow_execution_failed(
216
+ self,
217
+ state: SharedState,
218
+ attrs: ChildWorkflowExecutionFailedEventAttributes,
219
+ ) -> ChildWorkflowMachineTransition<Failed> {
220
+ ChildWorkflowMachineTransition::ok(
221
+ vec![ChildWorkflowCommand::Fail(Failure {
222
+ message: "Child Workflow execution failed".to_owned(),
223
+ failure_info: failure_info_from_state(&state, attrs.retry_state()),
224
+ cause: attrs.failure.map(Box::new),
225
+ ..Default::default()
226
+ })],
227
+ Failed::default(),
228
+ )
229
+ }
230
+ fn on_child_workflow_execution_timed_out(
231
+ self,
232
+ state: SharedState,
233
+ retry_state: RetryState,
234
+ ) -> ChildWorkflowMachineTransition<TimedOut> {
235
+ ChildWorkflowMachineTransition::ok(
236
+ vec![ChildWorkflowCommand::Fail(Failure {
237
+ message: "Child Workflow execution timed out".to_owned(),
238
+ cause: Some(Box::new(Failure {
239
+ message: "Timed out".to_owned(),
240
+ failure_info: Some(FailureInfo::TimeoutFailureInfo(
241
+ failure::TimeoutFailureInfo {
242
+ last_heartbeat_details: None,
243
+ timeout_type: TimeoutType::StartToClose as i32,
244
+ },
245
+ )),
246
+ ..Default::default()
247
+ })),
248
+ failure_info: failure_info_from_state(&state, retry_state),
249
+ ..Default::default()
250
+ })],
251
+ TimedOut::default(),
252
+ )
253
+ }
254
+ fn on_child_workflow_execution_cancelled(self) -> ChildWorkflowMachineTransition<Cancelled> {
255
+ ChildWorkflowMachineTransition::ok(vec![ChildWorkflowCommand::Cancel], Cancelled::default())
256
+ }
257
+ fn on_child_workflow_execution_terminated(
258
+ self,
259
+ state: SharedState,
260
+ ) -> ChildWorkflowMachineTransition<Terminated> {
261
+ ChildWorkflowMachineTransition::ok(
262
+ vec![ChildWorkflowCommand::Fail(Failure {
263
+ message: "Child Workflow execution terminated".to_owned(),
264
+ cause: Some(Box::new(Failure {
265
+ message: "Terminated".to_owned(),
266
+ failure_info: Some(FailureInfo::TerminatedFailureInfo(
267
+ failure::TerminatedFailureInfo {},
268
+ )),
269
+ ..Default::default()
270
+ })),
271
+ failure_info: failure_info_from_state(&state, RetryState::NonRetryableFailure),
272
+ ..Default::default()
273
+ })],
274
+ Terminated::default(),
275
+ )
276
+ }
277
+ fn on_cancelled(
278
+ self,
279
+ state: SharedState,
280
+ ) -> ChildWorkflowMachineTransition<StartedOrCancelled> {
281
+ let dest = match state.cancel_type {
282
+ ChildWorkflowCancellationType::Abandon | ChildWorkflowCancellationType::TryCancel => {
283
+ StartedOrCancelled::Cancelled(Default::default())
284
+ }
285
+ _ => StartedOrCancelled::Started(Default::default()),
286
+ };
287
+ TransitionResult::ok(
288
+ [ChildWorkflowCommand::IssueCancelAfterStarted {
289
+ reason: "Parent workflow requested cancel".to_string(),
290
+ }],
291
+ dest,
292
+ )
293
+ }
294
+ }
295
+
296
+ #[derive(Default, Clone)]
297
+ pub(super) struct Terminated {}
298
+
299
+ #[derive(Default, Clone)]
300
+ pub(super) struct TimedOut {}
301
+
302
+ #[derive(Default, Clone, Debug)]
303
+ pub(super) struct SharedState {
304
+ initiated_event_id: i64,
305
+ started_event_id: i64,
306
+ lang_sequence_number: u32,
307
+ namespace: String,
308
+ workflow_id: String,
309
+ run_id: String,
310
+ workflow_type: String,
311
+ cancelled_before_sent: bool,
312
+ cancel_type: ChildWorkflowCancellationType,
313
+ }
314
+
315
+ /// Creates a new child workflow state machine and a command to start it on the server.
316
+ pub(super) fn new_child_workflow(attribs: StartChildWorkflowExecution) -> NewMachineWithCommand {
317
+ let (wf, add_cmd) = ChildWorkflowMachine::new_scheduled(attribs);
318
+ NewMachineWithCommand {
319
+ command: add_cmd,
320
+ machine: wf.into(),
321
+ }
322
+ }
323
+
324
+ impl ChildWorkflowMachine {
325
+ /// Create a new child workflow and immediately schedule it.
326
+ pub(crate) fn new_scheduled(attribs: StartChildWorkflowExecution) -> (Self, Command) {
327
+ let mut s = Self {
328
+ state: Created {}.into(),
329
+ shared_state: SharedState {
330
+ lang_sequence_number: attribs.seq,
331
+ workflow_id: attribs.workflow_id.clone(),
332
+ workflow_type: attribs.workflow_type.clone(),
333
+ namespace: attribs.namespace.clone(),
334
+ cancel_type: attribs.cancellation_type(),
335
+ ..Default::default()
336
+ },
337
+ };
338
+ OnEventWrapper::on_event_mut(&mut s, ChildWorkflowMachineEvents::Schedule)
339
+ .expect("Scheduling child workflows doesn't fail");
340
+ let cmd = Command {
341
+ command_type: CommandType::StartChildWorkflowExecution as i32,
342
+ attributes: Some(attribs.into()),
343
+ };
344
+ (s, cmd)
345
+ }
346
+
347
+ fn resolve_cancelled_msg(&self) -> ResolveChildWorkflowExecution {
348
+ let failure = Failure {
349
+ message: "Child Workflow execution cancelled".to_owned(),
350
+ cause: Some(Box::new(Failure {
351
+ failure_info: Some(FailureInfo::CanceledFailureInfo(
352
+ failure::CanceledFailureInfo {
353
+ ..Default::default()
354
+ },
355
+ )),
356
+ ..Default::default()
357
+ })),
358
+ failure_info: failure_info_from_state(
359
+ &self.shared_state,
360
+ RetryState::NonRetryableFailure,
361
+ ),
362
+ ..Default::default()
363
+ };
364
+ ResolveChildWorkflowExecution {
365
+ seq: self.shared_state.lang_sequence_number,
366
+ result: Some(ChildWorkflowResult {
367
+ status: Some(ChildWorkflowStatus::Cancelled(wfr::Cancellation {
368
+ failure: Some(failure),
369
+ })),
370
+ }),
371
+ }
372
+ }
373
+ }
374
+
375
+ impl TryFrom<HistoryEvent> for ChildWorkflowMachineEvents {
376
+ type Error = WFMachinesError;
377
+
378
+ fn try_from(e: HistoryEvent) -> Result<Self, Self::Error> {
379
+ Ok(match EventType::from_i32(e.event_type) {
380
+ Some(EventType::StartChildWorkflowExecutionInitiated) => {
381
+ Self::StartChildWorkflowExecutionInitiated(e.event_id)
382
+ }
383
+ Some(EventType::StartChildWorkflowExecutionFailed) => {
384
+ if let Some(
385
+ history_event::Attributes::StartChildWorkflowExecutionFailedEventAttributes(
386
+ StartChildWorkflowExecutionFailedEventAttributes { cause, .. },
387
+ ),
388
+ ) = e.attributes
389
+ {
390
+ Self::StartChildWorkflowExecutionFailed(
391
+ StartChildWorkflowExecutionFailedCause::from_i32(cause).ok_or_else(
392
+ || {
393
+ WFMachinesError::Fatal(
394
+ "Invalid StartChildWorkflowExecutionFailedCause".to_string(),
395
+ )
396
+ },
397
+ )?,
398
+ )
399
+ } else {
400
+ return Err(WFMachinesError::Fatal(
401
+ "StartChildWorkflowExecutionFailed attributes were unset".to_string(),
402
+ ));
403
+ }
404
+ }
405
+ Some(EventType::ChildWorkflowExecutionStarted) => {
406
+ if let Some(
407
+ history_event::Attributes::ChildWorkflowExecutionStartedEventAttributes(
408
+ ChildWorkflowExecutionStartedEventAttributes {
409
+ workflow_execution: Some(we),
410
+ ..
411
+ },
412
+ ),
413
+ ) = e.attributes
414
+ {
415
+ Self::ChildWorkflowExecutionStarted(ChildWorkflowExecutionStartedEvent {
416
+ workflow_execution: we,
417
+ started_event_id: e.event_id,
418
+ })
419
+ } else {
420
+ return Err(WFMachinesError::Fatal(
421
+ "ChildWorkflowExecutionStarted attributes were unset or malformed"
422
+ .to_string(),
423
+ ));
424
+ }
425
+ }
426
+ Some(EventType::ChildWorkflowExecutionCompleted) => {
427
+ if let Some(
428
+ history_event::Attributes::ChildWorkflowExecutionCompletedEventAttributes(
429
+ ChildWorkflowExecutionCompletedEventAttributes { result, .. },
430
+ ),
431
+ ) = e.attributes
432
+ {
433
+ Self::ChildWorkflowExecutionCompleted(result)
434
+ } else {
435
+ return Err(WFMachinesError::Fatal(
436
+ "ChildWorkflowExecutionCompleted attributes were unset or malformed"
437
+ .to_string(),
438
+ ));
439
+ }
440
+ }
441
+ Some(EventType::ChildWorkflowExecutionFailed) => {
442
+ if let Some(
443
+ history_event::Attributes::ChildWorkflowExecutionFailedEventAttributes(attrs),
444
+ ) = e.attributes
445
+ {
446
+ Self::ChildWorkflowExecutionFailed(attrs)
447
+ } else {
448
+ return Err(WFMachinesError::Fatal(
449
+ "ChildWorkflowExecutionFailed attributes were unset".to_string(),
450
+ ));
451
+ }
452
+ }
453
+ Some(EventType::ChildWorkflowExecutionTimedOut) => {
454
+ if let Some(
455
+ history_event::Attributes::ChildWorkflowExecutionTimedOutEventAttributes(atts),
456
+ ) = e.attributes
457
+ {
458
+ Self::ChildWorkflowExecutionTimedOut(atts.retry_state())
459
+ } else {
460
+ return Err(WFMachinesError::Fatal(
461
+ "ChildWorkflowExecutionTimedOut attributes were unset or malformed"
462
+ .to_string(),
463
+ ));
464
+ }
465
+ }
466
+ Some(EventType::ChildWorkflowExecutionTerminated) => {
467
+ Self::ChildWorkflowExecutionTerminated
468
+ }
469
+ Some(EventType::ChildWorkflowExecutionCanceled) => {
470
+ Self::ChildWorkflowExecutionCancelled
471
+ }
472
+ _ => {
473
+ return Err(WFMachinesError::Fatal(format!(
474
+ "Child workflow machine does not handle this event: {:?}",
475
+ e
476
+ )))
477
+ }
478
+ })
479
+ }
480
+ }
481
+
482
+ impl WFMachinesAdapter for ChildWorkflowMachine {
483
+ fn adapt_response(
484
+ &self,
485
+ my_command: Self::Command,
486
+ event_info: Option<EventInfo>,
487
+ ) -> Result<Vec<MachineResponse>, WFMachinesError> {
488
+ Ok(match my_command {
489
+ ChildWorkflowCommand::Start(we) => {
490
+ vec![ResolveChildWorkflowExecutionStart {
491
+ seq: self.shared_state.lang_sequence_number,
492
+ status: Some(resolve_child_workflow_execution_start::Status::Succeeded(
493
+ ResolveChildWorkflowExecutionStartSuccess { run_id: we.run_id },
494
+ )),
495
+ }
496
+ .into()]
497
+ }
498
+ ChildWorkflowCommand::StartFail(cause) => {
499
+ vec![ResolveChildWorkflowExecutionStart {
500
+ seq: self.shared_state.lang_sequence_number,
501
+ status: Some(resolve_child_workflow_execution_start::Status::Failed(
502
+ ResolveChildWorkflowExecutionStartFailure {
503
+ workflow_id: self.shared_state.workflow_id.clone(),
504
+ workflow_type: self.shared_state.workflow_type.clone(),
505
+ cause: cause as i32,
506
+ },
507
+ )),
508
+ }
509
+ .into()]
510
+ }
511
+ ChildWorkflowCommand::StartCancel(failure) => {
512
+ vec![ResolveChildWorkflowExecutionStart {
513
+ seq: self.shared_state.lang_sequence_number,
514
+ status: Some(resolve_child_workflow_execution_start::Status::Cancelled(
515
+ ResolveChildWorkflowExecutionStartCancelled {
516
+ failure: Some(failure),
517
+ },
518
+ )),
519
+ }
520
+ .into()]
521
+ }
522
+ ChildWorkflowCommand::Complete(result) => {
523
+ vec![ResolveChildWorkflowExecution {
524
+ seq: self.shared_state.lang_sequence_number,
525
+ result: Some(ChildWorkflowResult {
526
+ status: Some(ChildWorkflowStatus::Completed(wfr::Success {
527
+ result: convert_payloads(event_info, result)?,
528
+ })),
529
+ }),
530
+ }
531
+ .into()]
532
+ }
533
+ ChildWorkflowCommand::Fail(failure) => {
534
+ vec![ResolveChildWorkflowExecution {
535
+ seq: self.shared_state.lang_sequence_number,
536
+ result: Some(ChildWorkflowResult {
537
+ status: Some(ChildWorkflowStatus::Failed(wfr::Failure {
538
+ failure: Some(failure),
539
+ })),
540
+ }),
541
+ }
542
+ .into()]
543
+ }
544
+ ChildWorkflowCommand::Cancel => {
545
+ vec![self.resolve_cancelled_msg().into()]
546
+ }
547
+ ChildWorkflowCommand::IssueCancelAfterStarted { reason } => {
548
+ let mut resps = vec![];
549
+ if self.shared_state.cancel_type != ChildWorkflowCancellationType::Abandon {
550
+ resps.push(MachineResponse::NewCoreOriginatedCommand(
551
+ RequestCancelExternalWorkflowExecutionCommandAttributes {
552
+ namespace: self.shared_state.namespace.clone(),
553
+ workflow_id: self.shared_state.workflow_id.clone(),
554
+ run_id: self.shared_state.run_id.clone(),
555
+ child_workflow_only: true,
556
+ reason,
557
+ control: "".to_string(),
558
+ }
559
+ .into(),
560
+ ))
561
+ }
562
+ // Immediately resolve abandon/trycancel modes
563
+ if matches!(
564
+ self.shared_state.cancel_type,
565
+ ChildWorkflowCancellationType::Abandon
566
+ | ChildWorkflowCancellationType::TryCancel
567
+ ) {
568
+ resps.push(self.resolve_cancelled_msg().into())
569
+ }
570
+ resps
571
+ }
572
+ })
573
+ }
574
+
575
+ fn matches_event(&self, event: &HistoryEvent) -> bool {
576
+ matches!(
577
+ event.event_type(),
578
+ EventType::StartChildWorkflowExecutionInitiated
579
+ | EventType::StartChildWorkflowExecutionFailed
580
+ | EventType::ChildWorkflowExecutionStarted
581
+ | EventType::ChildWorkflowExecutionCompleted
582
+ | EventType::ChildWorkflowExecutionFailed
583
+ | EventType::ChildWorkflowExecutionTimedOut
584
+ | EventType::ChildWorkflowExecutionTerminated
585
+ | EventType::ChildWorkflowExecutionCanceled
586
+ )
587
+ }
588
+ }
589
+
590
+ impl TryFrom<CommandType> for ChildWorkflowMachineEvents {
591
+ type Error = ();
592
+
593
+ fn try_from(c: CommandType) -> Result<Self, Self::Error> {
594
+ Ok(match c {
595
+ CommandType::StartChildWorkflowExecution => Self::CommandStartChildWorkflowExecution,
596
+ CommandType::RequestCancelExternalWorkflowExecution => {
597
+ Self::CommandRequestCancelExternalWorkflowExecution
598
+ }
599
+ _ => return Err(()),
600
+ })
601
+ }
602
+ }
603
+
604
+ impl Cancellable for ChildWorkflowMachine {
605
+ fn cancel(&mut self) -> Result<Vec<MachineResponse>, MachineError<Self::Error>> {
606
+ let event = ChildWorkflowMachineEvents::Cancel;
607
+ let vec = OnEventWrapper::on_event_mut(self, event)?;
608
+ let res = vec
609
+ .into_iter()
610
+ .map(|mc| match mc {
611
+ c @ ChildWorkflowCommand::StartCancel(_)
612
+ | c @ ChildWorkflowCommand::IssueCancelAfterStarted { .. } => {
613
+ self.adapt_response(c, None)
614
+ }
615
+ x => panic!("Invalid cancel event response {:?}", x),
616
+ })
617
+ .collect::<Result<Vec<_>, _>>()?
618
+ .into_iter()
619
+ .flatten()
620
+ .collect();
621
+ Ok(res)
622
+ }
623
+
624
+ fn was_cancelled_before_sent_to_server(&self) -> bool {
625
+ self.shared_state.cancelled_before_sent
626
+ }
627
+ }
628
+
629
+ fn failure_info_from_state(state: &SharedState, retry_state: RetryState) -> Option<FailureInfo> {
630
+ Some(FailureInfo::ChildWorkflowExecutionFailureInfo(
631
+ failure::ChildWorkflowExecutionFailureInfo {
632
+ namespace: state.namespace.clone(),
633
+ workflow_type: Some(WorkflowType {
634
+ name: state.workflow_type.clone(),
635
+ }),
636
+ initiated_event_id: state.initiated_event_id,
637
+ started_event_id: state.started_event_id,
638
+ retry_state: retry_state as i32,
639
+ workflow_execution: Some(WorkflowExecution {
640
+ workflow_id: state.workflow_id.clone(),
641
+ run_id: state.run_id.clone(),
642
+ }),
643
+ },
644
+ ))
645
+ }
646
+
647
+ fn convert_payloads(
648
+ event_info: Option<EventInfo>,
649
+ result: Option<Payloads>,
650
+ ) -> Result<Option<Payload>, WFMachinesError> {
651
+ result.map(TryInto::try_into).transpose().map_err(|pe| {
652
+ WFMachinesError::Fatal(format!(
653
+ "Not exactly one payload in child workflow result ({}) for event: {:?}",
654
+ pe, event_info
655
+ ))
656
+ })
657
+ }
658
+
659
+ #[cfg(test)]
660
+ mod test {
661
+ use super::*;
662
+ use crate::{
663
+ replay::TestHistoryBuilder, test_help::canned_histories, worker::workflow::ManagedWFFunc,
664
+ };
665
+ use anyhow::anyhow;
666
+ use rstest::{fixture, rstest};
667
+ use std::mem::discriminant;
668
+ use temporal_sdk::{
669
+ CancellableFuture, ChildWorkflowOptions, WfContext, WorkflowFunction, WorkflowResult,
670
+ };
671
+ use temporal_sdk_core_protos::coresdk::{
672
+ child_workflow::child_workflow_result,
673
+ workflow_activation::resolve_child_workflow_execution_start::Status as StartStatus,
674
+ };
675
+
676
+ #[derive(Clone, Copy)]
677
+ enum Expectation {
678
+ Success,
679
+ Failure,
680
+ StartFailure,
681
+ }
682
+
683
+ impl Expectation {
684
+ const fn try_from_u8(x: u8) -> Option<Self> {
685
+ Some(match x {
686
+ 0 => Self::Success,
687
+ 1 => Self::Failure,
688
+ 2 => Self::StartFailure,
689
+ _ => return None,
690
+ })
691
+ }
692
+ }
693
+
694
+ #[fixture]
695
+ fn child_workflow_happy_hist() -> ManagedWFFunc {
696
+ let func = WorkflowFunction::new(parent_wf);
697
+ let t = canned_histories::single_child_workflow("child-id-1");
698
+ assert_eq!(3, t.get_full_history_info().unwrap().wf_task_count());
699
+ ManagedWFFunc::new(t, func, vec![[Expectation::Success as u8].into()])
700
+ }
701
+
702
+ #[fixture]
703
+ fn child_workflow_fail_hist() -> ManagedWFFunc {
704
+ let func = WorkflowFunction::new(parent_wf);
705
+ let t = canned_histories::single_child_workflow_fail("child-id-1");
706
+ assert_eq!(3, t.get_full_history_info().unwrap().wf_task_count());
707
+ ManagedWFFunc::new(t, func, vec![[Expectation::Failure as u8].into()])
708
+ }
709
+
710
+ #[fixture]
711
+ fn child_workflow_start_fail_hist() -> ManagedWFFunc {
712
+ let func = WorkflowFunction::new(parent_wf);
713
+ let t = canned_histories::single_child_workflow_start_fail("child-id-1");
714
+ assert_eq!(2, t.get_full_history_info().unwrap().wf_task_count());
715
+ ManagedWFFunc::new(t, func, vec![[Expectation::StartFailure as u8].into()])
716
+ }
717
+
718
+ async fn parent_wf(ctx: WfContext) -> WorkflowResult<()> {
719
+ let expectation = Expectation::try_from_u8(ctx.get_args()[0].data[0]).unwrap();
720
+ let child = ctx.child_workflow(ChildWorkflowOptions {
721
+ workflow_id: "child-id-1".to_string(),
722
+ workflow_type: "child".to_string(),
723
+ ..Default::default()
724
+ });
725
+
726
+ let start_res = child.start(&ctx).await;
727
+ match (expectation, &start_res.status) {
728
+ (Expectation::Success | Expectation::Failure, StartStatus::Succeeded(_)) => {}
729
+ (Expectation::StartFailure, StartStatus::Failed(_)) => return Ok(().into()),
730
+ _ => return Err(anyhow!("Unexpected start status")),
731
+ };
732
+ match (
733
+ expectation,
734
+ start_res.into_started().unwrap().result().await.status,
735
+ ) {
736
+ (Expectation::Success, Some(child_workflow_result::Status::Completed(_))) => {
737
+ Ok(().into())
738
+ }
739
+ (Expectation::Failure, _) => Ok(().into()),
740
+ _ => Err(anyhow!("Unexpected child WF status")),
741
+ }
742
+ }
743
+
744
+ #[rstest(
745
+ wfm,
746
+ case::success(child_workflow_happy_hist()),
747
+ case::failure(child_workflow_fail_hist())
748
+ )]
749
+ #[tokio::test]
750
+ async fn single_child_workflow_until_completion(mut wfm: ManagedWFFunc) {
751
+ wfm.get_next_activation().await.unwrap();
752
+ let commands = wfm.get_server_commands().commands;
753
+ assert_eq!(commands.len(), 1);
754
+ assert_eq!(
755
+ commands[0].command_type,
756
+ CommandType::StartChildWorkflowExecution as i32
757
+ );
758
+
759
+ wfm.get_next_activation().await.unwrap();
760
+ let commands = wfm.get_server_commands().commands;
761
+ // Workflow is activated because the child WF has started.
762
+ // It does not generate any commands, just waits for completion.
763
+ assert_eq!(commands.len(), 0);
764
+
765
+ wfm.get_next_activation().await.unwrap();
766
+ let commands = wfm.get_server_commands().commands;
767
+ assert_eq!(commands.len(), 1);
768
+ assert_eq!(
769
+ commands[0].command_type,
770
+ CommandType::CompleteWorkflowExecution as i32
771
+ );
772
+ wfm.shutdown().await.unwrap();
773
+ }
774
+
775
+ #[rstest(wfm, case::start_failure(child_workflow_start_fail_hist()))]
776
+ #[tokio::test]
777
+ async fn single_child_workflow_start_fail(mut wfm: ManagedWFFunc) {
778
+ wfm.get_next_activation().await.unwrap();
779
+ let commands = wfm.get_server_commands().commands;
780
+ assert_eq!(commands.len(), 1);
781
+ assert_eq!(
782
+ commands[0].command_type,
783
+ CommandType::StartChildWorkflowExecution as i32
784
+ );
785
+
786
+ wfm.get_next_activation().await.unwrap();
787
+ let commands = wfm.get_server_commands().commands;
788
+ assert_eq!(commands.len(), 1);
789
+ assert_eq!(
790
+ commands[0].command_type,
791
+ CommandType::CompleteWorkflowExecution as i32
792
+ );
793
+ wfm.shutdown().await.unwrap();
794
+ }
795
+
796
+ async fn cancel_before_send_wf(ctx: WfContext) -> WorkflowResult<()> {
797
+ let workflow_id = "child-id-1";
798
+ let child = ctx.child_workflow(ChildWorkflowOptions {
799
+ workflow_id: workflow_id.to_string(),
800
+ workflow_type: "child".to_string(),
801
+ ..Default::default()
802
+ });
803
+ let start = child.start(&ctx);
804
+ start.cancel(&ctx);
805
+ match start.await.status {
806
+ StartStatus::Cancelled(_) => Ok(().into()),
807
+ _ => Err(anyhow!("Unexpected start status")),
808
+ }
809
+ }
810
+
811
+ #[fixture]
812
+ fn child_workflow_cancel_before_sent() -> ManagedWFFunc {
813
+ let func = WorkflowFunction::new(cancel_before_send_wf);
814
+ let mut t = TestHistoryBuilder::default();
815
+ t.add_by_type(EventType::WorkflowExecutionStarted);
816
+ t.add_full_wf_task();
817
+ t.add_workflow_task_scheduled_and_started();
818
+ assert_eq!(2, t.get_full_history_info().unwrap().wf_task_count());
819
+ ManagedWFFunc::new(t, func, vec![])
820
+ }
821
+
822
+ #[rstest(wfm, case::default(child_workflow_cancel_before_sent()))]
823
+ #[tokio::test]
824
+ async fn single_child_workflow_cancel_before_sent(mut wfm: ManagedWFFunc) {
825
+ wfm.get_next_activation().await.unwrap();
826
+ let commands = wfm.get_server_commands().commands;
827
+ // Workflow starts and cancels the child workflow, no commands should be sent to server.
828
+ assert_eq!(commands.len(), 0);
829
+
830
+ wfm.get_next_activation().await.unwrap();
831
+ let commands = wfm.get_server_commands().commands;
832
+ assert_eq!(commands.len(), 1);
833
+ assert_eq!(
834
+ commands[0].command_type,
835
+ CommandType::CompleteWorkflowExecution as i32
836
+ );
837
+ wfm.shutdown().await.unwrap();
838
+ }
839
+
840
+ #[test]
841
+ fn cancels_ignored_terminal() {
842
+ for state in [
843
+ ChildWorkflowMachineState::Cancelled(Cancelled {}),
844
+ Failed {}.into(),
845
+ StartFailed {}.into(),
846
+ TimedOut {}.into(),
847
+ Completed {}.into(),
848
+ ] {
849
+ let mut s = ChildWorkflowMachine {
850
+ state: state.clone(),
851
+ shared_state: Default::default(),
852
+ };
853
+ let cmds = s.cancel().unwrap();
854
+ assert_eq!(cmds.len(), 0);
855
+ assert_eq!(discriminant(&state), discriminant(&s.state));
856
+ }
857
+ }
858
+ }