temporalio 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (317) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -0
  3. data/LICENSE +20 -0
  4. data/README.md +130 -0
  5. data/bridge/Cargo.lock +2865 -0
  6. data/bridge/Cargo.toml +26 -0
  7. data/bridge/sdk-core/ARCHITECTURE.md +76 -0
  8. data/bridge/sdk-core/Cargo.lock +2606 -0
  9. data/bridge/sdk-core/Cargo.toml +2 -0
  10. data/bridge/sdk-core/LICENSE.txt +23 -0
  11. data/bridge/sdk-core/README.md +107 -0
  12. data/bridge/sdk-core/arch_docs/diagrams/README.md +10 -0
  13. data/bridge/sdk-core/arch_docs/diagrams/sticky_queues.puml +40 -0
  14. data/bridge/sdk-core/arch_docs/diagrams/workflow_internals.svg +1 -0
  15. data/bridge/sdk-core/arch_docs/sticky_queues.md +51 -0
  16. data/bridge/sdk-core/bridge-ffi/Cargo.toml +24 -0
  17. data/bridge/sdk-core/bridge-ffi/LICENSE.txt +23 -0
  18. data/bridge/sdk-core/bridge-ffi/build.rs +25 -0
  19. data/bridge/sdk-core/bridge-ffi/include/sdk-core-bridge.h +249 -0
  20. data/bridge/sdk-core/bridge-ffi/src/lib.rs +825 -0
  21. data/bridge/sdk-core/bridge-ffi/src/wrappers.rs +211 -0
  22. data/bridge/sdk-core/client/Cargo.toml +40 -0
  23. data/bridge/sdk-core/client/LICENSE.txt +23 -0
  24. data/bridge/sdk-core/client/src/lib.rs +1294 -0
  25. data/bridge/sdk-core/client/src/metrics.rs +165 -0
  26. data/bridge/sdk-core/client/src/raw.rs +931 -0
  27. data/bridge/sdk-core/client/src/retry.rs +674 -0
  28. data/bridge/sdk-core/client/src/workflow_handle/mod.rs +185 -0
  29. data/bridge/sdk-core/core/Cargo.toml +116 -0
  30. data/bridge/sdk-core/core/LICENSE.txt +23 -0
  31. data/bridge/sdk-core/core/benches/workflow_replay.rs +73 -0
  32. data/bridge/sdk-core/core/src/abstractions.rs +166 -0
  33. data/bridge/sdk-core/core/src/core_tests/activity_tasks.rs +911 -0
  34. data/bridge/sdk-core/core/src/core_tests/child_workflows.rs +221 -0
  35. data/bridge/sdk-core/core/src/core_tests/determinism.rs +107 -0
  36. data/bridge/sdk-core/core/src/core_tests/local_activities.rs +515 -0
  37. data/bridge/sdk-core/core/src/core_tests/mod.rs +100 -0
  38. data/bridge/sdk-core/core/src/core_tests/queries.rs +736 -0
  39. data/bridge/sdk-core/core/src/core_tests/replay_flag.rs +65 -0
  40. data/bridge/sdk-core/core/src/core_tests/workers.rs +259 -0
  41. data/bridge/sdk-core/core/src/core_tests/workflow_cancels.rs +124 -0
  42. data/bridge/sdk-core/core/src/core_tests/workflow_tasks.rs +2070 -0
  43. data/bridge/sdk-core/core/src/ephemeral_server/mod.rs +515 -0
  44. data/bridge/sdk-core/core/src/lib.rs +175 -0
  45. data/bridge/sdk-core/core/src/log_export.rs +62 -0
  46. data/bridge/sdk-core/core/src/pollers/mod.rs +54 -0
  47. data/bridge/sdk-core/core/src/pollers/poll_buffer.rs +297 -0
  48. data/bridge/sdk-core/core/src/protosext/mod.rs +428 -0
  49. data/bridge/sdk-core/core/src/replay/mod.rs +71 -0
  50. data/bridge/sdk-core/core/src/retry_logic.rs +202 -0
  51. data/bridge/sdk-core/core/src/telemetry/metrics.rs +383 -0
  52. data/bridge/sdk-core/core/src/telemetry/mod.rs +412 -0
  53. data/bridge/sdk-core/core/src/telemetry/prometheus_server.rs +77 -0
  54. data/bridge/sdk-core/core/src/test_help/mod.rs +875 -0
  55. data/bridge/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +580 -0
  56. data/bridge/sdk-core/core/src/worker/activities/local_activities.rs +1042 -0
  57. data/bridge/sdk-core/core/src/worker/activities.rs +464 -0
  58. data/bridge/sdk-core/core/src/worker/client/mocks.rs +87 -0
  59. data/bridge/sdk-core/core/src/worker/client.rs +347 -0
  60. data/bridge/sdk-core/core/src/worker/mod.rs +566 -0
  61. data/bridge/sdk-core/core/src/worker/workflow/bridge.rs +37 -0
  62. data/bridge/sdk-core/core/src/worker/workflow/driven_workflow.rs +110 -0
  63. data/bridge/sdk-core/core/src/worker/workflow/history_update.rs +458 -0
  64. data/bridge/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +911 -0
  65. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +298 -0
  66. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +171 -0
  67. data/bridge/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +860 -0
  68. data/bridge/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +140 -0
  69. data/bridge/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +161 -0
  70. data/bridge/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +133 -0
  71. data/bridge/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +1448 -0
  72. data/bridge/sdk-core/core/src/worker/workflow/machines/mod.rs +342 -0
  73. data/bridge/sdk-core/core/src/worker/workflow/machines/mutable_side_effect_state_machine.rs +127 -0
  74. data/bridge/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +712 -0
  75. data/bridge/sdk-core/core/src/worker/workflow/machines/side_effect_state_machine.rs +71 -0
  76. data/bridge/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +443 -0
  77. data/bridge/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +439 -0
  78. data/bridge/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +169 -0
  79. data/bridge/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +246 -0
  80. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +96 -0
  81. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +1184 -0
  82. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +277 -0
  83. data/bridge/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +198 -0
  84. data/bridge/sdk-core/core/src/worker/workflow/managed_run.rs +647 -0
  85. data/bridge/sdk-core/core/src/worker/workflow/mod.rs +1143 -0
  86. data/bridge/sdk-core/core/src/worker/workflow/run_cache.rs +145 -0
  87. data/bridge/sdk-core/core/src/worker/workflow/wft_poller.rs +88 -0
  88. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream.rs +940 -0
  89. data/bridge/sdk-core/core-api/Cargo.toml +31 -0
  90. data/bridge/sdk-core/core-api/LICENSE.txt +23 -0
  91. data/bridge/sdk-core/core-api/src/errors.rs +95 -0
  92. data/bridge/sdk-core/core-api/src/lib.rs +151 -0
  93. data/bridge/sdk-core/core-api/src/worker.rs +135 -0
  94. data/bridge/sdk-core/etc/deps.svg +187 -0
  95. data/bridge/sdk-core/etc/dynamic-config.yaml +2 -0
  96. data/bridge/sdk-core/etc/otel-collector-config.yaml +36 -0
  97. data/bridge/sdk-core/etc/prometheus.yaml +6 -0
  98. data/bridge/sdk-core/fsm/Cargo.toml +18 -0
  99. data/bridge/sdk-core/fsm/LICENSE.txt +23 -0
  100. data/bridge/sdk-core/fsm/README.md +3 -0
  101. data/bridge/sdk-core/fsm/rustfsm_procmacro/Cargo.toml +27 -0
  102. data/bridge/sdk-core/fsm/rustfsm_procmacro/LICENSE.txt +23 -0
  103. data/bridge/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +647 -0
  104. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/progress.rs +8 -0
  105. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dupe_transitions_fail.rs +18 -0
  106. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dupe_transitions_fail.stderr +12 -0
  107. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dynamic_dest_pass.rs +41 -0
  108. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/forgot_name_fail.rs +14 -0
  109. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/forgot_name_fail.stderr +11 -0
  110. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/handler_arg_pass.rs +32 -0
  111. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/handler_pass.rs +31 -0
  112. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/medium_complex_pass.rs +46 -0
  113. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.rs +29 -0
  114. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +12 -0
  115. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/simple_pass.rs +32 -0
  116. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/struct_event_variant_fail.rs +18 -0
  117. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/struct_event_variant_fail.stderr +5 -0
  118. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_more_item_event_variant_fail.rs +11 -0
  119. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_more_item_event_variant_fail.stderr +5 -0
  120. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_zero_item_event_variant_fail.rs +11 -0
  121. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_zero_item_event_variant_fail.stderr +5 -0
  122. data/bridge/sdk-core/fsm/rustfsm_trait/Cargo.toml +14 -0
  123. data/bridge/sdk-core/fsm/rustfsm_trait/LICENSE.txt +23 -0
  124. data/bridge/sdk-core/fsm/rustfsm_trait/src/lib.rs +249 -0
  125. data/bridge/sdk-core/fsm/src/lib.rs +2 -0
  126. data/bridge/sdk-core/histories/fail_wf_task.bin +0 -0
  127. data/bridge/sdk-core/histories/timer_workflow_history.bin +0 -0
  128. data/bridge/sdk-core/integ-with-otel.sh +7 -0
  129. data/bridge/sdk-core/protos/api_upstream/README.md +9 -0
  130. data/bridge/sdk-core/protos/api_upstream/api-linter.yaml +40 -0
  131. data/bridge/sdk-core/protos/api_upstream/buf.yaml +12 -0
  132. data/bridge/sdk-core/protos/api_upstream/dependencies/gogoproto/gogo.proto +141 -0
  133. data/bridge/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +86 -0
  134. data/bridge/sdk-core/protos/api_upstream/temporal/api/cluster/v1/message.proto +83 -0
  135. data/bridge/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +259 -0
  136. data/bridge/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +112 -0
  137. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +46 -0
  138. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/cluster.proto +40 -0
  139. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +57 -0
  140. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +55 -0
  141. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +168 -0
  142. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +97 -0
  143. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +51 -0
  144. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/query.proto +50 -0
  145. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +41 -0
  146. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +60 -0
  147. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +59 -0
  148. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +51 -0
  149. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +122 -0
  150. data/bridge/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +108 -0
  151. data/bridge/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +114 -0
  152. data/bridge/sdk-core/protos/api_upstream/temporal/api/filter/v1/message.proto +56 -0
  153. data/bridge/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +751 -0
  154. data/bridge/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +97 -0
  155. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +161 -0
  156. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +99 -0
  157. data/bridge/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +61 -0
  158. data/bridge/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +55 -0
  159. data/bridge/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +300 -0
  160. data/bridge/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +108 -0
  161. data/bridge/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +46 -0
  162. data/bridge/sdk-core/protos/api_upstream/temporal/api/version/v1/message.proto +59 -0
  163. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +145 -0
  164. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +1124 -0
  165. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +401 -0
  166. data/bridge/sdk-core/protos/grpc/health/v1/health.proto +63 -0
  167. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +78 -0
  168. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +79 -0
  169. data/bridge/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +210 -0
  170. data/bridge/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +77 -0
  171. data/bridge/sdk-core/protos/local/temporal/sdk/core/common/common.proto +15 -0
  172. data/bridge/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +30 -0
  173. data/bridge/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +30 -0
  174. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +261 -0
  175. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +297 -0
  176. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +29 -0
  177. data/bridge/sdk-core/protos/testsrv_upstream/api-linter.yaml +38 -0
  178. data/bridge/sdk-core/protos/testsrv_upstream/buf.yaml +13 -0
  179. data/bridge/sdk-core/protos/testsrv_upstream/dependencies/gogoproto/gogo.proto +141 -0
  180. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +63 -0
  181. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +90 -0
  182. data/bridge/sdk-core/rustfmt.toml +1 -0
  183. data/bridge/sdk-core/sdk/Cargo.toml +47 -0
  184. data/bridge/sdk-core/sdk/LICENSE.txt +23 -0
  185. data/bridge/sdk-core/sdk/src/activity_context.rs +230 -0
  186. data/bridge/sdk-core/sdk/src/app_data.rs +37 -0
  187. data/bridge/sdk-core/sdk/src/conversions.rs +8 -0
  188. data/bridge/sdk-core/sdk/src/interceptors.rs +17 -0
  189. data/bridge/sdk-core/sdk/src/lib.rs +792 -0
  190. data/bridge/sdk-core/sdk/src/payload_converter.rs +11 -0
  191. data/bridge/sdk-core/sdk/src/workflow_context/options.rs +295 -0
  192. data/bridge/sdk-core/sdk/src/workflow_context.rs +683 -0
  193. data/bridge/sdk-core/sdk/src/workflow_future.rs +503 -0
  194. data/bridge/sdk-core/sdk-core-protos/Cargo.toml +30 -0
  195. data/bridge/sdk-core/sdk-core-protos/LICENSE.txt +23 -0
  196. data/bridge/sdk-core/sdk-core-protos/build.rs +108 -0
  197. data/bridge/sdk-core/sdk-core-protos/src/constants.rs +7 -0
  198. data/bridge/sdk-core/sdk-core-protos/src/history_builder.rs +497 -0
  199. data/bridge/sdk-core/sdk-core-protos/src/history_info.rs +230 -0
  200. data/bridge/sdk-core/sdk-core-protos/src/lib.rs +1910 -0
  201. data/bridge/sdk-core/sdk-core-protos/src/task_token.rs +38 -0
  202. data/bridge/sdk-core/sdk-core-protos/src/utilities.rs +14 -0
  203. data/bridge/sdk-core/test-utils/Cargo.toml +35 -0
  204. data/bridge/sdk-core/test-utils/src/canned_histories.rs +1579 -0
  205. data/bridge/sdk-core/test-utils/src/histfetch.rs +28 -0
  206. data/bridge/sdk-core/test-utils/src/lib.rs +598 -0
  207. data/bridge/sdk-core/tests/integ_tests/client_tests.rs +36 -0
  208. data/bridge/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +128 -0
  209. data/bridge/sdk-core/tests/integ_tests/heartbeat_tests.rs +218 -0
  210. data/bridge/sdk-core/tests/integ_tests/polling_tests.rs +146 -0
  211. data/bridge/sdk-core/tests/integ_tests/queries_tests.rs +437 -0
  212. data/bridge/sdk-core/tests/integ_tests/visibility_tests.rs +93 -0
  213. data/bridge/sdk-core/tests/integ_tests/workflow_tests/activities.rs +878 -0
  214. data/bridge/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +61 -0
  215. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +59 -0
  216. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +58 -0
  217. data/bridge/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +50 -0
  218. data/bridge/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +60 -0
  219. data/bridge/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +54 -0
  220. data/bridge/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +634 -0
  221. data/bridge/sdk-core/tests/integ_tests/workflow_tests/patches.rs +113 -0
  222. data/bridge/sdk-core/tests/integ_tests/workflow_tests/replay.rs +137 -0
  223. data/bridge/sdk-core/tests/integ_tests/workflow_tests/resets.rs +93 -0
  224. data/bridge/sdk-core/tests/integ_tests/workflow_tests/signals.rs +167 -0
  225. data/bridge/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +99 -0
  226. data/bridge/sdk-core/tests/integ_tests/workflow_tests/timers.rs +131 -0
  227. data/bridge/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +75 -0
  228. data/bridge/sdk-core/tests/integ_tests/workflow_tests.rs +587 -0
  229. data/bridge/sdk-core/tests/load_tests.rs +191 -0
  230. data/bridge/sdk-core/tests/main.rs +111 -0
  231. data/bridge/sdk-core/tests/runner.rs +93 -0
  232. data/bridge/src/connection.rs +167 -0
  233. data/bridge/src/lib.rs +180 -0
  234. data/bridge/src/runtime.rs +47 -0
  235. data/bridge/src/worker.rs +73 -0
  236. data/ext/Rakefile +9 -0
  237. data/lib/bridge.so +0 -0
  238. data/lib/gen/dependencies/gogoproto/gogo_pb.rb +14 -0
  239. data/lib/gen/temporal/api/batch/v1/message_pb.rb +48 -0
  240. data/lib/gen/temporal/api/cluster/v1/message_pb.rb +67 -0
  241. data/lib/gen/temporal/api/command/v1/message_pb.rb +166 -0
  242. data/lib/gen/temporal/api/common/v1/message_pb.rb +69 -0
  243. data/lib/gen/temporal/api/enums/v1/batch_operation_pb.rb +32 -0
  244. data/lib/gen/temporal/api/enums/v1/cluster_pb.rb +26 -0
  245. data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +37 -0
  246. data/lib/gen/temporal/api/enums/v1/common_pb.rb +41 -0
  247. data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +67 -0
  248. data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +71 -0
  249. data/lib/gen/temporal/api/enums/v1/namespace_pb.rb +37 -0
  250. data/lib/gen/temporal/api/enums/v1/query_pb.rb +31 -0
  251. data/lib/gen/temporal/api/enums/v1/reset_pb.rb +24 -0
  252. data/lib/gen/temporal/api/enums/v1/schedule_pb.rb +28 -0
  253. data/lib/gen/temporal/api/enums/v1/task_queue_pb.rb +30 -0
  254. data/lib/gen/temporal/api/enums/v1/update_pb.rb +28 -0
  255. data/lib/gen/temporal/api/enums/v1/workflow_pb.rb +89 -0
  256. data/lib/gen/temporal/api/errordetails/v1/message_pb.rb +84 -0
  257. data/lib/gen/temporal/api/failure/v1/message_pb.rb +83 -0
  258. data/lib/gen/temporal/api/filter/v1/message_pb.rb +40 -0
  259. data/lib/gen/temporal/api/history/v1/message_pb.rb +489 -0
  260. data/lib/gen/temporal/api/namespace/v1/message_pb.rb +63 -0
  261. data/lib/gen/temporal/api/operatorservice/v1/request_response_pb.rb +125 -0
  262. data/lib/gen/temporal/api/operatorservice/v1/service_pb.rb +20 -0
  263. data/lib/gen/temporal/api/query/v1/message_pb.rb +38 -0
  264. data/lib/gen/temporal/api/replication/v1/message_pb.rb +37 -0
  265. data/lib/gen/temporal/api/schedule/v1/message_pb.rb +128 -0
  266. data/lib/gen/temporal/api/taskqueue/v1/message_pb.rb +73 -0
  267. data/lib/gen/temporal/api/update/v1/message_pb.rb +26 -0
  268. data/lib/gen/temporal/api/version/v1/message_pb.rb +41 -0
  269. data/lib/gen/temporal/api/workflow/v1/message_pb.rb +110 -0
  270. data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +771 -0
  271. data/lib/gen/temporal/api/workflowservice/v1/service_pb.rb +20 -0
  272. data/lib/gen/temporal/sdk/core/activity_result/activity_result_pb.rb +58 -0
  273. data/lib/gen/temporal/sdk/core/activity_task/activity_task_pb.rb +57 -0
  274. data/lib/gen/temporal/sdk/core/bridge/bridge_pb.rb +222 -0
  275. data/lib/gen/temporal/sdk/core/child_workflow/child_workflow_pb.rb +57 -0
  276. data/lib/gen/temporal/sdk/core/common/common_pb.rb +22 -0
  277. data/lib/gen/temporal/sdk/core/core_interface_pb.rb +34 -0
  278. data/lib/gen/temporal/sdk/core/external_data/external_data_pb.rb +27 -0
  279. data/lib/gen/temporal/sdk/core/workflow_activation/workflow_activation_pb.rb +164 -0
  280. data/lib/gen/temporal/sdk/core/workflow_commands/workflow_commands_pb.rb +192 -0
  281. data/lib/gen/temporal/sdk/core/workflow_completion/workflow_completion_pb.rb +34 -0
  282. data/lib/temporal/bridge.rb +14 -0
  283. data/lib/temporal/client/implementation.rb +339 -0
  284. data/lib/temporal/client/workflow_handle.rb +243 -0
  285. data/lib/temporal/client.rb +144 -0
  286. data/lib/temporal/connection.rb +736 -0
  287. data/lib/temporal/data_converter.rb +150 -0
  288. data/lib/temporal/error/failure.rb +194 -0
  289. data/lib/temporal/error/workflow_failure.rb +17 -0
  290. data/lib/temporal/errors.rb +22 -0
  291. data/lib/temporal/failure_converter/base.rb +26 -0
  292. data/lib/temporal/failure_converter/basic.rb +313 -0
  293. data/lib/temporal/failure_converter.rb +8 -0
  294. data/lib/temporal/interceptor/chain.rb +27 -0
  295. data/lib/temporal/interceptor/client.rb +102 -0
  296. data/lib/temporal/payload_codec/base.rb +32 -0
  297. data/lib/temporal/payload_converter/base.rb +24 -0
  298. data/lib/temporal/payload_converter/bytes.rb +26 -0
  299. data/lib/temporal/payload_converter/composite.rb +47 -0
  300. data/lib/temporal/payload_converter/encoding_base.rb +35 -0
  301. data/lib/temporal/payload_converter/json.rb +25 -0
  302. data/lib/temporal/payload_converter/nil.rb +25 -0
  303. data/lib/temporal/payload_converter.rb +14 -0
  304. data/lib/temporal/retry_policy.rb +82 -0
  305. data/lib/temporal/retry_state.rb +35 -0
  306. data/lib/temporal/runtime.rb +22 -0
  307. data/lib/temporal/timeout_type.rb +29 -0
  308. data/lib/temporal/version.rb +3 -0
  309. data/lib/temporal/workflow/execution_info.rb +54 -0
  310. data/lib/temporal/workflow/execution_status.rb +36 -0
  311. data/lib/temporal/workflow/id_reuse_policy.rb +36 -0
  312. data/lib/temporal/workflow/query_reject_condition.rb +33 -0
  313. data/lib/temporal.rb +8 -0
  314. data/lib/temporalio.rb +3 -0
  315. data/lib/thermite_patch.rb +23 -0
  316. data/temporalio.gemspec +41 -0
  317. metadata +583 -0
