temporalio 0.0.0 → 0.0.2

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 (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,26 @@
1
+ require 'temporalio/payload_converter/encoding_base'
2
+
3
+ module Temporalio
4
+ module PayloadConverter
5
+ # A payload converter for encoding/decoding nils.
6
+ class Nil < EncodingBase
7
+ ENCODING = 'binary/null'.freeze
8
+
9
+ def encoding
10
+ ENCODING
11
+ end
12
+
13
+ def from_payload(_payload)
14
+ nil
15
+ end
16
+
17
+ def to_payload(data)
18
+ return nil unless data.nil?
19
+
20
+ Temporalio::Api::Common::V1::Payload.new(
21
+ metadata: { 'encoding' => ENCODING },
22
+ )
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,14 @@
1
+ require 'temporalio/payload_converter/bytes'
2
+ require 'temporalio/payload_converter/composite'
3
+ require 'temporalio/payload_converter/json'
4
+ require 'temporalio/payload_converter/nil'
5
+
6
+ module Temporalio
7
+ module PayloadConverter
8
+ DEFAULT = Temporalio::PayloadConverter::Composite.new(
9
+ Temporalio::PayloadConverter::Nil.new,
10
+ Temporalio::PayloadConverter::Bytes.new,
11
+ Temporalio::PayloadConverter::JSON.new,
12
+ )
13
+ end
14
+ end
@@ -0,0 +1,82 @@
1
+ require 'temporal/api/common/v1/message_pb'
2
+ require 'temporalio/errors'
3
+
4
+ module Temporalio
5
+ # Options for retrying workflows and activities.
6
+ #
7
+ # @see https://docs.temporal.io/application-development/features/#workflow-retry-policy
8
+ class RetryPolicy
9
+ class Invalid < Temporalio::Error; end
10
+
11
+ # @return [Integer] Backoff interval for the first retry.
12
+ attr_reader :initial_interval
13
+
14
+ # @return [Float] Coefficient to multiply previous backoff interval by to get new interval.
15
+ attr_reader :backoff
16
+
17
+ # @return [Integer, nil] Maximum backoff interval between retries. Default 100x
18
+ # {#initial_interval}.
19
+ attr_reader :max_interval
20
+
21
+ # @return [Integer] Maximum number of attempts. If 0, the default, there is no maximum.
22
+ attr_reader :max_attempts
23
+
24
+ # @return [Array<String>] List of error types that are not retryable.
25
+ attr_reader :non_retriable_errors
26
+
27
+ # @param initial_interval [Integer] Backoff interval (in seconds) for the first retry.
28
+ # @param backoff [Float] Coefficient to multiply previous backoff interval by to get new
29
+ # interval.
30
+ # @param max_interval [Integer] Maximum backoff interval between retries. Default 100x
31
+ # {#initial_interval}.
32
+ # @param max_attempts [Integer] Maximum number of attempts. If 0, there is no maximum.
33
+ # @param non_retriable_errors [Array<String>] List of error types that are not retryable.
34
+ def initialize(
35
+ initial_interval: 1,
36
+ backoff: 2.0,
37
+ max_interval: nil,
38
+ max_attempts: 0,
39
+ non_retriable_errors: []
40
+ )
41
+ @initial_interval = initial_interval
42
+ @backoff = backoff
43
+ @max_interval = max_interval
44
+ @max_attempts = max_attempts
45
+ @non_retriable_errors = non_retriable_errors
46
+ end
47
+
48
+ def validate!
49
+ # Retries disabled
50
+ return if max_attempts == 1
51
+
52
+ # Maximum attempts
53
+ raise Invalid, 'Maximum attempts must be specified' unless max_attempts
54
+ raise Invalid, 'Maximum attempts cannot be negative' if max_attempts.negative?
55
+
56
+ # Initial interval
57
+ raise Invalid, 'Initial interval must be specified' unless initial_interval
58
+ raise Invalid, 'Initial interval cannot be negative' if initial_interval.negative?
59
+ raise Invalid, 'Initial interval must be in whole seconds' unless initial_interval.is_a?(Integer)
60
+
61
+ # Backoff coefficient
62
+ raise Invalid, 'Backoff coefficient must be specified' unless backoff
63
+ raise Invalid, 'Backoff coefficient cannot be less than 1' if backoff < 1
64
+
65
+ # Maximum interval
66
+ if max_interval
67
+ raise Invalid, 'Maximum interval cannot be negative' if max_interval.negative?
68
+ raise Invalid, 'Maximum interval cannot be less than initial interval' if max_interval < initial_interval
69
+ end
70
+ end
71
+
72
+ def to_proto
73
+ Temporalio::Api::Common::V1::RetryPolicy.new(
74
+ initial_interval: Google::Protobuf::Duration.new(seconds: initial_interval),
75
+ backoff_coefficient: backoff,
76
+ maximum_interval: max_interval ? Google::Protobuf::Duration.new(seconds: max_interval) : nil,
77
+ maximum_attempts: max_attempts,
78
+ non_retryable_error_types: non_retriable_errors.map(&:name).compact,
79
+ )
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,35 @@
1
+ module Temporalio
2
+ # Current retry state of the workflow/activity during error.
3
+ module RetryState
4
+ STATES = [
5
+ IN_PROGRESS = :IN_PROGRESS,
6
+ NON_RETRYABLE_FAILURE = :NON_RETRYABLE_FAILURE,
7
+ TIMEOUT = :TIMEOUT,
8
+ MAXIMUM_ATTEMPTS_REACHED = :MAXIMUM_ATTEMPTS_REACHED,
9
+ RETRY_POLICY_NOT_SET = :RETRY_POLICY_NOT_SET,
10
+ INTERNAL_SERVER_ERROR = :INTERNAL_SERVER_ERROR,
11
+ CANCEL_REQUESTED = :CANCEL_REQUESTED,
12
+ ].freeze
13
+
14
+ # RBS screws up style definitions when using .freeze
15
+ # rubocop:disable Style/MutableConstant
16
+ API_MAP = {
17
+ RETRY_STATE_IN_PROGRESS: IN_PROGRESS,
18
+ RETRY_STATE_NON_RETRYABLE_FAILURE: NON_RETRYABLE_FAILURE,
19
+ RETRY_STATE_TIMEOUT: TIMEOUT,
20
+ RETRY_STATE_MAXIMUM_ATTEMPTS_REACHED: MAXIMUM_ATTEMPTS_REACHED,
21
+ RETRY_STATE_RETRY_POLICY_NOT_SET: RETRY_POLICY_NOT_SET,
22
+ RETRY_STATE_INTERNAL_SERVER_ERROR: INTERNAL_SERVER_ERROR,
23
+ RETRY_STATE_CANCEL_REQUESTED: CANCEL_REQUESTED,
24
+ }
25
+ # rubocop:enable Style/MutableConstant
26
+
27
+ def self.to_raw(state)
28
+ API_MAP.invert[state] || :RETRY_STATE_UNSPECIFIED
29
+ end
30
+
31
+ def self.from_raw(raw_state)
32
+ API_MAP[raw_state]
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,25 @@
1
+ require 'singleton'
2
+ require 'temporalio/bridge'
3
+ require 'temporalio/worker/reactor'
4
+
5
+ module Temporalio
6
+ # @api private
7
+ class Runtime
8
+ include Singleton
9
+
10
+ attr_reader :core_runtime, :reactor
11
+
12
+ def initialize
13
+ @core_runtime = Temporalio::Bridge::Runtime.init
14
+ @reactor = Temporalio::Worker::Reactor.new
15
+ end
16
+
17
+ def ensure_callback_loop
18
+ return if @thread
19
+
20
+ @thread = Thread.new do
21
+ core_runtime.run_callback_loop
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,29 @@
1
+ module Temporalio
2
+ # Type of timeout for {Temporalio::TimeoutError}.
3
+ module TimeoutType
4
+ TYPES = [
5
+ START_TO_CLOSE = :START_TO_CLOSE,
6
+ SCHEDULE_TO_START = :SCHEDULE_TO_START,
7
+ SCHEDULE_TO_CLOSE = :SCHEDULE_TO_CLOSE,
8
+ HEARTBEAT = :HEARTBEAT,
9
+ ].freeze
10
+
11
+ # RBS screws up style definitions when using .freeze
12
+ # rubocop:disable Style/MutableConstant
13
+ API_MAP = {
14
+ TIMEOUT_TYPE_START_TO_CLOSE: START_TO_CLOSE,
15
+ TIMEOUT_TYPE_SCHEDULE_TO_START: SCHEDULE_TO_START,
16
+ TIMEOUT_TYPE_SCHEDULE_TO_CLOSE: SCHEDULE_TO_CLOSE,
17
+ TIMEOUT_TYPE_HEARTBEAT: HEARTBEAT,
18
+ }
19
+ # rubocop:enable Style/MutableConstant
20
+
21
+ def self.to_raw(type)
22
+ API_MAP.invert[type] || :TIMEOUT_TYPE_UNSPECIFIED
23
+ end
24
+
25
+ def self.from_raw(raw_type)
26
+ API_MAP[raw_type]
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,3 @@
1
+ module Temporalio
2
+ VERSION = '0.0.2'.freeze
3
+ end
@@ -0,0 +1,92 @@
1
+ require 'google/protobuf/well_known_types'
2
+ require 'temporalio/activity/context'
3
+ require 'temporalio/activity/info'
4
+ require 'temporalio/error/failure'
5
+ require 'temporalio/errors'
6
+
7
+ module Temporalio
8
+ class Worker
9
+ # The main class for handling activity processing. It is expected to be executed from
10
+ # some threaded or async executor's context since methods called here might be blocking
11
+ # and this should not affect the main worker reactor.
12
+ #
13
+ # @api private
14
+ class ActivityRunner
15
+ def initialize(activity_class, start, task_queue, task_token, worker, converter)
16
+ @activity_class = activity_class
17
+ @start = start
18
+ @task_queue = task_queue
19
+ @task_token = task_token
20
+ @worker = worker
21
+ @converter = converter
22
+ end
23
+
24
+ def run
25
+ activity = activity_class.new(context)
26
+ input = converter.from_payload_array(start.input.to_a)
27
+
28
+ result = activity.execute(*input)
29
+
30
+ converter.to_payload(result)
31
+ rescue StandardError => e
32
+ # Temporal server ignores cancellation failures that were not requested by the server.
33
+ # However within the SDK cancellations are also used during the worker shutdown. In order
34
+ # to provide a seamless handling experience (same error raised within the Activity) we are
35
+ # using the ActivityCancelled error and then swapping it with a CancelledError here.
36
+ #
37
+ # In the future this will be handled by the SDK Core — https://github.com/temporalio/sdk-core/issues/461
38
+ if e.is_a?(Temporalio::Error::ActivityCancelled) && e.by_request?
39
+ e = Temporalio::Error::CancelledError.new(e.message)
40
+ end
41
+
42
+ converter.to_failure(e)
43
+ end
44
+
45
+ def cancel(reason, by_request:)
46
+ context.cancel(reason, by_request: by_request)
47
+ end
48
+
49
+ private
50
+
51
+ attr_reader :activity_class, :start, :task_queue, :task_token, :worker, :converter
52
+
53
+ def context
54
+ return @context if @context
55
+
56
+ heartbeat_proc = ->(*details) { heartbeat(*details) }
57
+ @context = Temporalio::Activity::Context.new(
58
+ generate_activity_info,
59
+ heartbeat_proc,
60
+ shielded: activity_class._shielded,
61
+ )
62
+ end
63
+
64
+ def generate_activity_info
65
+ Temporalio::Activity::Info.new(
66
+ activity_id: start.activity_id,
67
+ activity_type: start.activity_type,
68
+ attempt: start.attempt,
69
+ current_attempt_scheduled_time: start.current_attempt_scheduled_time&.to_time,
70
+ heartbeat_details: converter.from_payload_array(start.heartbeat_details.to_a),
71
+ heartbeat_timeout: start.heartbeat_timeout&.to_f,
72
+ local: !start.is_local.nil?,
73
+ schedule_to_close_timeout: start.schedule_to_close_timeout&.to_f,
74
+ scheduled_time: start.scheduled_time&.to_time,
75
+ start_to_close_timeout: start.start_to_close_timeout&.to_f,
76
+ started_time: start.started_time&.to_time,
77
+ task_queue: task_queue,
78
+ task_token: task_token,
79
+ workflow_id: start.workflow_execution&.workflow_id,
80
+ workflow_namespace: start.workflow_namespace,
81
+ workflow_run_id: start.workflow_execution&.run_id,
82
+ workflow_type: start.workflow_type,
83
+ ).freeze
84
+ end
85
+
86
+ def heartbeat(*details)
87
+ payloads = converter.to_payload_array(details)
88
+ worker.record_activity_heartbeat(task_token, payloads)
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,138 @@
1
+ require 'temporalio/error/failure'
2
+ require 'temporalio/errors'
3
+ require 'temporalio/worker/activity_runner'
4
+ require 'temporalio/worker/sync_worker'
5
+
6
+ module Temporalio
7
+ class Worker
8
+ # @api private
9
+ class ActivityWorker
10
+ def initialize(task_queue, core_worker, activities, converter, executor, graceful_timeout)
11
+ @task_queue = task_queue
12
+ @worker = SyncWorker.new(core_worker)
13
+ @activities = prepare_activities(activities)
14
+ @converter = converter
15
+ @executor = executor
16
+ @graceful_timeout = graceful_timeout
17
+ @running_activities = {}
18
+ @cancellations = []
19
+ @drain_queue = Queue.new
20
+ end
21
+
22
+ def run(reactor)
23
+ # @type var outstanding_tasks: Array[Async::Task]
24
+ outstanding_tasks = []
25
+
26
+ loop do
27
+ activity_task = worker.poll_activity_task
28
+ outstanding_tasks << reactor.async do |async_task|
29
+ if activity_task.start
30
+ handle_start_activity(activity_task.task_token, activity_task.start)
31
+ elsif activity_task.cancel
32
+ handle_cancel_activity(activity_task.task_token, activity_task.cancel)
33
+ end
34
+ ensure
35
+ outstanding_tasks.delete(async_task)
36
+ end
37
+ end
38
+ rescue Temporalio::Bridge::Error::WorkerShutdown
39
+ # No need to re-raise this error, it's a part of a normal shutdown
40
+ ensure
41
+ reactor.async do |async_task|
42
+ cancelation_task =
43
+ if graceful_timeout
44
+ async_task.async do
45
+ sleep graceful_timeout
46
+ running_activities.each_value do |activity_runner|
47
+ activity_runner.cancel('Worker is shutting down', by_request: false)
48
+ end
49
+ end
50
+ end
51
+
52
+ outstanding_tasks.each(&:wait)
53
+ cancelation_task&.stop # all tasks completed, stop cancellations
54
+ drain_queue.close
55
+ end
56
+ end
57
+
58
+ def drain
59
+ drain_queue.pop
60
+ end
61
+
62
+ private
63
+
64
+ attr_reader :task_queue, :worker, :activities, :converter, :executor, :graceful_timeout,
65
+ :running_activities, :cancellations, :drain_queue
66
+
67
+ def prepare_activities(activities)
68
+ activities.each_with_object({}) do |activity, result|
69
+ unless activity.ancestors.include?(Temporalio::Activity)
70
+ raise ArgumentError, 'Activity must be a subclass of Temporalio::Activity'
71
+ end
72
+
73
+ if result[activity._name]
74
+ raise ArgumentError, "More than one activity named #{activity._name}"
75
+ end
76
+
77
+ result[activity._name] = activity
78
+ result
79
+ end
80
+ end
81
+
82
+ def lookup_activity(activity_type)
83
+ activities.fetch(activity_type) do
84
+ activity_names = activities.keys.sort.join(', ')
85
+ raise Temporalio::Error::ApplicationError.new(
86
+ "Activity #{activity_type} is not registered on this worker, available activities: #{activity_names}",
87
+ type: 'NotFoundError',
88
+ )
89
+ end
90
+ end
91
+
92
+ def run_activity(token, start)
93
+ activity_class = lookup_activity(start.activity_type)
94
+ runner = ActivityRunner.new(activity_class, start, task_queue, token, worker, converter)
95
+ running_activities[token] = runner
96
+ queue = Queue.new
97
+
98
+ executor.schedule do
99
+ queue << runner.run
100
+ end
101
+
102
+ queue.pop
103
+ rescue StandardError => e
104
+ converter.to_failure(e)
105
+ end
106
+
107
+ def handle_start_activity(task_token, start)
108
+ result = run_activity(task_token, start)
109
+
110
+ case result
111
+ when Temporalio::Api::Common::V1::Payload
112
+ worker.complete_activity_task_with_success(task_token, result)
113
+ when Temporalio::Api::Failure::V1::Failure
114
+ # only respond with a cancellation when it was requested, otherwise it's a regular failure
115
+ if result.canceled_failure_info && cancellations.include?(task_token)
116
+ worker.complete_activity_task_with_cancellation(task_token, result)
117
+ else
118
+ worker.complete_activity_task_with_failure(task_token, result)
119
+ end
120
+ end
121
+
122
+ running_activities.delete(task_token)
123
+ cancellations.delete(task_token)
124
+ end
125
+
126
+ def handle_cancel_activity(task_token, _cancel)
127
+ runner = running_activities.fetch(task_token) do
128
+ # TODO: Use logger instead when implemented
129
+ warn "Cannot find activity to cancel for token #{task_token}"
130
+ return # early escape
131
+ end
132
+
133
+ cancellations << task_token
134
+ runner&.cancel('Activity cancellation requested', by_request: true)
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,46 @@
1
+ require 'async'
2
+
3
+ module Temporalio
4
+ class Worker
5
+ # A shared async reactor.
6
+ #
7
+ # This class allows multiple workers to access the same Async reactor
8
+ # without forcing the SDK users to wrap their execution in an Async block. This
9
+ # is handled using a queue that is polled from within a running Async reactor,
10
+ # so all the blocks end up being executed within it.
11
+ #
12
+ # @api private
13
+ class Reactor
14
+ def initialize
15
+ @queue = Queue.new
16
+ @thread = nil
17
+ @mutex = Mutex.new
18
+ end
19
+
20
+ def async(&block)
21
+ ensure_reactor_thread
22
+ queue << block
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :queue, :mutex
28
+
29
+ def ensure_reactor_thread
30
+ mutex.synchronize do
31
+ @thread ||= Thread.new { run_loop }
32
+ end
33
+ end
34
+
35
+ def run_loop
36
+ reactor = Async::Reactor.new
37
+ reactor.run do |task|
38
+ loop do
39
+ block = queue.pop
40
+ task.async { |subtask| block.call(subtask) }
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,63 @@
1
+ require 'temporalio/errors'
2
+
3
+ module Temporalio
4
+ class Worker
5
+ # A class used to manage the lifecycle of running any number of workers.
6
+ #
7
+ # @api private
8
+ class Runner
9
+ def initialize(*workers)
10
+ if workers.empty?
11
+ raise ArgumentError, 'Must be initialized with at least one worker'
12
+ end
13
+
14
+ @workers = workers
15
+ @mutex = Mutex.new
16
+ @started = false
17
+ @shutdown = false
18
+ end
19
+
20
+ def run(&block)
21
+ @thread = Thread.current
22
+ @started = true
23
+ workers.each { |worker| worker.start(self) }
24
+
25
+ block ? block.call : sleep
26
+ rescue Temporalio::Error::WorkerShutdown
27
+ # Explicit shutdown requested, no need to raise
28
+ ensure
29
+ @shutdown = true
30
+ shutdown_workers
31
+ end
32
+
33
+ def shutdown(exception = Temporalio::Error::WorkerShutdown.new('Manual shutdown'))
34
+ mutex.synchronize do
35
+ return unless running?
36
+
37
+ @shutdown = true
38
+ end
39
+
40
+ # propagate shutdown to the running thread
41
+ thread&.raise(exception)
42
+ end
43
+
44
+ private
45
+
46
+ attr_reader :workers, :mutex, :thread
47
+
48
+ def running?
49
+ @started && !@shutdown
50
+ end
51
+
52
+ def shutdown_workers
53
+ # Protect shutdown from any outside raises
54
+ Thread.handle_interrupt(StandardError => :never) do
55
+ workers.map do |worker|
56
+ # Shut down each worker (and wait for it) concurrently in separate threads
57
+ Thread.new { worker.shutdown }
58
+ end.each(&:join)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,88 @@
1
+ require 'temporal/sdk/core/activity_task/activity_task_pb'
2
+ require 'temporal/sdk/core/core_interface_pb'
3
+
4
+ module Temporalio
5
+ class Worker
6
+ # This is a wrapper class for the Core Worker (provided via the Bridge) to abstract
7
+ # away its async nature allowing other modules/classes to interact with it without
8
+ # any callbacks (simplifying the code).
9
+ #
10
+ # CAUTION: This class will block the thread its running in unless it is used from
11
+ # within an Async reactor.
12
+ #
13
+ # @api private
14
+ class SyncWorker
15
+ def initialize(core_worker)
16
+ @core_worker = core_worker
17
+ end
18
+
19
+ def poll_activity_task
20
+ with_queue do |done|
21
+ core_worker.poll_activity_task do |task, error|
22
+ done.call(task && Coresdk::ActivityTask::ActivityTask.decode(task), error)
23
+ end
24
+ end
25
+ end
26
+
27
+ def complete_activity_task_with_success(task_token, payload)
28
+ result = Coresdk::ActivityResult::ActivityExecutionResult.new(
29
+ completed: Coresdk::ActivityResult::Success.new(result: payload),
30
+ )
31
+
32
+ complete_activity_task(task_token, result)
33
+ end
34
+
35
+ def complete_activity_task_with_failure(task_token, failure)
36
+ result = Coresdk::ActivityResult::ActivityExecutionResult.new(
37
+ failed: Coresdk::ActivityResult::Failure.new(failure: failure),
38
+ )
39
+
40
+ complete_activity_task(task_token, result)
41
+ end
42
+
43
+ def complete_activity_task_with_cancellation(task_token, failure)
44
+ result = Coresdk::ActivityResult::ActivityExecutionResult.new(
45
+ cancelled: Coresdk::ActivityResult::Cancellation.new(failure: failure),
46
+ )
47
+
48
+ complete_activity_task(task_token, result)
49
+ end
50
+
51
+ def record_activity_heartbeat(task_token, payloads)
52
+ proto = Coresdk::ActivityHeartbeat.new(
53
+ task_token: task_token,
54
+ details: payloads,
55
+ )
56
+ encoded_proto = Coresdk::ActivityHeartbeat.encode(proto)
57
+
58
+ core_worker.record_activity_heartbeat(encoded_proto)
59
+ end
60
+
61
+ private
62
+
63
+ attr_reader :core_worker
64
+
65
+ def with_queue(&block)
66
+ queue = Queue.new
67
+ done = ->(result, error = nil) { queue << [result, error] }
68
+ block.call(done)
69
+ (result, exception) = queue.pop
70
+ raise exception if exception
71
+
72
+ result
73
+ end
74
+
75
+ def complete_activity_task(task_token, result)
76
+ proto = Coresdk::ActivityTaskCompletion.new(
77
+ task_token: task_token,
78
+ result: result,
79
+ )
80
+ encoded_proto = Coresdk::ActivityTaskCompletion.encode(proto)
81
+
82
+ with_queue do |done|
83
+ core_worker.complete_activity_task(encoded_proto, &done)
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end