@@ -0,0 +1,1910 @@
1
+ //! Contains the protobuf definitions used as arguments to and return values from interactions with
2
+ //! the Temporal Core SDK. Language SDK authors can generate structs using the proto definitions
3
+ //! that will match the generated structs in this module.
4
+
5
+ pub mod constants;
6
+ pub mod utilities;
7
+
8
+ #[cfg(feature = "history_builders")]
9
+ mod history_builder;
10
+ #[cfg(feature = "history_builders")]
11
+ mod history_info;
12
+ mod task_token;
13
+
14
+ #[cfg(feature = "history_builders")]
15
+ pub use history_builder::{default_wes_attribs, TestHistoryBuilder, DEFAULT_WORKFLOW_TYPE};
16
+ #[cfg(feature = "history_builders")]
17
+ pub use history_info::HistoryInfo;
18
+ pub use task_token::TaskToken;
19
+
20
+ #[allow(clippy::large_enum_variant, clippy::derive_partial_eq_without_eq)]
21
+ // I'd prefer not to do this, but there are some generated things that just don't need it.
22
+ #[allow(missing_docs)]
23
+ pub mod coresdk {
24
+ //! Contains all protobufs relating to communication between core and lang-specific SDKs
25
+
26
+ tonic::include_proto!("coresdk");
27
+
28
+ use crate::temporal::api::{
29
+ common::v1::{ActivityType, Payload, Payloads, WorkflowExecution},
30
+ failure::v1::{failure::FailureInfo, ApplicationFailureInfo, Failure},
31
+ workflowservice::v1::PollActivityTaskQueueResponse,
32
+ };
33
+ use activity_task::ActivityTask;
34
+ use serde::{Deserialize, Serialize};
35
+ use std::{
36
+ collections::HashMap,
37
+ convert::TryFrom,
38
+ fmt::{Display, Formatter},
39
+ iter::FromIterator,
40
+ };
41
+ use workflow_activation::{workflow_activation_job, WorkflowActivationJob};
42
+ use workflow_commands::{workflow_command, workflow_command::Variant, WorkflowCommand};
43
+ use workflow_completion::{workflow_activation_completion, WorkflowActivationCompletion};
44
+
45
+ #[allow(clippy::module_inception)]
46
+ pub mod activity_task {
47
+ use crate::{coresdk::ActivityTaskCompletion, task_token::fmt_tt};
48
+ use std::fmt::{Display, Formatter};
49
+ tonic::include_proto!("coresdk.activity_task");
50
+
51
+ impl ActivityTask {
52
+ pub fn cancel_from_ids(task_token: Vec<u8>, reason: ActivityCancelReason) -> Self {
53
+ Self {
54
+ task_token,
55
+ variant: Some(activity_task::Variant::Cancel(Cancel {
56
+ reason: reason as i32,
57
+ })),
58
+ }
59
+ }
60
+ }
61
+
62
+ impl Display for ActivityTaskCompletion {
63
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
64
+ write!(
65
+ f,
66
+ "ActivityTaskCompletion(token: {}",
67
+ fmt_tt(&self.task_token),
68
+ )?;
69
+ if let Some(r) = self.result.as_ref() {
70
+ write!(f, ", {}", r)?;
71
+ } else {
72
+ write!(f, ", missing result")?;
73
+ }
74
+ write!(f, ")")
75
+ }
76
+ }
77
+ }
78
+ #[allow(clippy::module_inception)]
79
+ pub mod activity_result {
80
+ tonic::include_proto!("coresdk.activity_result");
81
+ use super::super::temporal::api::{
82
+ common::v1::Payload,
83
+ failure::v1::{failure, CanceledFailureInfo, Failure as APIFailure},
84
+ };
85
+ use crate::temporal::api::{enums::v1::TimeoutType, failure::v1::TimeoutFailureInfo};
86
+ use activity_execution_result as aer;
87
+ use std::fmt::{Display, Formatter};
88
+
89
+ impl ActivityExecutionResult {
90
+ pub const fn ok(result: Payload) -> Self {
91
+ Self {
92
+ status: Some(aer::Status::Completed(Success {
93
+ result: Some(result),
94
+ })),
95
+ }
96
+ }
97
+
98
+ pub fn fail(fail: APIFailure) -> Self {
99
+ Self {
100
+ status: Some(aer::Status::Failed(Failure {
101
+ failure: Some(fail),
102
+ })),
103
+ }
104
+ }
105
+
106
+ pub fn cancel_from_details(payload: Option<Payload>) -> Self {
107
+ Self {
108
+ status: Some(aer::Status::Cancelled(Cancellation::from_details(payload))),
109
+ }
110
+ }
111
+
112
+ pub const fn will_complete_async() -> Self {
113
+ Self {
114
+ status: Some(aer::Status::WillCompleteAsync(WillCompleteAsync {})),
115
+ }
116
+ }
117
+
118
+ pub fn is_cancelled(&self) -> bool {
119
+ matches!(self.status, Some(aer::Status::Cancelled(_)))
120
+ }
121
+ }
122
+
123
+ impl Display for ActivityExecutionResult {
124
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
125
+ write!(f, "ActivityExecutionResult(")?;
126
+ match self.status.as_ref() {
127
+ None => write!(f, "missing result)"),
128
+ Some(aer::Status::Completed(v)) => {
129
+ write!(f, "{})", v)
130
+ }
131
+ Some(aer::Status::Failed(v)) => {
132
+ write!(f, "{})", v)
133
+ }
134
+ Some(aer::Status::Cancelled(v)) => {
135
+ write!(f, "{})", v)
136
+ }
137
+ Some(aer::Status::WillCompleteAsync(_)) => {
138
+ write!(f, "Will complete async)")
139
+ }
140
+ }
141
+ }
142
+ }
143
+
144
+ impl Display for Success {
145
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
146
+ write!(f, "Success(")?;
147
+ if let Some(ref v) = self.result {
148
+ write!(f, "{}", v)?;
149
+ }
150
+ write!(f, ")")
151
+ }
152
+ }
153
+
154
+ impl Display for Failure {
155
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
156
+ write!(f, "Failure(")?;
157
+ if let Some(ref v) = self.failure {
158
+ write!(f, "{}", v)?;
159
+ }
160
+ write!(f, ")")
161
+ }
162
+ }
163
+
164
+ impl Display for Cancellation {
165
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
166
+ write!(f, "Cancellation(")?;
167
+ if let Some(ref v) = self.failure {
168
+ write!(f, "{}", v)?;
169
+ }
170
+ write!(f, ")")
171
+ }
172
+ }
173
+
174
+ impl From<Result<Payload, APIFailure>> for ActivityExecutionResult {
175
+ fn from(r: Result<Payload, APIFailure>) -> Self {
176
+ Self {
177
+ status: match r {
178
+ Ok(p) => Some(aer::Status::Completed(Success { result: Some(p) })),
179
+ Err(f) => Some(aer::Status::Failed(Failure { failure: Some(f) })),
180
+ },
181
+ }
182
+ }
183
+ }
184
+
185
+ impl ActivityResolution {
186
+ pub fn unwrap_ok_payload(self) -> Payload {
187
+ match self.status.unwrap() {
188
+ activity_resolution::Status::Completed(c) => c.result.unwrap(),
189
+ _ => panic!("Activity was not successful"),
190
+ }
191
+ }
192
+
193
+ pub fn completed_ok(&self) -> bool {
194
+ matches!(self.status, Some(activity_resolution::Status::Completed(_)))
195
+ }
196
+
197
+ pub fn failed(&self) -> bool {
198
+ matches!(self.status, Some(activity_resolution::Status::Failed(_)))
199
+ }
200
+
201
+ pub fn timed_out(&self) -> bool {
202
+ matches!(self.status, Some(activity_resolution::Status::Failed(Failure {
203
+ failure: Some(ref f)
204
+ })) if f.is_timeout()
205
+ || f.cause.as_ref().map(|c| c.is_timeout()).unwrap_or_default())
206
+ }
207
+
208
+ pub fn cancelled(&self) -> bool {
209
+ matches!(self.status, Some(activity_resolution::Status::Cancelled(_)))
210
+ }
211
+ }
212
+
213
+ impl Cancellation {
214
+ pub fn from_details(payload: Option<Payload>) -> Self {
215
+ Cancellation {
216
+ failure: Some(APIFailure {
217
+ message: "Activity cancelled".to_string(),
218
+ failure_info: Some(failure::FailureInfo::CanceledFailureInfo(
219
+ CanceledFailureInfo {
220
+ details: payload.map(Into::into),
221
+ },
222
+ )),
223
+ ..Default::default()
224
+ }),
225
+ }
226
+ }
227
+ }
228
+
229
+ impl Failure {
230
+ pub fn timeout(timeout_type: TimeoutType) -> Self {
231
+ Failure {
232
+ failure: Some(APIFailure {
233
+ message: "Activity timed out".to_string(),
234
+ failure_info: Some(failure::FailureInfo::TimeoutFailureInfo(
235
+ TimeoutFailureInfo {
236
+ timeout_type: timeout_type as i32,
237
+ last_heartbeat_details: None,
238
+ },
239
+ )),
240
+ ..Default::default()
241
+ }),
242
+ }
243
+ }
244
+ }
245
+ }
246
+
247
+ pub mod bridge {
248
+ tonic::include_proto!("coresdk.bridge");
249
+ }
250
+
251
+ pub mod common {
252
+ tonic::include_proto!("coresdk.common");
253
+ use super::external_data::LocalActivityMarkerData;
254
+ use crate::{
255
+ coresdk::{AsJsonPayloadExt, IntoPayloadsExt},
256
+ temporal::api::common::v1::{Payload, Payloads},
257
+ };
258
+ use std::collections::HashMap;
259
+
260
+ pub fn build_has_change_marker_details(
261
+ patch_id: &str,
262
+ deprecated: bool,
263
+ ) -> HashMap<String, Payloads> {
264
+ let mut hm = HashMap::new();
265
+ hm.insert("patch_id".to_string(), patch_id.as_bytes().into());
266
+ let deprecated = deprecated as u8;
267
+ hm.insert("deprecated".to_string(), (&[deprecated]).into());
268
+ hm
269
+ }
270
+
271
+ pub fn decode_change_marker_details(
272
+ details: &HashMap<String, Payloads>,
273
+ ) -> Option<(String, bool)> {
274
+ let name =
275
+ std::str::from_utf8(&details.get("patch_id")?.payloads.first()?.data).ok()?;
276
+ let deprecated = *details.get("deprecated")?.payloads.first()?.data.first()? != 0;
277
+ Some((name.to_string(), deprecated))
278
+ }
279
+
280
+ pub fn build_local_activity_marker_details(
281
+ metadata: LocalActivityMarkerData,
282
+ result: Option<Payload>,
283
+ ) -> HashMap<String, Payloads> {
284
+ let mut hm = HashMap::new();
285
+ // It would be more efficient for this to be proto binary, but then it shows up as
286
+ // meaningless in the Temporal UI...
287
+ if let Some(jsonified) = metadata.as_json_payload().into_payloads() {
288
+ hm.insert("data".to_string(), jsonified);
289
+ }
290
+ if let Some(res) = result {
291
+ hm.insert("result".to_string(), res.into());
292
+ }
293
+ hm
294
+ }
295
+
296
+ /// Given a marker detail map, returns just the local activity info, but not the payload.
297
+ /// This is fairly inexpensive. Deserializing the whole payload may not be.
298
+ pub fn extract_local_activity_marker_data(
299
+ details: &HashMap<String, Payloads>,
300
+ ) -> Option<LocalActivityMarkerData> {
301
+ details
302
+ .get("data")
303
+ .and_then(|p| p.payloads.get(0))
304
+ .and_then(|p| std::str::from_utf8(&p.data).ok())
305
+ .and_then(|s| serde_json::from_str(s).ok())
306
+ }
307
+
308
+ /// Given a marker detail map, returns the local activity info and the result payload
309
+ /// if they are found and the marker data is well-formed. This removes the data from the
310
+ /// map.
311
+ pub fn extract_local_activity_marker_details(
312
+ details: &mut HashMap<String, Payloads>,
313
+ ) -> (Option<LocalActivityMarkerData>, Option<Payload>) {
314
+ let data = extract_local_activity_marker_data(details);
315
+ let result = details.remove("result").and_then(|mut p| p.payloads.pop());
316
+ (data, result)
317
+ }
318
+ }
319
+
320
+ pub mod external_data {
321
+ use prost_types::{Duration, Timestamp};
322
+ use serde::{Deserialize, Deserializer, Serialize, Serializer};
323
+ tonic::include_proto!("coresdk.external_data");
324
+
325
+ // Buncha hullaballoo because prost types aren't serde compat.
326
+ // See https://github.com/tokio-rs/prost/issues/75 which hilariously Chad opened ages ago
327
+
328
+ #[derive(Serialize, Deserialize)]
329
+ #[serde(remote = "Timestamp")]
330
+ struct TimestampDef {
331
+ pub seconds: i64,
332
+ pub nanos: i32,
333
+ }
334
+ mod opt_timestamp {
335
+ use super::*;
336
+
337
+ pub fn serialize<S>(value: &Option<Timestamp>, serializer: S) -> Result<S::Ok, S::Error>
338
+ where
339
+ S: Serializer,
340
+ {
341
+ #[derive(Serialize)]
342
+ struct Helper<'a>(#[serde(with = "TimestampDef")] &'a Timestamp);
343
+
344
+ value.as_ref().map(Helper).serialize(serializer)
345
+ }
346
+
347
+ pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Timestamp>, D::Error>
348
+ where
349
+ D: Deserializer<'de>,
350
+ {
351
+ #[derive(Deserialize)]
352
+ struct Helper(#[serde(with = "TimestampDef")] Timestamp);
353
+
354
+ let helper = Option::deserialize(deserializer)?;
355
+ Ok(helper.map(|Helper(external)| external))
356
+ }
357
+ }
358
+
359
+ // Luckily Duration is also stored the exact same way
360
+ #[derive(Serialize, Deserialize)]
361
+ #[serde(remote = "Duration")]
362
+ struct DurationDef {
363
+ pub seconds: i64,
364
+ pub nanos: i32,
365
+ }
366
+ mod opt_duration {
367
+ use super::*;
368
+
369
+ pub fn serialize<S>(value: &Option<Duration>, serializer: S) -> Result<S::Ok, S::Error>
370
+ where
371
+ S: Serializer,
372
+ {
373
+ #[derive(Serialize)]
374
+ struct Helper<'a>(#[serde(with = "DurationDef")] &'a Duration);
375
+
376
+ value.as_ref().map(Helper).serialize(serializer)
377
+ }
378
+
379
+ pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Duration>, D::Error>
380
+ where
381
+ D: Deserializer<'de>,
382
+ {
383
+ #[derive(Deserialize)]
384
+ struct Helper(#[serde(with = "DurationDef")] Duration);
385
+
386
+ let helper = Option::deserialize(deserializer)?;
387
+ Ok(helper.map(|Helper(external)| external))
388
+ }
389
+ }
390
+ }
391
+
392
+ pub mod workflow_activation {
393
+ use crate::{
394
+ coresdk::{
395
+ common::NamespacedWorkflowExecution,
396
+ workflow_activation::remove_from_cache::EvictionReason, FromPayloadsExt,
397
+ },
398
+ temporal::api::{
399
+ common::v1::Header,
400
+ history::v1::{
401
+ WorkflowExecutionCancelRequestedEventAttributes,
402
+ WorkflowExecutionSignaledEventAttributes,
403
+ WorkflowExecutionStartedEventAttributes,
404
+ },
405
+ query::v1::WorkflowQuery,
406
+ },
407
+ };
408
+ use std::{
409
+ collections::HashMap,
410
+ fmt::{Display, Formatter},
411
+ };
412
+
413
+ tonic::include_proto!("coresdk.workflow_activation");
414
+
415
+ pub fn create_evict_activation(
416
+ run_id: String,
417
+ message: String,
418
+ reason: EvictionReason,
419
+ ) -> WorkflowActivation {
420
+ WorkflowActivation {
421
+ timestamp: None,
422
+ run_id,
423
+ is_replaying: false,
424
+ history_length: 0,
425
+ jobs: vec![WorkflowActivationJob::from(
426
+ workflow_activation_job::Variant::RemoveFromCache(RemoveFromCache {
427
+ message,
428
+ reason: reason as i32,
429
+ }),
430
+ )],
431
+ }
432
+ }
433
+
434
+ pub fn query_to_job(id: String, q: WorkflowQuery) -> QueryWorkflow {
435
+ QueryWorkflow {
436
+ query_id: id,
437
+ query_type: q.query_type,
438
+ arguments: Vec::from_payloads(q.query_args),
439
+ headers: q.header.map(|h| h.into()).unwrap_or_default(),
440
+ }
441
+ }
442
+
443
+ impl WorkflowActivation {
444
+ /// Returns the index of the eviction job if this activation contains one. If present
445
+ /// it should always be the last job in the list.
446
+ pub fn eviction_index(&self) -> Option<usize> {
447
+ self.jobs.iter().position(|j| {
448
+ matches!(
449
+ j,
450
+ WorkflowActivationJob {
451
+ variant: Some(workflow_activation_job::Variant::RemoveFromCache(_))
452
+ }
453
+ )
454
+ })
455
+ }
456
+
457
+ /// Returns true if the only job is eviction
458
+ pub fn is_only_eviction(&self) -> bool {
459
+ self.jobs.len() == 1 && self.eviction_index().is_some()
460
+ }
461
+
462
+ /// Returns eviction reason if this activation has an evict job
463
+ pub fn eviction_reason(&self) -> Option<EvictionReason> {
464
+ self.jobs.iter().find_map(|j| {
465
+ if let Some(workflow_activation_job::Variant::RemoveFromCache(ref rj)) =
466
+ j.variant
467
+ {
468
+ EvictionReason::from_i32(rj.reason)
469
+ } else {
470
+ None
471
+ }
472
+ })
473
+ }
474
+
475
+ /// Append an eviction job to the joblist
476
+ pub fn append_evict_job(&mut self, evict_job: RemoveFromCache) {
477
+ if let Some(last_job) = self.jobs.last() {
478
+ if matches!(
479
+ last_job.variant,
480
+ Some(workflow_activation_job::Variant::RemoveFromCache(_))
481
+ ) {
482
+ return;
483
+ }
484
+ }
485
+ let evict_job = WorkflowActivationJob::from(
486
+ workflow_activation_job::Variant::RemoveFromCache(evict_job),
487
+ );
488
+ self.jobs.push(evict_job);
489
+ }
490
+ }
491
+
492
+ impl Display for EvictionReason {
493
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
494
+ write!(f, "{:?}", self)
495
+ }
496
+ }
497
+
498
+ impl Display for WorkflowActivation {
499
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
500
+ write!(f, "WorkflowActivation(")?;
501
+ write!(f, "run_id: {}, ", self.run_id)?;
502
+ write!(f, "is_replaying: {}, ", self.is_replaying)?;
503
+ write!(
504
+ f,
505
+ "jobs: {})",
506
+ self.jobs
507
+ .iter()
508
+ .map(ToString::to_string)
509
+ .collect::<Vec<_>>()
510
+ .as_slice()
511
+ .join(", ")
512
+ )
513
+ }
514
+ }
515
+
516
+ impl Display for WorkflowActivationJob {
517
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
518
+ match &self.variant {
519
+ None => write!(f, "empty"),
520
+ Some(v) => write!(f, "{}", v),
521
+ }
522
+ }
523
+ }
524
+
525
+ impl Display for workflow_activation_job::Variant {
526
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
527
+ match self {
528
+ workflow_activation_job::Variant::StartWorkflow(_) => {
529
+ write!(f, "StartWorkflow")
530
+ }
531
+ workflow_activation_job::Variant::FireTimer(t) => {
532
+ write!(f, "FireTimer({})", t.seq)
533
+ }
534
+ workflow_activation_job::Variant::UpdateRandomSeed(_) => {
535
+ write!(f, "UpdateRandomSeed")
536
+ }
537
+ workflow_activation_job::Variant::QueryWorkflow(_) => {
538
+ write!(f, "QueryWorkflow")
539
+ }
540
+ workflow_activation_job::Variant::CancelWorkflow(_) => {
541
+ write!(f, "CancelWorkflow")
542
+ }
543
+ workflow_activation_job::Variant::SignalWorkflow(_) => {
544
+ write!(f, "SignalWorkflow")
545
+ }
546
+ workflow_activation_job::Variant::ResolveActivity(r) => {
547
+ write!(f, "ResolveActivity({})", r.seq)
548
+ }
549
+ workflow_activation_job::Variant::NotifyHasPatch(_) => {
550
+ write!(f, "NotifyHasPatch")
551
+ }
552
+ workflow_activation_job::Variant::ResolveChildWorkflowExecutionStart(_) => {
553
+ write!(f, "ResolveChildWorkflowExecutionStart")
554
+ }
555
+ workflow_activation_job::Variant::ResolveChildWorkflowExecution(_) => {
556
+ write!(f, "ResolveChildWorkflowExecution")
557
+ }
558
+ workflow_activation_job::Variant::ResolveSignalExternalWorkflow(_) => {
559
+ write!(f, "ResolveSignalExternalWorkflow")
560
+ }
561
+ workflow_activation_job::Variant::RemoveFromCache(_) => {
562
+ write!(f, "RemoveFromCache")
563
+ }
564
+ workflow_activation_job::Variant::ResolveRequestCancelExternalWorkflow(_) => {
565
+ write!(f, "ResolveRequestCancelExternalWorkflow")
566
+ }
567
+ }
568
+ }
569
+ }
570
+
571
+ impl Display for QueryWorkflow {
572
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
573
+ write!(
574
+ f,
575
+ "QueryWorkflow(id: {}, type: {})",
576
+ self.query_id, self.query_type
577
+ )
578
+ }
579
+ }
580
+
581
+ impl From<WorkflowExecutionSignaledEventAttributes> for SignalWorkflow {
582
+ fn from(a: WorkflowExecutionSignaledEventAttributes) -> Self {
583
+ Self {
584
+ signal_name: a.signal_name,
585
+ input: Vec::from_payloads(a.input),
586
+ identity: a.identity,
587
+ headers: a.header.map(Into::into).unwrap_or_default(),
588
+ }
589
+ }
590
+ }
591
+
592
+ impl From<WorkflowExecutionCancelRequestedEventAttributes> for CancelWorkflow {
593
+ fn from(_a: WorkflowExecutionCancelRequestedEventAttributes) -> Self {
594
+ Self { details: vec![] }
595
+ }
596
+ }
597
+
598
+ /// Create a [StartWorkflow] job from corresponding event attributes
599
+ pub fn start_workflow_from_attribs(
600
+ attrs: WorkflowExecutionStartedEventAttributes,
601
+ workflow_id: String,
602
+ randomness_seed: u64,
603
+ ) -> StartWorkflow {
604
+ StartWorkflow {
605
+ workflow_type: attrs.workflow_type.map(|wt| wt.name).unwrap_or_default(),
606
+ workflow_id,
607
+ arguments: Vec::from_payloads(attrs.input),
608
+ randomness_seed,
609
+ headers: match attrs.header {
610
+ None => HashMap::new(),
611
+ Some(Header { fields }) => fields,
612
+ },
613
+ identity: attrs.identity,
614
+ parent_workflow_info: attrs.parent_workflow_execution.map(|pe| {
615
+ NamespacedWorkflowExecution {
616
+ namespace: attrs.parent_workflow_namespace,
617
+ run_id: pe.run_id,
618
+ workflow_id: pe.workflow_id,
619
+ }
620
+ }),
621
+ workflow_execution_timeout: attrs.workflow_execution_timeout,
622
+ workflow_run_timeout: attrs.workflow_run_timeout,
623
+ workflow_task_timeout: attrs.workflow_task_timeout,
624
+ continued_from_execution_run_id: attrs.continued_execution_run_id,
625
+ continued_initiator: attrs.initiator,
626
+ continued_failure: attrs.continued_failure,
627
+ last_completion_result: attrs.last_completion_result,
628
+ first_execution_run_id: attrs.first_execution_run_id,
629
+ retry_policy: attrs.retry_policy,
630
+ attempt: attrs.attempt,
631
+ cron_schedule: attrs.cron_schedule,
632
+ workflow_execution_expiration_time: attrs.workflow_execution_expiration_time,
633
+ cron_schedule_to_schedule_interval: attrs.first_workflow_task_backoff,
634
+ memo: attrs.memo,
635
+ search_attributes: attrs.search_attributes,
636
+ }
637
+ }
638
+ }
639
+
640
+ pub mod workflow_completion {
641
+ use crate::temporal::api::failure;
642
+ tonic::include_proto!("coresdk.workflow_completion");
643
+
644
+ impl workflow_activation_completion::Status {
645
+ pub const fn is_success(&self) -> bool {
646
+ match &self {
647
+ Self::Successful(_) => true,
648
+ Self::Failed(_) => false,
649
+ }
650
+ }
651
+ }
652
+
653
+ impl From<failure::v1::Failure> for Failure {
654
+ fn from(f: failure::v1::Failure) -> Self {
655
+ Failure { failure: Some(f) }
656
+ }
657
+ }
658
+ }
659
+
660
+ pub mod child_workflow {
661
+ tonic::include_proto!("coresdk.child_workflow");
662
+ }
663
+
664
+ pub mod workflow_commands {
665
+ tonic::include_proto!("coresdk.workflow_commands");
666
+
667
+ use crate::temporal::api::{common::v1::Payloads, enums::v1::QueryResultType};
668
+ use std::fmt::{Display, Formatter};
669
+
670
+ impl Display for WorkflowCommand {
671
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
672
+ match &self.variant {
673
+ None => write!(f, "Empty"),
674
+ Some(v) => write!(f, "{}", v),
675
+ }
676
+ }
677
+ }
678
+
679
+ impl Display for StartTimer {
680
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
681
+ write!(f, "StartTimer({})", self.seq)
682
+ }
683
+ }
684
+
685
+ impl Display for ScheduleActivity {
686
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
687
+ write!(f, "ScheduleActivity({}, {})", self.seq, self.activity_type)
688
+ }
689
+ }
690
+
691
+ impl Display for ScheduleLocalActivity {
692
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
693
+ write!(
694
+ f,
695
+ "ScheduleLocalActivity({}, {})",
696
+ self.seq, self.activity_type
697
+ )
698
+ }
699
+ }
700
+
701
+ impl Display for QueryResult {
702
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
703
+ write!(f, "RespondToQuery({})", self.query_id)
704
+ }
705
+ }
706
+
707
+ impl Display for RequestCancelActivity {
708
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
709
+ write!(f, "RequestCancelActivity({})", self.seq)
710
+ }
711
+ }
712
+
713
+ impl Display for RequestCancelLocalActivity {
714
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
715
+ write!(f, "RequestCancelLocalActivity({})", self.seq)
716
+ }
717
+ }
718
+
719
+ impl Display for CancelTimer {
720
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
721
+ write!(f, "CancelTimer({})", self.seq)
722
+ }
723
+ }
724
+
725
+ impl Display for CompleteWorkflowExecution {
726
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
727
+ write!(f, "CompleteWorkflowExecution")
728
+ }
729
+ }
730
+
731
+ impl Display for FailWorkflowExecution {
732
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
733
+ write!(f, "FailWorkflowExecution")
734
+ }
735
+ }
736
+
737
+ impl Display for ContinueAsNewWorkflowExecution {
738
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
739
+ write!(f, "ContinueAsNewWorkflowExecution")
740
+ }
741
+ }
742
+
743
+ impl Display for CancelWorkflowExecution {
744
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
745
+ write!(f, "CancelWorkflowExecution")
746
+ }
747
+ }
748
+
749
+ impl Display for SetPatchMarker {
750
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
751
+ write!(f, "SetPatchMarker({})", self.patch_id)
752
+ }
753
+ }
754
+
755
+ impl Display for StartChildWorkflowExecution {
756
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
757
+ write!(
758
+ f,
759
+ "StartChildWorkflowExecution({}, {})",
760
+ self.seq, self.workflow_type
761
+ )
762
+ }
763
+ }
764
+
765
+ impl Display for RequestCancelExternalWorkflowExecution {
766
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
767
+ write!(f, "RequestCancelExternalWorkflowExecution({})", self.seq)
768
+ }
769
+ }
770
+
771
+ impl Display for UpsertWorkflowSearchAttributes {
772
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
773
+ write!(
774
+ f,
775
+ "UpsertWorkflowSearchAttributes({:?})",
776
+ self.search_attributes.keys()
777
+ )
778
+ }
779
+ }
780
+
781
+ impl Display for SignalExternalWorkflowExecution {
782
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
783
+ write!(f, "SignalExternalWorkflowExecution({})", self.seq)
784
+ }
785
+ }
786
+
787
+ impl Display for CancelSignalWorkflow {
788
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
789
+ write!(f, "CancelSignalWorkflow({})", self.seq)
790
+ }
791
+ }
792
+
793
+ impl Display for CancelChildWorkflowExecution {
794
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
795
+ write!(
796
+ f,
797
+ "CancelChildWorkflowExecution({})",
798
+ self.child_workflow_seq
799
+ )
800
+ }
801
+ }
802
+
803
+ impl QueryResult {
804
+ /// Helper to construct the Temporal API query result types.
805
+ pub fn into_components(self) -> (String, QueryResultType, Option<Payloads>, String) {
806
+ match self {
807
+ QueryResult {
808
+ variant: Some(query_result::Variant::Succeeded(qs)),
809
+ query_id,
810
+ } => (
811
+ query_id,
812
+ QueryResultType::Answered,
813
+ qs.response.map(Into::into),
814
+ "".to_string(),
815
+ ),
816
+ QueryResult {
817
+ variant: Some(query_result::Variant::Failed(err)),
818
+ query_id,
819
+ } => (query_id, QueryResultType::Failed, None, err.message),
820
+ QueryResult {
821
+ variant: None,
822
+ query_id,
823
+ } => (
824
+ query_id,
825
+ QueryResultType::Failed,
826
+ None,
827
+ "Query response was empty".to_string(),
828
+ ),
829
+ }
830
+ }
831
+ }
832
+ }
833
+
834
+ pub type HistoryEventId = i64;
835
+
836
+ impl From<workflow_activation_job::Variant> for WorkflowActivationJob {
837
+ fn from(a: workflow_activation_job::Variant) -> Self {
838
+ Self { variant: Some(a) }
839
+ }
840
+ }
841
+
842
+ impl From<Vec<WorkflowCommand>> for workflow_completion::Success {
843
+ fn from(v: Vec<WorkflowCommand>) -> Self {
844
+ Self { commands: v }
845
+ }
846
+ }
847
+
848
+ impl From<workflow_command::Variant> for WorkflowCommand {
849
+ fn from(v: workflow_command::Variant) -> Self {
850
+ Self { variant: Some(v) }
851
+ }
852
+ }
853
+
854
+ impl workflow_completion::Success {
855
+ pub fn from_variants(cmds: Vec<Variant>) -> Self {
856
+ let cmds: Vec<_> = cmds
857
+ .into_iter()
858
+ .map(|c| WorkflowCommand { variant: Some(c) })
859
+ .collect();
860
+ cmds.into()
861
+ }
862
+ }
863
+
864
+ impl WorkflowActivationCompletion {
865
+ /// Create a successful activation with no commands in it
866
+ pub fn empty(run_id: impl Into<String>) -> Self {
867
+ let success = workflow_completion::Success::from_variants(vec![]);
868
+ Self {
869
+ run_id: run_id.into(),
870
+ status: Some(workflow_activation_completion::Status::Successful(success)),
871
+ }
872
+ }
873
+
874
+ /// Create a successful activation from a list of commands
875
+ pub fn from_cmds(run_id: impl Into<String>, cmds: Vec<workflow_command::Variant>) -> Self {
876
+ let success = workflow_completion::Success::from_variants(cmds);
877
+ Self {
878
+ run_id: run_id.into(),
879
+ status: Some(workflow_activation_completion::Status::Successful(success)),
880
+ }
881
+ }
882
+
883
+ /// Create a successful activation from just one command
884
+ pub fn from_cmd(run_id: impl Into<String>, cmd: workflow_command::Variant) -> Self {
885
+ let success = workflow_completion::Success::from_variants(vec![cmd]);
886
+ Self {
887
+ run_id: run_id.into(),
888
+ status: Some(workflow_activation_completion::Status::Successful(success)),
889
+ }
890
+ }
891
+
892
+ pub fn fail(run_id: impl Into<String>, failure: Failure) -> Self {
893
+ Self {
894
+ run_id: run_id.into(),
895
+ status: Some(workflow_activation_completion::Status::Failed(
896
+ workflow_completion::Failure {
897
+ failure: Some(failure),
898
+ },
899
+ )),
900
+ }
901
+ }
902
+
903
+ /// Returns true if the activation has either a fail, continue, cancel, or complete workflow
904
+ /// execution command in it.
905
+ pub fn has_execution_ending(&self) -> bool {
906
+ self.has_complete_workflow_execution()
907
+ || self.has_fail_execution()
908
+ || self.has_continue_as_new()
909
+ || self.has_cancel_workflow_execution()
910
+ }
911
+
912
+ /// Returns true if the activation contains a fail workflow execution command
913
+ pub fn has_fail_execution(&self) -> bool {
914
+ if let Some(workflow_activation_completion::Status::Successful(s)) = &self.status {
915
+ return s.commands.iter().any(|wfc| {
916
+ matches!(
917
+ wfc,
918
+ WorkflowCommand {
919
+ variant: Some(workflow_command::Variant::FailWorkflowExecution(_)),
920
+ }
921
+ )
922
+ });
923
+ }
924
+ false
925
+ }
926
+
927
+ /// Returns true if the activation contains a cancel workflow execution command
928
+ pub fn has_cancel_workflow_execution(&self) -> bool {
929
+ if let Some(workflow_activation_completion::Status::Successful(s)) = &self.status {
930
+ return s.commands.iter().any(|wfc| {
931
+ matches!(
932
+ wfc,
933
+ WorkflowCommand {
934
+ variant: Some(workflow_command::Variant::CancelWorkflowExecution(_)),
935
+ }
936
+ )
937
+ });
938
+ }
939
+ false
940
+ }
941
+
942
+ /// Returns true if the activation contains a continue as new workflow execution command
943
+ pub fn has_continue_as_new(&self) -> bool {
944
+ if let Some(workflow_activation_completion::Status::Successful(s)) = &self.status {
945
+ return s.commands.iter().any(|wfc| {
946
+ matches!(
947
+ wfc,
948
+ WorkflowCommand {
949
+ variant: Some(
950
+ workflow_command::Variant::ContinueAsNewWorkflowExecution(_)
951
+ ),
952
+ }
953
+ )
954
+ });
955
+ }
956
+ false
957
+ }
958
+
959
+ /// Returns true if the activation contains a complete workflow execution command
960
+ pub fn has_complete_workflow_execution(&self) -> bool {
961
+ if let Some(workflow_activation_completion::Status::Successful(s)) = &self.status {
962
+ return s.commands.iter().any(|wfc| {
963
+ matches!(
964
+ wfc,
965
+ WorkflowCommand {
966
+ variant: Some(workflow_command::Variant::CompleteWorkflowExecution(_)),
967
+ }
968
+ )
969
+ });
970
+ }
971
+ false
972
+ }
973
+
974
+ /// Returns true if the activation completion is a success with no commands
975
+ pub fn is_empty(&self) -> bool {
976
+ if let Some(workflow_activation_completion::Status::Successful(s)) = &self.status {
977
+ return s.commands.is_empty();
978
+ }
979
+ false
980
+ }
981
+ }
982
+
983
+ /// Makes converting outgoing lang commands into [WorkflowActivationCompletion]s easier
984
+ pub trait IntoCompletion {
985
+ /// The conversion function
986
+ fn into_completion(self, run_id: String) -> WorkflowActivationCompletion;
987
+ }
988
+
989
+ impl IntoCompletion for workflow_command::Variant {
990
+ fn into_completion(self, run_id: String) -> WorkflowActivationCompletion {
991
+ WorkflowActivationCompletion::from_cmd(run_id, self)
992
+ }
993
+ }
994
+
995
+ impl<I, V> IntoCompletion for I
996
+ where
997
+ I: IntoIterator<Item = V>,
998
+ V: Into<WorkflowCommand>,
999
+ {
1000
+ fn into_completion(self, run_id: String) -> WorkflowActivationCompletion {
1001
+ let success = self.into_iter().map(Into::into).collect::<Vec<_>>().into();
1002
+ WorkflowActivationCompletion {
1003
+ run_id,
1004
+ status: Some(workflow_activation_completion::Status::Successful(success)),
1005
+ }
1006
+ }
1007
+ }
1008
+
1009
+ impl Display for WorkflowActivationCompletion {
1010
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1011
+ write!(
1012
+ f,
1013
+ "WorkflowActivationCompletion(run_id: {}, status: ",
1014
+ &self.run_id
1015
+ )?;
1016
+ match &self.status {
1017
+ None => write!(f, "empty")?,
1018
+ Some(s) => write!(f, "{}", s)?,
1019
+ };
1020
+ write!(f, ")")
1021
+ }
1022
+ }
1023
+
1024
+ impl Display for workflow_activation_completion::Status {
1025
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1026
+ match self {
1027
+ workflow_activation_completion::Status::Successful(
1028
+ workflow_completion::Success { commands },
1029
+ ) => {
1030
+ write!(f, "Success(")?;
1031
+ let mut written = 0;
1032
+ for c in commands {
1033
+ write!(f, "{} ", c)?;
1034
+ written += 1;
1035
+ if written >= 10 && written < commands.len() {
1036
+ write!(f, "... {} more", commands.len() - written)?;
1037
+ break;
1038
+ }
1039
+ }
1040
+ write!(f, ")")
1041
+ }
1042
+ workflow_activation_completion::Status::Failed(_) => {
1043
+ write!(f, "Failed")
1044
+ }
1045
+ }
1046
+ }
1047
+ }
1048
+
1049
+ impl ActivityTask {
1050
+ pub fn start_from_poll_resp(r: PollActivityTaskQueueResponse) -> Self {
1051
+ let (workflow_id, run_id) = r
1052
+ .workflow_execution
1053
+ .map(|we| (we.workflow_id, we.run_id))
1054
+ .unwrap_or_default();
1055
+ Self {
1056
+ task_token: r.task_token,
1057
+ variant: Some(activity_task::activity_task::Variant::Start(
1058
+ activity_task::Start {
1059
+ workflow_namespace: r.workflow_namespace,
1060
+ workflow_type: r.workflow_type.map_or_else(|| "".to_string(), |wt| wt.name),
1061
+ workflow_execution: Some(WorkflowExecution {
1062
+ workflow_id,
1063
+ run_id,
1064
+ }),
1065
+ activity_id: r.activity_id,
1066
+ activity_type: r.activity_type.map_or_else(|| "".to_string(), |at| at.name),
1067
+ header_fields: r.header.map(Into::into).unwrap_or_default(),
1068
+ input: Vec::from_payloads(r.input),
1069
+ heartbeat_details: Vec::from_payloads(r.heartbeat_details),
1070
+ scheduled_time: r.scheduled_time,
1071
+ current_attempt_scheduled_time: r.current_attempt_scheduled_time,
1072
+ started_time: r.started_time,
1073
+ attempt: r.attempt as u32,
1074
+ schedule_to_close_timeout: r.schedule_to_close_timeout,
1075
+ start_to_close_timeout: r.start_to_close_timeout,
1076
+ heartbeat_timeout: r.heartbeat_timeout,
1077
+ retry_policy: r.retry_policy.map(Into::into),
1078
+ is_local: false,
1079
+ },
1080
+ )),
1081
+ }
1082
+ }
1083
+ }
1084
+
1085
+ impl From<String> for ActivityType {
1086
+ fn from(name: String) -> Self {
1087
+ Self { name }
1088
+ }
1089
+ }
1090
+
1091
+ impl From<ActivityType> for String {
1092
+ fn from(at: ActivityType) -> Self {
1093
+ at.name
1094
+ }
1095
+ }
1096
+
1097
+ impl Failure {
1098
+ pub fn is_timeout(&self) -> bool {
1099
+ matches!(self.failure_info, Some(FailureInfo::TimeoutFailureInfo(_)))
1100
+ }
1101
+
1102
+ pub fn application_failure(message: String, non_retryable: bool) -> Self {
1103
+ Self {
1104
+ message,
1105
+ failure_info: Some(FailureInfo::ApplicationFailureInfo(
1106
+ ApplicationFailureInfo {
1107
+ non_retryable,
1108
+ ..Default::default()
1109
+ },
1110
+ )),
1111
+ ..Default::default()
1112
+ }
1113
+ }
1114
+
1115
+ /// Extracts an ApplicationFailureInfo from a Failure instance if it exists
1116
+ pub fn maybe_application_failure(&self) -> Option<&ApplicationFailureInfo> {
1117
+ if let Failure {
1118
+ failure_info: Some(FailureInfo::ApplicationFailureInfo(f)),
1119
+ ..
1120
+ } = self
1121
+ {
1122
+ Some(f)
1123
+ } else {
1124
+ None
1125
+ }
1126
+ }
1127
+ }
1128
+
1129
+ impl Display for Failure {
1130
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1131
+ write!(f, "Failure({}, ", self.message)?;
1132
+ match self.failure_info.as_ref() {
1133
+ None => write!(f, "missing info")?,
1134
+ Some(FailureInfo::TimeoutFailureInfo(v)) => {
1135
+ write!(f, "Timeout: {:?}", v.timeout_type())?;
1136
+ }
1137
+ Some(FailureInfo::ApplicationFailureInfo(v)) => {
1138
+ write!(f, "Application Failure: {}", v.r#type)?;
1139
+ }
1140
+ Some(FailureInfo::CanceledFailureInfo(_)) => {
1141
+ write!(f, "Cancelled")?;
1142
+ }
1143
+ Some(FailureInfo::TerminatedFailureInfo(_)) => {
1144
+ write!(f, "Terminated")?;
1145
+ }
1146
+ Some(FailureInfo::ServerFailureInfo(_)) => {
1147
+ write!(f, "Server Failure")?;
1148
+ }
1149
+ Some(FailureInfo::ResetWorkflowFailureInfo(_)) => {
1150
+ write!(f, "Reset Workflow")?;
1151
+ }
1152
+ Some(FailureInfo::ActivityFailureInfo(v)) => {
1153
+ write!(
1154
+ f,
1155
+ "Activity Failure: scheduled_event_id: {}",
1156
+ v.scheduled_event_id
1157
+ )?;
1158
+ }
1159
+ Some(FailureInfo::ChildWorkflowExecutionFailureInfo(v)) => {
1160
+ write!(
1161
+ f,
1162
+ "Child Workflow: started_event_id: {}",
1163
+ v.started_event_id
1164
+ )?;
1165
+ }
1166
+ }
1167
+ write!(f, ")")
1168
+ }
1169
+ }
1170
+
1171
+ impl From<&str> for Failure {
1172
+ fn from(v: &str) -> Self {
1173
+ Failure::application_failure(v.to_string(), false)
1174
+ }
1175
+ }
1176
+
1177
+ impl From<String> for Failure {
1178
+ fn from(v: String) -> Self {
1179
+ Failure::application_failure(v, false)
1180
+ }
1181
+ }
1182
+
1183
+ impl From<anyhow::Error> for Failure {
1184
+ fn from(ae: anyhow::Error) -> Self {
1185
+ Failure::application_failure(ae.to_string(), false)
1186
+ }
1187
+ }
1188
+
1189
+ pub trait FromPayloadsExt {
1190
+ fn from_payloads(p: Option<Payloads>) -> Self;
1191
+ }
1192
+ impl<T> FromPayloadsExt for T
1193
+ where
1194
+ T: FromIterator<Payload>,
1195
+ {
1196
+ fn from_payloads(p: Option<Payloads>) -> Self {
1197
+ match p {
1198
+ None => std::iter::empty().collect(),
1199
+ Some(p) => p.payloads.into_iter().map(Into::into).collect(),
1200
+ }
1201
+ }
1202
+ }
1203
+
1204
+ pub trait IntoPayloadsExt {
1205
+ fn into_payloads(self) -> Option<Payloads>;
1206
+ }
1207
+ impl<T> IntoPayloadsExt for T
1208
+ where
1209
+ T: IntoIterator<Item = Payload>,
1210
+ {
1211
+ fn into_payloads(self) -> Option<Payloads> {
1212
+ let mut iterd = self.into_iter().peekable();
1213
+ if iterd.peek().is_none() {
1214
+ None
1215
+ } else {
1216
+ Some(Payloads {
1217
+ payloads: iterd.map(Into::into).collect(),
1218
+ })
1219
+ }
1220
+ }
1221
+ }
1222
+
1223
+ impl From<Payload> for Payloads {
1224
+ fn from(p: Payload) -> Self {
1225
+ Self { payloads: vec![p] }
1226
+ }
1227
+ }
1228
+
1229
+ impl<T> From<T> for Payloads
1230
+ where
1231
+ T: AsRef<[u8]>,
1232
+ {
1233
+ fn from(v: T) -> Self {
1234
+ Self {
1235
+ payloads: vec![v.into()],
1236
+ }
1237
+ }
1238
+ }
1239
+
1240
+ #[derive(thiserror::Error, Debug)]
1241
+ pub enum PayloadDeserializeErr {
1242
+ /// This deserializer does not handle this type of payload. Allows composing multiple
1243
+ /// deserializers.
1244
+ #[error("This deserializer does not understand this payload")]
1245
+ DeserializerDoesNotHandle,
1246
+ #[error("Error during deserialization: {0}")]
1247
+ DeserializeErr(#[from] anyhow::Error),
1248
+ }
1249
+
1250
+ // TODO: Once the prototype SDK is un-prototyped this serialization will need to be compat with
1251
+ // other SDKs (given they might execute an activity).
1252
+ pub trait AsJsonPayloadExt {
1253
+ fn as_json_payload(&self) -> anyhow::Result<Payload>;
1254
+ }
1255
+ impl<T> AsJsonPayloadExt for T
1256
+ where
1257
+ T: Serialize,
1258
+ {
1259
+ fn as_json_payload(&self) -> anyhow::Result<Payload> {
1260
+ let as_json = serde_json::to_string(self)?;
1261
+ let mut metadata = HashMap::new();
1262
+ metadata.insert("encoding".to_string(), b"json/plain".to_vec());
1263
+ Ok(Payload {
1264
+ metadata,
1265
+ data: as_json.into_bytes(),
1266
+ })
1267
+ }
1268
+ }
1269
+
1270
+ pub trait FromJsonPayloadExt: Sized {
1271
+ fn from_json_payload(payload: &Payload) -> Result<Self, PayloadDeserializeErr>;
1272
+ }
1273
+ impl<T> FromJsonPayloadExt for T
1274
+ where
1275
+ T: for<'de> Deserialize<'de>,
1276
+ {
1277
+ fn from_json_payload(payload: &Payload) -> Result<Self, PayloadDeserializeErr> {
1278
+ if !matches!(
1279
+ payload.metadata.get("encoding").map(|v| v.as_slice()),
1280
+ Some(b"json/plain")
1281
+ ) {
1282
+ return Err(PayloadDeserializeErr::DeserializerDoesNotHandle);
1283
+ }
1284
+ let payload_str = std::str::from_utf8(&payload.data).map_err(anyhow::Error::from)?;
1285
+ Ok(serde_json::from_str(payload_str).map_err(anyhow::Error::from)?)
1286
+ }
1287
+ }
1288
+
1289
+ /// Errors when converting from a [Payloads] api proto to our internal [Payload]
1290
+ #[derive(derive_more::Display, Debug)]
1291
+ pub enum PayloadsToPayloadError {
1292
+ MoreThanOnePayload,
1293
+ NoPayload,
1294
+ }
1295
+ impl TryFrom<Payloads> for Payload {
1296
+ type Error = PayloadsToPayloadError;
1297
+
1298
+ fn try_from(mut v: Payloads) -> Result<Self, Self::Error> {
1299
+ match v.payloads.pop() {
1300
+ None => Err(PayloadsToPayloadError::NoPayload),
1301
+ Some(p) => {
1302
+ if v.payloads.is_empty() {
1303
+ Ok(p)
1304
+ } else {
1305
+ Err(PayloadsToPayloadError::MoreThanOnePayload)
1306
+ }
1307
+ }
1308
+ }
1309
+ }
1310
+ }
1311
+ }
1312
+
1313
+ // No need to lint these
1314
+ #[allow(
1315
+ clippy::all,
1316
+ missing_docs,
1317
+ rustdoc::broken_intra_doc_links,
1318
+ rustdoc::bare_urls
1319
+ )]
1320
+ // This is disgusting, but unclear to me how to avoid it. TODO: Discuss w/ prost maintainer
1321
+ pub mod temporal {
1322
+ pub mod api {
1323
+ pub mod cluster {
1324
+ pub mod v1 {
1325
+ tonic::include_proto!("temporal.api.cluster.v1");
1326
+ }
1327
+ }
1328
+ pub mod batch {
1329
+ pub mod v1 {
1330
+ tonic::include_proto!("temporal.api.batch.v1");
1331
+ }
1332
+ }
1333
+ pub mod command {
1334
+ pub mod v1 {
1335
+ tonic::include_proto!("temporal.api.command.v1");
1336
+
1337
+ use crate::{
1338
+ coresdk::{workflow_commands, IntoPayloadsExt},
1339
+ temporal::api::{
1340
+ common::v1::{ActivityType, WorkflowType},
1341
+ enums::v1::CommandType,
1342
+ },
1343
+ };
1344
+ use command::Attributes;
1345
+ use std::fmt::{Display, Formatter};
1346
+
1347
+ impl From<command::Attributes> for Command {
1348
+ fn from(c: command::Attributes) -> Self {
1349
+ match c {
1350
+ a @ Attributes::StartTimerCommandAttributes(_) => Self {
1351
+ command_type: CommandType::StartTimer as i32,
1352
+ attributes: Some(a),
1353
+ },
1354
+ a @ Attributes::CancelTimerCommandAttributes(_) => Self {
1355
+ command_type: CommandType::CancelTimer as i32,
1356
+ attributes: Some(a),
1357
+ },
1358
+ a @ Attributes::CompleteWorkflowExecutionCommandAttributes(_) => Self {
1359
+ command_type: CommandType::CompleteWorkflowExecution as i32,
1360
+ attributes: Some(a),
1361
+ },
1362
+ a @ Attributes::FailWorkflowExecutionCommandAttributes(_) => Self {
1363
+ command_type: CommandType::FailWorkflowExecution as i32,
1364
+ attributes: Some(a),
1365
+ },
1366
+ a @ Attributes::ScheduleActivityTaskCommandAttributes(_) => Self {
1367
+ command_type: CommandType::ScheduleActivityTask as i32,
1368
+ attributes: Some(a),
1369
+ },
1370
+ a @ Attributes::RequestCancelActivityTaskCommandAttributes(_) => Self {
1371
+ command_type: CommandType::RequestCancelActivityTask as i32,
1372
+ attributes: Some(a),
1373
+ },
1374
+ a @ Attributes::ContinueAsNewWorkflowExecutionCommandAttributes(_) => {
1375
+ Self {
1376
+ command_type: CommandType::ContinueAsNewWorkflowExecution
1377
+ as i32,
1378
+ attributes: Some(a),
1379
+ }
1380
+ }
1381
+ a @ Attributes::CancelWorkflowExecutionCommandAttributes(_) => Self {
1382
+ command_type: CommandType::CancelWorkflowExecution as i32,
1383
+ attributes: Some(a),
1384
+ },
1385
+ _ => unimplemented!(),
1386
+ }
1387
+ }
1388
+ }
1389
+
1390
+ impl Display for Command {
1391
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1392
+ let ct = CommandType::from_i32(self.command_type)
1393
+ .unwrap_or(CommandType::Unspecified);
1394
+ write!(f, "{:?}", ct)
1395
+ }
1396
+ }
1397
+
1398
+ impl From<workflow_commands::StartTimer> for command::Attributes {
1399
+ fn from(s: workflow_commands::StartTimer) -> Self {
1400
+ Self::StartTimerCommandAttributes(StartTimerCommandAttributes {
1401
+ timer_id: s.seq.to_string(),
1402
+ start_to_fire_timeout: s.start_to_fire_timeout,
1403
+ })
1404
+ }
1405
+ }
1406
+
1407
+ impl From<workflow_commands::UpsertWorkflowSearchAttributes> for command::Attributes {
1408
+ fn from(s: workflow_commands::UpsertWorkflowSearchAttributes) -> Self {
1409
+ Self::UpsertWorkflowSearchAttributesCommandAttributes(
1410
+ UpsertWorkflowSearchAttributesCommandAttributes {
1411
+ search_attributes: Some(s.search_attributes.into()),
1412
+ },
1413
+ )
1414
+ }
1415
+ }
1416
+
1417
+ impl From<workflow_commands::CancelTimer> for command::Attributes {
1418
+ fn from(s: workflow_commands::CancelTimer) -> Self {
1419
+ Self::CancelTimerCommandAttributes(CancelTimerCommandAttributes {
1420
+ timer_id: s.seq.to_string(),
1421
+ })
1422
+ }
1423
+ }
1424
+
1425
+ impl From<workflow_commands::ScheduleActivity> for command::Attributes {
1426
+ fn from(s: workflow_commands::ScheduleActivity) -> Self {
1427
+ Self::ScheduleActivityTaskCommandAttributes(
1428
+ ScheduleActivityTaskCommandAttributes {
1429
+ activity_id: s.activity_id,
1430
+ activity_type: Some(ActivityType {
1431
+ name: s.activity_type,
1432
+ }),
1433
+ task_queue: Some(s.task_queue.into()),
1434
+ header: Some(s.headers.into()),
1435
+ input: s.arguments.into_payloads(),
1436
+ schedule_to_close_timeout: s.schedule_to_close_timeout,
1437
+ schedule_to_start_timeout: s.schedule_to_start_timeout,
1438
+ start_to_close_timeout: s.start_to_close_timeout,
1439
+ heartbeat_timeout: s.heartbeat_timeout,
1440
+ retry_policy: s.retry_policy.map(Into::into),
1441
+ request_eager_execution: !s.do_not_eagerly_execute,
1442
+ },
1443
+ )
1444
+ }
1445
+ }
1446
+
1447
+ impl From<workflow_commands::StartChildWorkflowExecution> for command::Attributes {
1448
+ fn from(s: workflow_commands::StartChildWorkflowExecution) -> Self {
1449
+ Self::StartChildWorkflowExecutionCommandAttributes(
1450
+ StartChildWorkflowExecutionCommandAttributes {
1451
+ workflow_id: s.workflow_id,
1452
+ workflow_type: Some(WorkflowType {
1453
+ name: s.workflow_type,
1454
+ }),
1455
+ control: "".into(),
1456
+ namespace: s.namespace,
1457
+ task_queue: Some(s.task_queue.into()),
1458
+ header: Some(s.headers.into()),
1459
+ memo: Some(s.memo.into()),
1460
+ search_attributes: Some(s.search_attributes.into()),
1461
+ input: s.input.into_payloads(),
1462
+ workflow_id_reuse_policy: s.workflow_id_reuse_policy,
1463
+ workflow_execution_timeout: s.workflow_execution_timeout,
1464
+ workflow_run_timeout: s.workflow_run_timeout,
1465
+ workflow_task_timeout: s.workflow_task_timeout,
1466
+ retry_policy: s.retry_policy.map(Into::into),
1467
+ cron_schedule: s.cron_schedule.clone(),
1468
+ parent_close_policy: s.parent_close_policy,
1469
+ },
1470
+ )
1471
+ }
1472
+ }
1473
+
1474
+ impl From<workflow_commands::CompleteWorkflowExecution> for command::Attributes {
1475
+ fn from(c: workflow_commands::CompleteWorkflowExecution) -> Self {
1476
+ Self::CompleteWorkflowExecutionCommandAttributes(
1477
+ CompleteWorkflowExecutionCommandAttributes {
1478
+ result: c.result.map(Into::into),
1479
+ },
1480
+ )
1481
+ }
1482
+ }
1483
+
1484
+ impl From<workflow_commands::FailWorkflowExecution> for command::Attributes {
1485
+ fn from(c: workflow_commands::FailWorkflowExecution) -> Self {
1486
+ Self::FailWorkflowExecutionCommandAttributes(
1487
+ FailWorkflowExecutionCommandAttributes {
1488
+ failure: c.failure.map(Into::into),
1489
+ },
1490
+ )
1491
+ }
1492
+ }
1493
+
1494
+ impl From<workflow_commands::ContinueAsNewWorkflowExecution> for command::Attributes {
1495
+ fn from(c: workflow_commands::ContinueAsNewWorkflowExecution) -> Self {
1496
+ Self::ContinueAsNewWorkflowExecutionCommandAttributes(
1497
+ ContinueAsNewWorkflowExecutionCommandAttributes {
1498
+ workflow_type: Some(c.workflow_type.into()),
1499
+ task_queue: Some(c.task_queue.into()),
1500
+ input: c.arguments.into_payloads(),
1501
+ workflow_run_timeout: c.workflow_run_timeout,
1502
+ workflow_task_timeout: c.workflow_task_timeout,
1503
+ memo: if c.memo.is_empty() {
1504
+ None
1505
+ } else {
1506
+ Some(c.memo.into())
1507
+ },
1508
+ header: if c.headers.is_empty() {
1509
+ None
1510
+ } else {
1511
+ Some(c.headers.into())
1512
+ },
1513
+ retry_policy: c.retry_policy,
1514
+ search_attributes: if c.search_attributes.is_empty() {
1515
+ None
1516
+ } else {
1517
+ Some(c.search_attributes.into())
1518
+ },
1519
+ ..Default::default()
1520
+ },
1521
+ )
1522
+ }
1523
+ }
1524
+
1525
+ impl From<workflow_commands::CancelWorkflowExecution> for command::Attributes {
1526
+ fn from(_c: workflow_commands::CancelWorkflowExecution) -> Self {
1527
+ Self::CancelWorkflowExecutionCommandAttributes(
1528
+ CancelWorkflowExecutionCommandAttributes { details: None },
1529
+ )
1530
+ }
1531
+ }
1532
+ }
1533
+ }
1534
+ pub mod common {
1535
+ pub mod v1 {
1536
+ use std::{
1537
+ collections::HashMap,
1538
+ fmt::{Display, Formatter},
1539
+ };
1540
+ tonic::include_proto!("temporal.api.common.v1");
1541
+
1542
+ impl<T> From<T> for Payload
1543
+ where
1544
+ T: AsRef<[u8]>,
1545
+ {
1546
+ fn from(v: T) -> Self {
1547
+ // TODO: Set better encodings, whole data converter deal. Setting anything
1548
+ // for now at least makes it show up in the web UI.
1549
+ let mut metadata = HashMap::new();
1550
+ metadata.insert("encoding".to_string(), b"binary/plain".to_vec());
1551
+ Self {
1552
+ metadata,
1553
+ data: v.as_ref().to_vec(),
1554
+ }
1555
+ }
1556
+ }
1557
+
1558
+ impl Payload {
1559
+ // Is its own function b/c asref causes implementation conflicts
1560
+ pub fn as_slice(&self) -> &[u8] {
1561
+ self.data.as_slice()
1562
+ }
1563
+ }
1564
+
1565
+ impl Display for Payload {
1566
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1567
+ if self.data.len() > 64 {
1568
+ let mut windows = self.data.as_slice().windows(32);
1569
+ write!(
1570
+ f,
1571
+ "[{}..{}]",
1572
+ base64::encode(windows.next().unwrap_or_default()),
1573
+ base64::encode(windows.next_back().unwrap_or_default())
1574
+ )
1575
+ } else {
1576
+ write!(f, "[{}]", base64::encode(&self.data))
1577
+ }
1578
+ }
1579
+ }
1580
+
1581
+ impl Display for Header {
1582
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1583
+ write!(f, "Header(")?;
1584
+ for kv in &self.fields {
1585
+ write!(f, "{}: ", kv.0)?;
1586
+ write!(f, "{}, ", kv.1)?;
1587
+ }
1588
+ write!(f, ")")
1589
+ }
1590
+ }
1591
+
1592
+ impl From<Header> for HashMap<String, Payload> {
1593
+ fn from(h: Header) -> Self {
1594
+ h.fields.into_iter().map(|(k, v)| (k, v.into())).collect()
1595
+ }
1596
+ }
1597
+
1598
+ impl From<Memo> for HashMap<String, Payload> {
1599
+ fn from(h: Memo) -> Self {
1600
+ h.fields.into_iter().map(|(k, v)| (k, v.into())).collect()
1601
+ }
1602
+ }
1603
+
1604
+ impl From<SearchAttributes> for HashMap<String, Payload> {
1605
+ fn from(h: SearchAttributes) -> Self {
1606
+ h.indexed_fields
1607
+ .into_iter()
1608
+ .map(|(k, v)| (k, v.into()))
1609
+ .collect()
1610
+ }
1611
+ }
1612
+
1613
+ impl From<HashMap<String, Payload>> for SearchAttributes {
1614
+ fn from(h: HashMap<String, Payload>) -> Self {
1615
+ Self {
1616
+ indexed_fields: h.into_iter().map(|(k, v)| (k, v.into())).collect(),
1617
+ }
1618
+ }
1619
+ }
1620
+ }
1621
+ }
1622
+ pub mod enums {
1623
+ pub mod v1 {
1624
+ tonic::include_proto!("temporal.api.enums.v1");
1625
+ }
1626
+ }
1627
+ pub mod failure {
1628
+ pub mod v1 {
1629
+ tonic::include_proto!("temporal.api.failure.v1");
1630
+ }
1631
+ }
1632
+ pub mod filter {
1633
+ pub mod v1 {
1634
+ tonic::include_proto!("temporal.api.filter.v1");
1635
+ }
1636
+ }
1637
+ pub mod history {
1638
+ pub mod v1 {
1639
+ use crate::temporal::api::{
1640
+ enums::v1::EventType, history::v1::history_event::Attributes,
1641
+ };
1642
+ use anyhow::bail;
1643
+ use prost::alloc::fmt::Formatter;
1644
+ use std::fmt::Display;
1645
+
1646
+ tonic::include_proto!("temporal.api.history.v1");
1647
+
1648
+ impl History {
1649
+ pub fn extract_run_id_from_start(&self) -> Result<&str, anyhow::Error> {
1650
+ if let Some(
1651
+ history_event::Attributes::WorkflowExecutionStartedEventAttributes(wes),
1652
+ ) = self.events.get(0).and_then(|x| x.attributes.as_ref())
1653
+ {
1654
+ Ok(&wes.original_execution_run_id)
1655
+ } else {
1656
+ bail!("First event is not WorkflowExecutionStarted?!?")
1657
+ }
1658
+ }
1659
+
1660
+ /// Returns the event id of the final event in the history. Will return 0 if
1661
+ /// there are no events.
1662
+ pub fn last_event_id(&self) -> i64 {
1663
+ self.events.last().map(|e| e.event_id).unwrap_or_default()
1664
+ }
1665
+ }
1666
+
1667
+ impl HistoryEvent {
1668
+ /// Returns true if this is an event created to mirror a command
1669
+ pub fn is_command_event(&self) -> bool {
1670
+ EventType::from_i32(self.event_type).map_or(false, |et| match et {
1671
+ EventType::ActivityTaskScheduled
1672
+ | EventType::ActivityTaskCancelRequested
1673
+ | EventType::MarkerRecorded
1674
+ | EventType::RequestCancelExternalWorkflowExecutionInitiated
1675
+ | EventType::SignalExternalWorkflowExecutionInitiated
1676
+ | EventType::StartChildWorkflowExecutionInitiated
1677
+ | EventType::TimerCanceled
1678
+ | EventType::TimerStarted
1679
+ | EventType::UpsertWorkflowSearchAttributes
1680
+ | EventType::WorkflowExecutionCanceled
1681
+ | EventType::WorkflowExecutionCompleted
1682
+ | EventType::WorkflowExecutionContinuedAsNew
1683
+ | EventType::WorkflowExecutionFailed => true,
1684
+ _ => false,
1685
+ })
1686
+ }
1687
+
1688
+ /// Returns the command's initiating event id, if present. This is the id of the
1689
+ /// event which "started" the command. Usually, the "scheduled" event for the
1690
+ /// command.
1691
+ pub fn get_initial_command_event_id(&self) -> Option<i64> {
1692
+ self.attributes.as_ref().and_then(|a| {
1693
+ // Fun! Not really any way to make this better w/o incompatibly changing
1694
+ // protos.
1695
+ match a {
1696
+ Attributes::ActivityTaskStartedEventAttributes(a) =>
1697
+ Some(a.scheduled_event_id),
1698
+ Attributes::ActivityTaskCompletedEventAttributes(a) =>
1699
+ Some(a.scheduled_event_id),
1700
+ Attributes::ActivityTaskFailedEventAttributes(a) => Some(a.scheduled_event_id),
1701
+ Attributes::ActivityTaskTimedOutEventAttributes(a) => Some(a.scheduled_event_id),
1702
+ Attributes::ActivityTaskCancelRequestedEventAttributes(a) => Some(a.scheduled_event_id),
1703
+ Attributes::ActivityTaskCanceledEventAttributes(a) => Some(a.scheduled_event_id),
1704
+ Attributes::TimerFiredEventAttributes(a) => Some(a.started_event_id),
1705
+ Attributes::TimerCanceledEventAttributes(a) => Some(a.started_event_id),
1706
+ Attributes::RequestCancelExternalWorkflowExecutionFailedEventAttributes(a) => Some(a.initiated_event_id),
1707
+ Attributes::ExternalWorkflowExecutionCancelRequestedEventAttributes(a) => Some(a.initiated_event_id),
1708
+ Attributes::StartChildWorkflowExecutionFailedEventAttributes(a) => Some(a.initiated_event_id),
1709
+ Attributes::ChildWorkflowExecutionStartedEventAttributes(a) => Some(a.initiated_event_id),
1710
+ Attributes::ChildWorkflowExecutionCompletedEventAttributes(a) => Some(a.initiated_event_id),
1711
+ Attributes::ChildWorkflowExecutionFailedEventAttributes(a) => Some(a.initiated_event_id),
1712
+ Attributes::ChildWorkflowExecutionCanceledEventAttributes(a) => Some(a.initiated_event_id),
1713
+ Attributes::ChildWorkflowExecutionTimedOutEventAttributes(a) => Some(a.initiated_event_id),
1714
+ Attributes::ChildWorkflowExecutionTerminatedEventAttributes(a) => Some(a.initiated_event_id),
1715
+ Attributes::SignalExternalWorkflowExecutionFailedEventAttributes(a) => Some(a.initiated_event_id),
1716
+ Attributes::ExternalWorkflowExecutionSignaledEventAttributes(a) => Some(a.initiated_event_id),
1717
+ Attributes::WorkflowTaskStartedEventAttributes(a) => Some(a.scheduled_event_id),
1718
+ Attributes::WorkflowTaskCompletedEventAttributes(a) => Some(a.scheduled_event_id),
1719
+ Attributes::WorkflowTaskTimedOutEventAttributes(a) => Some(a.scheduled_event_id),
1720
+ Attributes::WorkflowTaskFailedEventAttributes(a) => Some(a.scheduled_event_id),
1721
+ _ => None
1722
+ }
1723
+ })
1724
+ }
1725
+
1726
+ /// Returns true if the event is one which would end a workflow
1727
+ pub fn is_final_wf_execution_event(&self) -> bool {
1728
+ match self.event_type() {
1729
+ EventType::WorkflowExecutionCompleted => true,
1730
+ EventType::WorkflowExecutionCanceled => true,
1731
+ EventType::WorkflowExecutionFailed => true,
1732
+ EventType::WorkflowExecutionTimedOut => true,
1733
+ EventType::WorkflowExecutionContinuedAsNew => true,
1734
+ EventType::WorkflowExecutionTerminated => true,
1735
+ _ => false,
1736
+ }
1737
+ }
1738
+ }
1739
+
1740
+ impl Display for HistoryEvent {
1741
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1742
+ write!(
1743
+ f,
1744
+ "HistoryEvent(id: {}, {:?})",
1745
+ self.event_id,
1746
+ EventType::from_i32(self.event_type)
1747
+ )
1748
+ }
1749
+ }
1750
+ }
1751
+ }
1752
+ pub mod namespace {
1753
+ pub mod v1 {
1754
+ tonic::include_proto!("temporal.api.namespace.v1");
1755
+ }
1756
+ }
1757
+ pub mod operatorservice {
1758
+ pub mod v1 {
1759
+ tonic::include_proto!("temporal.api.operatorservice.v1");
1760
+ }
1761
+ }
1762
+ pub mod query {
1763
+ pub mod v1 {
1764
+ tonic::include_proto!("temporal.api.query.v1");
1765
+ }
1766
+ }
1767
+ pub mod replication {
1768
+ pub mod v1 {
1769
+ tonic::include_proto!("temporal.api.replication.v1");
1770
+ }
1771
+ }
1772
+ pub mod schedule {
1773
+ pub mod v1 {
1774
+ tonic::include_proto!("temporal.api.schedule.v1");
1775
+ }
1776
+ }
1777
+ pub mod taskqueue {
1778
+ pub mod v1 {
1779
+ use crate::temporal::api::enums::v1::TaskQueueKind;
1780
+ tonic::include_proto!("temporal.api.taskqueue.v1");
1781
+
1782
+ impl From<String> for TaskQueue {
1783
+ fn from(name: String) -> Self {
1784
+ Self {
1785
+ name,
1786
+ kind: TaskQueueKind::Normal as i32,
1787
+ }
1788
+ }
1789
+ }
1790
+ }
1791
+ }
1792
+ pub mod testservice {
1793
+ pub mod v1 {
1794
+ tonic::include_proto!("temporal.api.testservice.v1");
1795
+ }
1796
+ }
1797
+ pub mod update {
1798
+ pub mod v1 {
1799
+ tonic::include_proto!("temporal.api.update.v1");
1800
+ }
1801
+ }
1802
+ pub mod version {
1803
+ pub mod v1 {
1804
+ tonic::include_proto!("temporal.api.version.v1");
1805
+ }
1806
+ }
1807
+ pub mod workflow {
1808
+ pub mod v1 {
1809
+ tonic::include_proto!("temporal.api.workflow.v1");
1810
+ }
1811
+ }
1812
+ pub mod workflowservice {
1813
+ pub mod v1 {
1814
+ use std::{
1815
+ convert::TryInto,
1816
+ fmt::{Display, Formatter},
1817
+ time::{Duration, SystemTime},
1818
+ };
1819
+
1820
+ tonic::include_proto!("temporal.api.workflowservice.v1");
1821
+
1822
+ macro_rules! sched_to_start_impl {
1823
+ () => {
1824
+ /// Return the duration of the task schedule time to its start time if both
1825
+ /// are set and time went forward.
1826
+ pub fn sched_to_start(&self) -> Option<Duration> {
1827
+ if let Some((sch, st)) =
1828
+ self.scheduled_time.clone().zip(self.started_time.clone())
1829
+ {
1830
+ let sch: Result<SystemTime, _> = sch.try_into();
1831
+ let st: Result<SystemTime, _> = st.try_into();
1832
+ if let (Ok(sch), Ok(st)) = (sch, st) {
1833
+ return st.duration_since(sch).ok();
1834
+ }
1835
+ }
1836
+ None
1837
+ }
1838
+ };
1839
+ }
1840
+
1841
+ impl PollWorkflowTaskQueueResponse {
1842
+ sched_to_start_impl!();
1843
+ }
1844
+
1845
+ impl Display for PollWorkflowTaskQueueResponse {
1846
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1847
+ let last_event = self
1848
+ .history
1849
+ .as_ref()
1850
+ .and_then(|h| h.events.last().map(|he| he.event_id))
1851
+ .unwrap_or(0);
1852
+ write!(
1853
+ f,
1854
+ "PollWFTQResp(run_id: {}, attempt: {}, last_event: {})",
1855
+ self.workflow_execution
1856
+ .as_ref()
1857
+ .map_or("", |we| we.run_id.as_str()),
1858
+ self.attempt,
1859
+ last_event
1860
+ )
1861
+ }
1862
+ }
1863
+
1864
+ /// Can be used while debugging to avoid filling up a whole screen with poll resps
1865
+ pub struct CompactHist<'a>(pub &'a PollWorkflowTaskQueueResponse);
1866
+ impl Display for CompactHist<'_> {
1867
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1868
+ writeln!(
1869
+ f,
1870
+ "PollWorkflowTaskQueueResponse (prev_started: {}, started: {})",
1871
+ self.0.previous_started_event_id, self.0.started_event_id
1872
+ )?;
1873
+ if let Some(h) = self.0.history.as_ref() {
1874
+ for event in &h.events {
1875
+ writeln!(f, "{}", event)?;
1876
+ }
1877
+ }
1878
+ writeln!(f, "query: {:#?}", self.0.query)?;
1879
+ writeln!(f, "queries: {:#?}", self.0.queries)
1880
+ }
1881
+ }
1882
+
1883
+ impl PollActivityTaskQueueResponse {
1884
+ sched_to_start_impl!();
1885
+ }
1886
+
1887
+ impl QueryWorkflowResponse {
1888
+ /// Unwrap a successful response as vec of payloads
1889
+ pub fn unwrap(self) -> Vec<crate::temporal::api::common::v1::Payload> {
1890
+ self.query_result.unwrap().payloads
1891
+ }
1892
+ }
1893
+ }
1894
+ }
1895
+ }
1896
+ }
1897
+
1898
+ #[allow(
1899
+ clippy::all,
1900
+ missing_docs,
1901
+ rustdoc::broken_intra_doc_links,
1902
+ rustdoc::bare_urls
1903
+ )]
1904
+ pub mod grpc {
1905
+ pub mod health {
1906
+ pub mod v1 {
1907
+ tonic::include_proto!("grpc.health.v1");
1908
+ }
1909
+ }
1910
+ }