temporalio 0.1.1 → 0.3.0

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 (628) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +2 -0
  3. data/Cargo.lock +4324 -0
  4. data/Cargo.toml +25 -0
  5. data/Gemfile +20 -0
  6. data/LICENSE +16 -15
  7. data/README.md +985 -183
  8. data/Rakefile +101 -0
  9. data/ext/Cargo.toml +26 -0
  10. data/lib/temporalio/activity/complete_async_error.rb +11 -0
  11. data/lib/temporalio/activity/context.rb +86 -78
  12. data/lib/temporalio/activity/definition.rb +175 -0
  13. data/lib/temporalio/activity/info.rb +44 -47
  14. data/lib/temporalio/activity.rb +8 -81
  15. data/lib/temporalio/api/activity/v1/message.rb +25 -0
  16. data/lib/temporalio/api/batch/v1/message.rb +31 -0
  17. data/lib/temporalio/api/cloud/account/v1/message.rb +28 -0
  18. data/lib/temporalio/api/cloud/cloudservice/v1/request_response.rb +126 -0
  19. data/lib/temporalio/api/cloud/cloudservice/v1/service.rb +25 -0
  20. data/lib/temporalio/api/cloud/cloudservice.rb +3 -0
  21. data/lib/temporalio/api/cloud/identity/v1/message.rb +41 -0
  22. data/lib/temporalio/api/cloud/namespace/v1/message.rb +42 -0
  23. data/lib/temporalio/api/cloud/nexus/v1/message.rb +31 -0
  24. data/lib/temporalio/api/cloud/operation/v1/message.rb +28 -0
  25. data/lib/temporalio/api/cloud/region/v1/message.rb +24 -0
  26. data/lib/temporalio/api/cloud/resource/v1/message.rb +23 -0
  27. data/lib/temporalio/api/cloud/sink/v1/message.rb +24 -0
  28. data/lib/temporalio/api/cloud/usage/v1/message.rb +31 -0
  29. data/lib/temporalio/api/command/v1/message.rb +46 -0
  30. data/lib/temporalio/api/common/v1/grpc_status.rb +23 -0
  31. data/lib/temporalio/api/common/v1/message.rb +47 -0
  32. data/lib/temporalio/api/enums/v1/batch_operation.rb +22 -0
  33. data/lib/temporalio/api/enums/v1/command_type.rb +21 -0
  34. data/lib/temporalio/api/enums/v1/common.rb +26 -0
  35. data/lib/temporalio/api/enums/v1/event_type.rb +21 -0
  36. data/lib/temporalio/api/enums/v1/failed_cause.rb +26 -0
  37. data/lib/temporalio/api/enums/v1/namespace.rb +23 -0
  38. data/lib/temporalio/api/enums/v1/query.rb +22 -0
  39. data/lib/temporalio/api/enums/v1/reset.rb +23 -0
  40. data/lib/temporalio/api/enums/v1/schedule.rb +21 -0
  41. data/lib/temporalio/api/enums/v1/task_queue.rb +25 -0
  42. data/lib/temporalio/api/enums/v1/update.rb +22 -0
  43. data/lib/temporalio/api/enums/v1/workflow.rb +30 -0
  44. data/lib/temporalio/api/errordetails/v1/message.rb +42 -0
  45. data/lib/temporalio/api/export/v1/message.rb +24 -0
  46. data/lib/temporalio/api/failure/v1/message.rb +35 -0
  47. data/lib/temporalio/api/filter/v1/message.rb +27 -0
  48. data/lib/temporalio/api/history/v1/message.rb +90 -0
  49. data/lib/temporalio/api/namespace/v1/message.rb +31 -0
  50. data/lib/temporalio/api/nexus/v1/message.rb +40 -0
  51. data/lib/temporalio/api/operatorservice/v1/request_response.rb +49 -0
  52. data/lib/temporalio/api/operatorservice/v1/service.rb +23 -0
  53. data/lib/temporalio/api/operatorservice.rb +3 -0
  54. data/lib/temporalio/api/payload_visitor.rb +1513 -0
  55. data/lib/temporalio/api/protocol/v1/message.rb +23 -0
  56. data/lib/temporalio/api/query/v1/message.rb +27 -0
  57. data/lib/temporalio/api/replication/v1/message.rb +26 -0
  58. data/lib/temporalio/api/schedule/v1/message.rb +43 -0
  59. data/lib/temporalio/api/sdk/v1/enhanced_stack_trace.rb +25 -0
  60. data/lib/temporalio/api/sdk/v1/task_complete_metadata.rb +21 -0
  61. data/lib/temporalio/api/sdk/v1/user_metadata.rb +23 -0
  62. data/lib/temporalio/api/sdk/v1/workflow_metadata.rb +23 -0
  63. data/lib/temporalio/api/taskqueue/v1/message.rb +45 -0
  64. data/lib/{gen/temporal/api/testservice/v1/request_response_pb.rb → temporalio/api/testservice/v1/request_response.rb} +6 -24
  65. data/lib/temporalio/api/testservice/v1/service.rb +23 -0
  66. data/lib/temporalio/api/update/v1/message.rb +33 -0
  67. data/lib/temporalio/api/version/v1/message.rb +26 -0
  68. data/lib/temporalio/api/workflow/v1/message.rb +43 -0
  69. data/lib/temporalio/api/workflowservice/v1/request_response.rb +204 -0
  70. data/lib/temporalio/api/workflowservice/v1/service.rb +23 -0
  71. data/lib/temporalio/api/workflowservice.rb +3 -0
  72. data/lib/temporalio/api.rb +14 -0
  73. data/lib/temporalio/cancellation.rb +170 -0
  74. data/lib/temporalio/client/activity_id_reference.rb +32 -0
  75. data/lib/temporalio/client/async_activity_handle.rb +85 -0
  76. data/lib/temporalio/client/connection/cloud_service.rb +726 -0
  77. data/lib/temporalio/client/connection/operator_service.rb +201 -0
  78. data/lib/temporalio/client/connection/service.rb +42 -0
  79. data/lib/temporalio/client/connection/test_service.rb +111 -0
  80. data/lib/temporalio/client/connection/workflow_service.rb +1041 -0
  81. data/lib/temporalio/client/connection.rb +316 -0
  82. data/lib/temporalio/client/interceptor.rb +416 -0
  83. data/lib/temporalio/client/schedule.rb +967 -0
  84. data/lib/temporalio/client/schedule_handle.rb +126 -0
  85. data/lib/temporalio/client/workflow_execution.rb +100 -0
  86. data/lib/temporalio/client/workflow_execution_count.rb +36 -0
  87. data/lib/temporalio/client/workflow_execution_status.rb +18 -0
  88. data/lib/temporalio/client/workflow_handle.rb +326 -180
  89. data/lib/temporalio/client/workflow_query_reject_condition.rb +14 -0
  90. data/lib/temporalio/client/workflow_update_handle.rb +65 -0
  91. data/lib/temporalio/client/workflow_update_wait_stage.rb +17 -0
  92. data/lib/temporalio/client.rb +447 -94
  93. data/lib/temporalio/common_enums.rb +41 -0
  94. data/lib/temporalio/converters/data_converter.rb +99 -0
  95. data/lib/temporalio/converters/failure_converter.rb +202 -0
  96. data/lib/temporalio/converters/payload_codec.rb +26 -0
  97. data/lib/temporalio/converters/payload_converter/binary_null.rb +34 -0
  98. data/lib/temporalio/converters/payload_converter/binary_plain.rb +35 -0
  99. data/lib/temporalio/converters/payload_converter/binary_protobuf.rb +42 -0
  100. data/lib/temporalio/converters/payload_converter/composite.rb +66 -0
  101. data/lib/temporalio/converters/payload_converter/encoding.rb +35 -0
  102. data/lib/temporalio/converters/payload_converter/json_plain.rb +44 -0
  103. data/lib/temporalio/converters/payload_converter/json_protobuf.rb +41 -0
  104. data/lib/temporalio/converters/payload_converter.rb +71 -0
  105. data/lib/temporalio/converters/raw_value.rb +20 -0
  106. data/lib/temporalio/converters.rb +9 -0
  107. data/lib/temporalio/error/failure.rb +119 -94
  108. data/lib/temporalio/error.rb +155 -0
  109. data/lib/temporalio/internal/bridge/api/activity_result/activity_result.rb +34 -0
  110. data/lib/temporalio/internal/bridge/api/activity_task/activity_task.rb +31 -0
  111. data/lib/temporalio/internal/bridge/api/child_workflow/child_workflow.rb +33 -0
  112. data/lib/temporalio/internal/bridge/api/common/common.rb +26 -0
  113. data/lib/temporalio/internal/bridge/api/core_interface.rb +40 -0
  114. data/lib/temporalio/internal/bridge/api/external_data/external_data.rb +27 -0
  115. data/lib/temporalio/internal/bridge/api/nexus/nexus.rb +33 -0
  116. data/lib/temporalio/internal/bridge/api/workflow_activation/workflow_activation.rb +56 -0
  117. data/lib/temporalio/internal/bridge/api/workflow_commands/workflow_commands.rb +57 -0
  118. data/lib/temporalio/internal/bridge/api/workflow_completion/workflow_completion.rb +30 -0
  119. data/lib/temporalio/internal/bridge/api.rb +3 -0
  120. data/lib/temporalio/internal/bridge/client.rb +95 -0
  121. data/lib/temporalio/internal/bridge/runtime.rb +53 -0
  122. data/lib/temporalio/internal/bridge/testing.rb +66 -0
  123. data/lib/temporalio/internal/bridge/worker.rb +85 -0
  124. data/lib/temporalio/internal/bridge.rb +36 -0
  125. data/lib/temporalio/internal/client/implementation.rb +700 -0
  126. data/lib/temporalio/internal/metric.rb +122 -0
  127. data/lib/temporalio/internal/proto_utils.rb +133 -0
  128. data/lib/temporalio/internal/worker/activity_worker.rb +373 -0
  129. data/lib/temporalio/internal/worker/multi_runner.rb +213 -0
  130. data/lib/temporalio/internal/worker/workflow_instance/child_workflow_handle.rb +54 -0
  131. data/lib/temporalio/internal/worker/workflow_instance/context.rb +329 -0
  132. data/lib/temporalio/internal/worker/workflow_instance/details.rb +44 -0
  133. data/lib/temporalio/internal/worker/workflow_instance/external_workflow_handle.rb +32 -0
  134. data/lib/temporalio/internal/worker/workflow_instance/externally_immutable_hash.rb +22 -0
  135. data/lib/temporalio/internal/worker/workflow_instance/handler_execution.rb +25 -0
  136. data/lib/temporalio/internal/worker/workflow_instance/handler_hash.rb +41 -0
  137. data/lib/temporalio/internal/worker/workflow_instance/illegal_call_tracer.rb +97 -0
  138. data/lib/temporalio/internal/worker/workflow_instance/inbound_implementation.rb +62 -0
  139. data/lib/temporalio/internal/worker/workflow_instance/outbound_implementation.rb +415 -0
  140. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_logger.rb +37 -0
  141. data/lib/temporalio/internal/worker/workflow_instance/replay_safe_metric.rb +40 -0
  142. data/lib/temporalio/internal/worker/workflow_instance/scheduler.rb +163 -0
  143. data/lib/temporalio/internal/worker/workflow_instance.rb +730 -0
  144. data/lib/temporalio/internal/worker/workflow_worker.rb +196 -0
  145. data/lib/temporalio/internal.rb +7 -0
  146. data/lib/temporalio/metric.rb +109 -0
  147. data/lib/temporalio/retry_policy.rb +55 -73
  148. data/lib/temporalio/runtime.rb +302 -13
  149. data/lib/temporalio/scoped_logger.rb +96 -0
  150. data/lib/temporalio/search_attributes.rb +343 -0
  151. data/lib/temporalio/testing/activity_environment.rb +132 -0
  152. data/lib/temporalio/testing/workflow_environment.rb +345 -74
  153. data/lib/temporalio/testing.rb +4 -169
  154. data/lib/temporalio/version.rb +3 -1
  155. data/lib/temporalio/worker/activity_executor/fiber.rb +49 -0
  156. data/lib/temporalio/worker/activity_executor/thread_pool.rb +46 -0
  157. data/lib/temporalio/worker/activity_executor.rb +55 -0
  158. data/lib/temporalio/worker/interceptor.rb +362 -0
  159. data/lib/temporalio/worker/thread_pool.rb +237 -0
  160. data/lib/temporalio/worker/tuner.rb +151 -0
  161. data/lib/temporalio/worker/workflow_executor/thread_pool.rb +230 -0
  162. data/lib/temporalio/worker/workflow_executor.rb +26 -0
  163. data/lib/temporalio/worker.rb +554 -161
  164. data/lib/temporalio/workflow/activity_cancellation_type.rb +20 -0
  165. data/lib/temporalio/workflow/child_workflow_cancellation_type.rb +21 -0
  166. data/lib/temporalio/workflow/child_workflow_handle.rb +43 -0
  167. data/lib/temporalio/workflow/definition.rb +566 -0
  168. data/lib/temporalio/workflow/external_workflow_handle.rb +41 -0
  169. data/lib/temporalio/workflow/future.rb +117 -104
  170. data/lib/temporalio/workflow/handler_unfinished_policy.rb +13 -0
  171. data/lib/temporalio/workflow/info.rb +63 -57
  172. data/lib/temporalio/workflow/parent_close_policy.rb +19 -0
  173. data/lib/temporalio/workflow/update_info.rb +20 -0
  174. data/lib/temporalio/workflow.rb +523 -0
  175. data/lib/temporalio/workflow_history.rb +22 -0
  176. data/lib/temporalio.rb +6 -7
  177. data/temporalio.gemspec +20 -39
  178. metadata +171 -710
  179. data/bridge/Cargo.lock +0 -2997
  180. data/bridge/Cargo.toml +0 -29
  181. data/bridge/sdk-core/ARCHITECTURE.md +0 -76
  182. data/bridge/sdk-core/Cargo.toml +0 -2
  183. data/bridge/sdk-core/LICENSE.txt +0 -23
  184. data/bridge/sdk-core/README.md +0 -117
  185. data/bridge/sdk-core/arch_docs/diagrams/README.md +0 -10
  186. data/bridge/sdk-core/arch_docs/diagrams/sticky_queues.puml +0 -40
  187. data/bridge/sdk-core/arch_docs/diagrams/workflow_internals.svg +0 -1
  188. data/bridge/sdk-core/arch_docs/sticky_queues.md +0 -51
  189. data/bridge/sdk-core/client/Cargo.toml +0 -40
  190. data/bridge/sdk-core/client/LICENSE.txt +0 -23
  191. data/bridge/sdk-core/client/src/lib.rs +0 -1462
  192. data/bridge/sdk-core/client/src/metrics.rs +0 -174
  193. data/bridge/sdk-core/client/src/raw.rs +0 -932
  194. data/bridge/sdk-core/client/src/retry.rs +0 -763
  195. data/bridge/sdk-core/client/src/workflow_handle/mod.rs +0 -185
  196. data/bridge/sdk-core/core/Cargo.toml +0 -129
  197. data/bridge/sdk-core/core/LICENSE.txt +0 -23
  198. data/bridge/sdk-core/core/benches/workflow_replay.rs +0 -76
  199. data/bridge/sdk-core/core/src/abstractions.rs +0 -355
  200. data/bridge/sdk-core/core/src/core_tests/activity_tasks.rs +0 -1049
  201. data/bridge/sdk-core/core/src/core_tests/child_workflows.rs +0 -221
  202. data/bridge/sdk-core/core/src/core_tests/determinism.rs +0 -270
  203. data/bridge/sdk-core/core/src/core_tests/local_activities.rs +0 -1046
  204. data/bridge/sdk-core/core/src/core_tests/mod.rs +0 -100
  205. data/bridge/sdk-core/core/src/core_tests/queries.rs +0 -893
  206. data/bridge/sdk-core/core/src/core_tests/replay_flag.rs +0 -65
  207. data/bridge/sdk-core/core/src/core_tests/workers.rs +0 -257
  208. data/bridge/sdk-core/core/src/core_tests/workflow_cancels.rs +0 -124
  209. data/bridge/sdk-core/core/src/core_tests/workflow_tasks.rs +0 -2433
  210. data/bridge/sdk-core/core/src/ephemeral_server/mod.rs +0 -609
  211. data/bridge/sdk-core/core/src/internal_flags.rs +0 -136
  212. data/bridge/sdk-core/core/src/lib.rs +0 -289
  213. data/bridge/sdk-core/core/src/pollers/mod.rs +0 -54
  214. data/bridge/sdk-core/core/src/pollers/poll_buffer.rs +0 -297
  215. data/bridge/sdk-core/core/src/protosext/mod.rs +0 -428
  216. data/bridge/sdk-core/core/src/replay/mod.rs +0 -215
  217. data/bridge/sdk-core/core/src/retry_logic.rs +0 -202
  218. data/bridge/sdk-core/core/src/telemetry/log_export.rs +0 -190
  219. data/bridge/sdk-core/core/src/telemetry/metrics.rs +0 -462
  220. data/bridge/sdk-core/core/src/telemetry/mod.rs +0 -423
  221. data/bridge/sdk-core/core/src/telemetry/prometheus_server.rs +0 -83
  222. data/bridge/sdk-core/core/src/test_help/mod.rs +0 -939
  223. data/bridge/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +0 -536
  224. data/bridge/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +0 -89
  225. data/bridge/sdk-core/core/src/worker/activities/local_activities.rs +0 -1278
  226. data/bridge/sdk-core/core/src/worker/activities.rs +0 -557
  227. data/bridge/sdk-core/core/src/worker/client/mocks.rs +0 -107
  228. data/bridge/sdk-core/core/src/worker/client.rs +0 -389
  229. data/bridge/sdk-core/core/src/worker/mod.rs +0 -677
  230. data/bridge/sdk-core/core/src/worker/workflow/bridge.rs +0 -35
  231. data/bridge/sdk-core/core/src/worker/workflow/driven_workflow.rs +0 -99
  232. data/bridge/sdk-core/core/src/worker/workflow/history_update.rs +0 -1111
  233. data/bridge/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +0 -964
  234. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +0 -294
  235. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +0 -168
  236. data/bridge/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +0 -918
  237. data/bridge/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +0 -137
  238. data/bridge/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +0 -158
  239. data/bridge/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +0 -130
  240. data/bridge/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +0 -1525
  241. data/bridge/sdk-core/core/src/worker/workflow/machines/mod.rs +0 -324
  242. data/bridge/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +0 -179
  243. data/bridge/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +0 -659
  244. data/bridge/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +0 -439
  245. data/bridge/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +0 -435
  246. data/bridge/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +0 -175
  247. data/bridge/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +0 -249
  248. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +0 -85
  249. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +0 -1280
  250. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +0 -269
  251. data/bridge/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +0 -213
  252. data/bridge/sdk-core/core/src/worker/workflow/managed_run.rs +0 -1305
  253. data/bridge/sdk-core/core/src/worker/workflow/mod.rs +0 -1276
  254. data/bridge/sdk-core/core/src/worker/workflow/run_cache.rs +0 -128
  255. data/bridge/sdk-core/core/src/worker/workflow/wft_extraction.rs +0 -125
  256. data/bridge/sdk-core/core/src/worker/workflow/wft_poller.rs +0 -85
  257. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +0 -117
  258. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +0 -24
  259. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream.rs +0 -715
  260. data/bridge/sdk-core/core-api/Cargo.toml +0 -33
  261. data/bridge/sdk-core/core-api/LICENSE.txt +0 -23
  262. data/bridge/sdk-core/core-api/src/errors.rs +0 -62
  263. data/bridge/sdk-core/core-api/src/lib.rs +0 -113
  264. data/bridge/sdk-core/core-api/src/telemetry.rs +0 -141
  265. data/bridge/sdk-core/core-api/src/worker.rs +0 -161
  266. data/bridge/sdk-core/etc/deps.svg +0 -162
  267. data/bridge/sdk-core/etc/dynamic-config.yaml +0 -2
  268. data/bridge/sdk-core/etc/otel-collector-config.yaml +0 -36
  269. data/bridge/sdk-core/etc/prometheus.yaml +0 -6
  270. data/bridge/sdk-core/etc/regen-depgraph.sh +0 -5
  271. data/bridge/sdk-core/fsm/Cargo.toml +0 -18
  272. data/bridge/sdk-core/fsm/LICENSE.txt +0 -23
  273. data/bridge/sdk-core/fsm/README.md +0 -3
  274. data/bridge/sdk-core/fsm/rustfsm_procmacro/Cargo.toml +0 -27
  275. data/bridge/sdk-core/fsm/rustfsm_procmacro/LICENSE.txt +0 -23
  276. data/bridge/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +0 -650
  277. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/progress.rs +0 -8
  278. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dupe_transitions_fail.rs +0 -18
  279. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dupe_transitions_fail.stderr +0 -12
  280. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dynamic_dest_pass.rs +0 -41
  281. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/forgot_name_fail.rs +0 -14
  282. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/forgot_name_fail.stderr +0 -11
  283. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/handler_arg_pass.rs +0 -32
  284. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/handler_pass.rs +0 -31
  285. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/medium_complex_pass.rs +0 -46
  286. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.rs +0 -29
  287. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +0 -12
  288. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/simple_pass.rs +0 -32
  289. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/struct_event_variant_fail.rs +0 -18
  290. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/struct_event_variant_fail.stderr +0 -5
  291. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_more_item_event_variant_fail.rs +0 -11
  292. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_more_item_event_variant_fail.stderr +0 -5
  293. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_zero_item_event_variant_fail.rs +0 -11
  294. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_zero_item_event_variant_fail.stderr +0 -5
  295. data/bridge/sdk-core/fsm/rustfsm_trait/Cargo.toml +0 -14
  296. data/bridge/sdk-core/fsm/rustfsm_trait/LICENSE.txt +0 -23
  297. data/bridge/sdk-core/fsm/rustfsm_trait/src/lib.rs +0 -254
  298. data/bridge/sdk-core/fsm/src/lib.rs +0 -2
  299. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-16_history.bin +0 -0
  300. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-23_history.bin +0 -0
  301. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-85_history.bin +0 -0
  302. data/bridge/sdk-core/histories/fail_wf_task.bin +0 -0
  303. data/bridge/sdk-core/histories/timer_workflow_history.bin +0 -0
  304. data/bridge/sdk-core/integ-with-otel.sh +0 -7
  305. data/bridge/sdk-core/protos/api_upstream/README.md +0 -9
  306. data/bridge/sdk-core/protos/api_upstream/api-linter.yaml +0 -40
  307. data/bridge/sdk-core/protos/api_upstream/buf.yaml +0 -9
  308. data/bridge/sdk-core/protos/api_upstream/build/go.mod +0 -7
  309. data/bridge/sdk-core/protos/api_upstream/build/go.sum +0 -5
  310. data/bridge/sdk-core/protos/api_upstream/build/tools.go +0 -29
  311. data/bridge/sdk-core/protos/api_upstream/dependencies/gogoproto/gogo.proto +0 -141
  312. data/bridge/sdk-core/protos/api_upstream/go.mod +0 -6
  313. data/bridge/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +0 -89
  314. data/bridge/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +0 -248
  315. data/bridge/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +0 -123
  316. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +0 -47
  317. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +0 -52
  318. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +0 -56
  319. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +0 -170
  320. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +0 -123
  321. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +0 -51
  322. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/query.proto +0 -50
  323. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +0 -41
  324. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +0 -60
  325. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +0 -59
  326. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +0 -56
  327. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +0 -122
  328. data/bridge/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +0 -108
  329. data/bridge/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +0 -114
  330. data/bridge/sdk-core/protos/api_upstream/temporal/api/filter/v1/message.proto +0 -56
  331. data/bridge/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +0 -787
  332. data/bridge/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +0 -99
  333. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +0 -124
  334. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +0 -80
  335. data/bridge/sdk-core/protos/api_upstream/temporal/api/protocol/v1/message.proto +0 -57
  336. data/bridge/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +0 -61
  337. data/bridge/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +0 -55
  338. data/bridge/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +0 -379
  339. data/bridge/sdk-core/protos/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +0 -63
  340. data/bridge/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +0 -108
  341. data/bridge/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +0 -111
  342. data/bridge/sdk-core/protos/api_upstream/temporal/api/version/v1/message.proto +0 -59
  343. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +0 -146
  344. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +0 -1199
  345. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +0 -415
  346. data/bridge/sdk-core/protos/grpc/health/v1/health.proto +0 -63
  347. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +0 -79
  348. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +0 -80
  349. data/bridge/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +0 -78
  350. data/bridge/sdk-core/protos/local/temporal/sdk/core/common/common.proto +0 -16
  351. data/bridge/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +0 -31
  352. data/bridge/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +0 -31
  353. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +0 -270
  354. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +0 -305
  355. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +0 -35
  356. data/bridge/sdk-core/protos/testsrv_upstream/api-linter.yaml +0 -38
  357. data/bridge/sdk-core/protos/testsrv_upstream/buf.yaml +0 -13
  358. data/bridge/sdk-core/protos/testsrv_upstream/dependencies/gogoproto/gogo.proto +0 -141
  359. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +0 -63
  360. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +0 -90
  361. data/bridge/sdk-core/rustfmt.toml +0 -1
  362. data/bridge/sdk-core/sdk/Cargo.toml +0 -48
  363. data/bridge/sdk-core/sdk/LICENSE.txt +0 -23
  364. data/bridge/sdk-core/sdk/src/activity_context.rs +0 -230
  365. data/bridge/sdk-core/sdk/src/app_data.rs +0 -37
  366. data/bridge/sdk-core/sdk/src/interceptors.rs +0 -50
  367. data/bridge/sdk-core/sdk/src/lib.rs +0 -861
  368. data/bridge/sdk-core/sdk/src/payload_converter.rs +0 -11
  369. data/bridge/sdk-core/sdk/src/workflow_context/options.rs +0 -295
  370. data/bridge/sdk-core/sdk/src/workflow_context.rs +0 -694
  371. data/bridge/sdk-core/sdk/src/workflow_future.rs +0 -500
  372. data/bridge/sdk-core/sdk-core-protos/Cargo.toml +0 -33
  373. data/bridge/sdk-core/sdk-core-protos/LICENSE.txt +0 -23
  374. data/bridge/sdk-core/sdk-core-protos/build.rs +0 -142
  375. data/bridge/sdk-core/sdk-core-protos/src/constants.rs +0 -7
  376. data/bridge/sdk-core/sdk-core-protos/src/history_builder.rs +0 -557
  377. data/bridge/sdk-core/sdk-core-protos/src/history_info.rs +0 -234
  378. data/bridge/sdk-core/sdk-core-protos/src/lib.rs +0 -2088
  379. data/bridge/sdk-core/sdk-core-protos/src/task_token.rs +0 -48
  380. data/bridge/sdk-core/sdk-core-protos/src/utilities.rs +0 -14
  381. data/bridge/sdk-core/test-utils/Cargo.toml +0 -38
  382. data/bridge/sdk-core/test-utils/src/canned_histories.rs +0 -1389
  383. data/bridge/sdk-core/test-utils/src/histfetch.rs +0 -28
  384. data/bridge/sdk-core/test-utils/src/lib.rs +0 -709
  385. data/bridge/sdk-core/test-utils/src/wf_input_saver.rs +0 -50
  386. data/bridge/sdk-core/test-utils/src/workflows.rs +0 -29
  387. data/bridge/sdk-core/tests/fuzzy_workflow.rs +0 -130
  388. data/bridge/sdk-core/tests/heavy_tests.rs +0 -265
  389. data/bridge/sdk-core/tests/integ_tests/client_tests.rs +0 -36
  390. data/bridge/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +0 -150
  391. data/bridge/sdk-core/tests/integ_tests/heartbeat_tests.rs +0 -223
  392. data/bridge/sdk-core/tests/integ_tests/metrics_tests.rs +0 -239
  393. data/bridge/sdk-core/tests/integ_tests/polling_tests.rs +0 -90
  394. data/bridge/sdk-core/tests/integ_tests/queries_tests.rs +0 -314
  395. data/bridge/sdk-core/tests/integ_tests/visibility_tests.rs +0 -151
  396. data/bridge/sdk-core/tests/integ_tests/workflow_tests/activities.rs +0 -902
  397. data/bridge/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +0 -61
  398. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +0 -60
  399. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +0 -51
  400. data/bridge/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +0 -51
  401. data/bridge/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +0 -64
  402. data/bridge/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +0 -47
  403. data/bridge/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +0 -669
  404. data/bridge/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +0 -54
  405. data/bridge/sdk-core/tests/integ_tests/workflow_tests/patches.rs +0 -92
  406. data/bridge/sdk-core/tests/integ_tests/workflow_tests/replay.rs +0 -228
  407. data/bridge/sdk-core/tests/integ_tests/workflow_tests/resets.rs +0 -94
  408. data/bridge/sdk-core/tests/integ_tests/workflow_tests/signals.rs +0 -171
  409. data/bridge/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +0 -85
  410. data/bridge/sdk-core/tests/integ_tests/workflow_tests/timers.rs +0 -120
  411. data/bridge/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +0 -77
  412. data/bridge/sdk-core/tests/integ_tests/workflow_tests.rs +0 -596
  413. data/bridge/sdk-core/tests/main.rs +0 -103
  414. data/bridge/sdk-core/tests/runner.rs +0 -132
  415. data/bridge/sdk-core/tests/wf_input_replay.rs +0 -32
  416. data/bridge/src/connection.rs +0 -202
  417. data/bridge/src/lib.rs +0 -494
  418. data/bridge/src/runtime.rs +0 -54
  419. data/bridge/src/test_server.rs +0 -153
  420. data/bridge/src/worker.rs +0 -197
  421. data/ext/Rakefile +0 -9
  422. data/lib/gen/dependencies/gogoproto/gogo_pb.rb +0 -14
  423. data/lib/gen/temporal/api/batch/v1/message_pb.rb +0 -50
  424. data/lib/gen/temporal/api/command/v1/message_pb.rb +0 -160
  425. data/lib/gen/temporal/api/common/v1/message_pb.rb +0 -73
  426. data/lib/gen/temporal/api/enums/v1/batch_operation_pb.rb +0 -33
  427. data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +0 -37
  428. data/lib/gen/temporal/api/enums/v1/common_pb.rb +0 -42
  429. data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +0 -68
  430. data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +0 -79
  431. data/lib/gen/temporal/api/enums/v1/namespace_pb.rb +0 -37
  432. data/lib/gen/temporal/api/enums/v1/query_pb.rb +0 -31
  433. data/lib/gen/temporal/api/enums/v1/reset_pb.rb +0 -24
  434. data/lib/gen/temporal/api/enums/v1/schedule_pb.rb +0 -28
  435. data/lib/gen/temporal/api/enums/v1/task_queue_pb.rb +0 -30
  436. data/lib/gen/temporal/api/enums/v1/update_pb.rb +0 -25
  437. data/lib/gen/temporal/api/enums/v1/workflow_pb.rb +0 -89
  438. data/lib/gen/temporal/api/errordetails/v1/message_pb.rb +0 -84
  439. data/lib/gen/temporal/api/failure/v1/message_pb.rb +0 -83
  440. data/lib/gen/temporal/api/filter/v1/message_pb.rb +0 -40
  441. data/lib/gen/temporal/api/history/v1/message_pb.rb +0 -498
  442. data/lib/gen/temporal/api/namespace/v1/message_pb.rb +0 -64
  443. data/lib/gen/temporal/api/operatorservice/v1/request_response_pb.rb +0 -88
  444. data/lib/gen/temporal/api/operatorservice/v1/service_pb.rb +0 -20
  445. data/lib/gen/temporal/api/protocol/v1/message_pb.rb +0 -30
  446. data/lib/gen/temporal/api/query/v1/message_pb.rb +0 -38
  447. data/lib/gen/temporal/api/replication/v1/message_pb.rb +0 -37
  448. data/lib/gen/temporal/api/schedule/v1/message_pb.rb +0 -149
  449. data/lib/gen/temporal/api/sdk/v1/task_complete_metadata_pb.rb +0 -23
  450. data/lib/gen/temporal/api/taskqueue/v1/message_pb.rb +0 -73
  451. data/lib/gen/temporal/api/testservice/v1/service_pb.rb +0 -21
  452. data/lib/gen/temporal/api/update/v1/message_pb.rb +0 -72
  453. data/lib/gen/temporal/api/version/v1/message_pb.rb +0 -41
  454. data/lib/gen/temporal/api/workflow/v1/message_pb.rb +0 -111
  455. data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +0 -798
  456. data/lib/gen/temporal/api/workflowservice/v1/service_pb.rb +0 -20
  457. data/lib/gen/temporal/sdk/core/activity_result/activity_result_pb.rb +0 -62
  458. data/lib/gen/temporal/sdk/core/activity_task/activity_task_pb.rb +0 -61
  459. data/lib/gen/temporal/sdk/core/child_workflow/child_workflow_pb.rb +0 -61
  460. data/lib/gen/temporal/sdk/core/common/common_pb.rb +0 -26
  461. data/lib/gen/temporal/sdk/core/core_interface_pb.rb +0 -40
  462. data/lib/gen/temporal/sdk/core/external_data/external_data_pb.rb +0 -31
  463. data/lib/gen/temporal/sdk/core/workflow_activation/workflow_activation_pb.rb +0 -171
  464. data/lib/gen/temporal/sdk/core/workflow_commands/workflow_commands_pb.rb +0 -200
  465. data/lib/gen/temporal/sdk/core/workflow_completion/workflow_completion_pb.rb +0 -41
  466. data/lib/temporalio/bridge/connect_options.rb +0 -15
  467. data/lib/temporalio/bridge/error.rb +0 -8
  468. data/lib/temporalio/bridge/retry_config.rb +0 -24
  469. data/lib/temporalio/bridge/tls_options.rb +0 -19
  470. data/lib/temporalio/bridge.rb +0 -14
  471. data/lib/temporalio/client/implementation.rb +0 -340
  472. data/lib/temporalio/connection/retry_config.rb +0 -44
  473. data/lib/temporalio/connection/service.rb +0 -20
  474. data/lib/temporalio/connection/test_service.rb +0 -92
  475. data/lib/temporalio/connection/tls_options.rb +0 -51
  476. data/lib/temporalio/connection/workflow_service.rb +0 -731
  477. data/lib/temporalio/connection.rb +0 -86
  478. data/lib/temporalio/data_converter.rb +0 -191
  479. data/lib/temporalio/error/workflow_failure.rb +0 -19
  480. data/lib/temporalio/errors.rb +0 -40
  481. data/lib/temporalio/failure_converter/base.rb +0 -26
  482. data/lib/temporalio/failure_converter/basic.rb +0 -319
  483. data/lib/temporalio/failure_converter.rb +0 -7
  484. data/lib/temporalio/interceptor/activity_inbound.rb +0 -22
  485. data/lib/temporalio/interceptor/activity_outbound.rb +0 -24
  486. data/lib/temporalio/interceptor/chain.rb +0 -28
  487. data/lib/temporalio/interceptor/client.rb +0 -127
  488. data/lib/temporalio/interceptor.rb +0 -22
  489. data/lib/temporalio/payload_codec/base.rb +0 -32
  490. data/lib/temporalio/payload_converter/base.rb +0 -24
  491. data/lib/temporalio/payload_converter/bytes.rb +0 -27
  492. data/lib/temporalio/payload_converter/composite.rb +0 -49
  493. data/lib/temporalio/payload_converter/encoding_base.rb +0 -35
  494. data/lib/temporalio/payload_converter/json.rb +0 -26
  495. data/lib/temporalio/payload_converter/nil.rb +0 -26
  496. data/lib/temporalio/payload_converter.rb +0 -14
  497. data/lib/temporalio/retry_state.rb +0 -35
  498. data/lib/temporalio/testing/time_skipping_handle.rb +0 -32
  499. data/lib/temporalio/testing/time_skipping_interceptor.rb +0 -23
  500. data/lib/temporalio/timeout_type.rb +0 -29
  501. data/lib/temporalio/worker/activity_runner.rb +0 -114
  502. data/lib/temporalio/worker/activity_worker.rb +0 -164
  503. data/lib/temporalio/worker/reactor.rb +0 -46
  504. data/lib/temporalio/worker/runner.rb +0 -63
  505. data/lib/temporalio/worker/sync_worker.rb +0 -124
  506. data/lib/temporalio/worker/thread_pool_executor.rb +0 -51
  507. data/lib/temporalio/workflow/async.rb +0 -46
  508. data/lib/temporalio/workflow/execution_info.rb +0 -54
  509. data/lib/temporalio/workflow/execution_status.rb +0 -36
  510. data/lib/temporalio/workflow/id_reuse_policy.rb +0 -36
  511. data/lib/temporalio/workflow/query_reject_condition.rb +0 -33
  512. data/lib/thermite_patch.rb +0 -33
  513. data/sig/async.rbs +0 -17
  514. data/sig/protobuf.rbs +0 -16
  515. data/sig/protos/dependencies/gogoproto/gogo.rbs +0 -914
  516. data/sig/protos/google/protobuf/any.rbs +0 -157
  517. data/sig/protos/google/protobuf/descriptor.rbs +0 -2825
  518. data/sig/protos/google/protobuf/duration.rbs +0 -114
  519. data/sig/protos/google/protobuf/empty.rbs +0 -36
  520. data/sig/protos/google/protobuf/timestamp.rbs +0 -145
  521. data/sig/protos/google/protobuf/wrappers.rbs +0 -358
  522. data/sig/protos/temporal/api/batch/v1/message.rbs +0 -300
  523. data/sig/protos/temporal/api/command/v1/message.rbs +0 -1399
  524. data/sig/protos/temporal/api/common/v1/message.rbs +0 -528
  525. data/sig/protos/temporal/api/enums/v1/batch_operation.rbs +0 -79
  526. data/sig/protos/temporal/api/enums/v1/command_type.rbs +0 -68
  527. data/sig/protos/temporal/api/enums/v1/common.rbs +0 -118
  528. data/sig/protos/temporal/api/enums/v1/event_type.rbs +0 -264
  529. data/sig/protos/temporal/api/enums/v1/failed_cause.rbs +0 -277
  530. data/sig/protos/temporal/api/enums/v1/namespace.rbs +0 -108
  531. data/sig/protos/temporal/api/enums/v1/query.rbs +0 -81
  532. data/sig/protos/temporal/api/enums/v1/reset.rbs +0 -44
  533. data/sig/protos/temporal/api/enums/v1/schedule.rbs +0 -72
  534. data/sig/protos/temporal/api/enums/v1/task_queue.rbs +0 -92
  535. data/sig/protos/temporal/api/enums/v1/update.rbs +0 -64
  536. data/sig/protos/temporal/api/enums/v1/workflow.rbs +0 -371
  537. data/sig/protos/temporal/api/errordetails/v1/message.rbs +0 -551
  538. data/sig/protos/temporal/api/failure/v1/message.rbs +0 -581
  539. data/sig/protos/temporal/api/filter/v1/message.rbs +0 -171
  540. data/sig/protos/temporal/api/history/v1/message.rbs +0 -4609
  541. data/sig/protos/temporal/api/namespace/v1/message.rbs +0 -410
  542. data/sig/protos/temporal/api/operatorservice/v1/request_response.rbs +0 -643
  543. data/sig/protos/temporal/api/operatorservice/v1/service.rbs +0 -17
  544. data/sig/protos/temporal/api/protocol/v1/message.rbs +0 -84
  545. data/sig/protos/temporal/api/query/v1/message.rbs +0 -182
  546. data/sig/protos/temporal/api/replication/v1/message.rbs +0 -148
  547. data/sig/protos/temporal/api/schedule/v1/message.rbs +0 -1488
  548. data/sig/protos/temporal/api/sdk/v1/task_complete_metadata.rbs +0 -110
  549. data/sig/protos/temporal/api/taskqueue/v1/message.rbs +0 -486
  550. data/sig/protos/temporal/api/testservice/v1/request_response.rbs +0 -249
  551. data/sig/protos/temporal/api/testservice/v1/service.rbs +0 -15
  552. data/sig/protos/temporal/api/update/v1/message.rbs +0 -489
  553. data/sig/protos/temporal/api/version/v1/message.rbs +0 -184
  554. data/sig/protos/temporal/api/workflow/v1/message.rbs +0 -824
  555. data/sig/protos/temporal/api/workflowservice/v1/request_response.rbs +0 -7250
  556. data/sig/protos/temporal/api/workflowservice/v1/service.rbs +0 -22
  557. data/sig/protos/temporal/sdk/core/activity_result/activity_result.rbs +0 -380
  558. data/sig/protos/temporal/sdk/core/activity_task/activity_task.rbs +0 -386
  559. data/sig/protos/temporal/sdk/core/child_workflow/child_workflow.rbs +0 -323
  560. data/sig/protos/temporal/sdk/core/common/common.rbs +0 -62
  561. data/sig/protos/temporal/sdk/core/core_interface.rbs +0 -101
  562. data/sig/protos/temporal/sdk/core/external_data/external_data.rbs +0 -119
  563. data/sig/protos/temporal/sdk/core/workflow_activation/workflow_activation.rbs +0 -1473
  564. data/sig/protos/temporal/sdk/core/workflow_commands/workflow_commands.rbs +0 -1784
  565. data/sig/protos/temporal/sdk/core/workflow_completion/workflow_completion.rbs +0 -180
  566. data/sig/ruby.rbs +0 -12
  567. data/sig/temporalio/activity/context.rbs +0 -29
  568. data/sig/temporalio/activity/info.rbs +0 -43
  569. data/sig/temporalio/activity.rbs +0 -19
  570. data/sig/temporalio/bridge/connect_options.rbs +0 -19
  571. data/sig/temporalio/bridge/error.rbs +0 -8
  572. data/sig/temporalio/bridge/retry_config.rbs +0 -21
  573. data/sig/temporalio/bridge/tls_options.rbs +0 -17
  574. data/sig/temporalio/bridge.rbs +0 -71
  575. data/sig/temporalio/client/implementation.rbs +0 -38
  576. data/sig/temporalio/client/workflow_handle.rbs +0 -41
  577. data/sig/temporalio/client.rbs +0 -35
  578. data/sig/temporalio/connection/retry_config.rbs +0 -37
  579. data/sig/temporalio/connection/service.rbs +0 -14
  580. data/sig/temporalio/connection/test_service.rbs +0 -13
  581. data/sig/temporalio/connection/tls_options.rbs +0 -43
  582. data/sig/temporalio/connection/workflow_service.rbs +0 -48
  583. data/sig/temporalio/connection.rbs +0 -30
  584. data/sig/temporalio/data_converter.rbs +0 -35
  585. data/sig/temporalio/error/failure.rbs +0 -121
  586. data/sig/temporalio/error/workflow_failure.rbs +0 -9
  587. data/sig/temporalio/errors.rbs +0 -36
  588. data/sig/temporalio/failure_converter/base.rbs +0 -12
  589. data/sig/temporalio/failure_converter/basic.rbs +0 -86
  590. data/sig/temporalio/failure_converter.rbs +0 -5
  591. data/sig/temporalio/interceptor/activity_inbound.rbs +0 -21
  592. data/sig/temporalio/interceptor/activity_outbound.rbs +0 -10
  593. data/sig/temporalio/interceptor/chain.rbs +0 -24
  594. data/sig/temporalio/interceptor/client.rbs +0 -148
  595. data/sig/temporalio/interceptor.rbs +0 -6
  596. data/sig/temporalio/payload_codec/base.rbs +0 -12
  597. data/sig/temporalio/payload_converter/base.rbs +0 -12
  598. data/sig/temporalio/payload_converter/bytes.rbs +0 -9
  599. data/sig/temporalio/payload_converter/composite.rbs +0 -19
  600. data/sig/temporalio/payload_converter/encoding_base.rbs +0 -14
  601. data/sig/temporalio/payload_converter/json.rbs +0 -9
  602. data/sig/temporalio/payload_converter/nil.rbs +0 -9
  603. data/sig/temporalio/payload_converter.rbs +0 -5
  604. data/sig/temporalio/retry_policy.rbs +0 -25
  605. data/sig/temporalio/retry_state.rbs +0 -20
  606. data/sig/temporalio/runtime.rbs +0 -12
  607. data/sig/temporalio/testing/time_skipping_handle.rbs +0 -15
  608. data/sig/temporalio/testing/time_skipping_interceptor.rbs +0 -13
  609. data/sig/temporalio/testing/workflow_environment.rbs +0 -22
  610. data/sig/temporalio/testing.rbs +0 -35
  611. data/sig/temporalio/timeout_type.rbs +0 -15
  612. data/sig/temporalio/version.rbs +0 -3
  613. data/sig/temporalio/worker/activity_runner.rbs +0 -35
  614. data/sig/temporalio/worker/activity_worker.rbs +0 -44
  615. data/sig/temporalio/worker/reactor.rbs +0 -22
  616. data/sig/temporalio/worker/runner.rbs +0 -21
  617. data/sig/temporalio/worker/sync_worker.rbs +0 -23
  618. data/sig/temporalio/worker/thread_pool_executor.rbs +0 -23
  619. data/sig/temporalio/worker.rbs +0 -46
  620. data/sig/temporalio/workflow/async.rbs +0 -9
  621. data/sig/temporalio/workflow/execution_info.rbs +0 -55
  622. data/sig/temporalio/workflow/execution_status.rbs +0 -21
  623. data/sig/temporalio/workflow/future.rbs +0 -40
  624. data/sig/temporalio/workflow/id_reuse_policy.rbs +0 -15
  625. data/sig/temporalio/workflow/info.rbs +0 -55
  626. data/sig/temporalio/workflow/query_reject_condition.rbs +0 -14
  627. data/sig/temporalio.rbs +0 -2
  628. data/sig/thermite_patch.rbs +0 -15
data/README.md CHANGED
@@ -1,303 +1,1105 @@
1
- # Temporal Ruby SDK
1
+ <div style="overflow: hidden"><img src="https://raw.githubusercontent.com/temporalio/assets/main/files/w/ruby.png" alt="Temporal Ruby SDK" /></div>
2
2
 
3
- [![CI status](https://github.com/temporalio/sdk-ruby/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/temporalio/sdk-ruby/actions/workflows/ci.yml?query=branch%3Amain)
4
- [![Build](https://github.com/temporalio/sdk-ruby/actions/workflows/build-native-ext.yml/badge.svg)](https://github.com/temporalio/sdk-ruby/actions/workflows/build-native-ext.yml?query=branch%3Amain+event%3Arelease)
5
- [![Gem Version](https://badge.fury.io/rb/temporalio.svg)](https://rubygems.org/gems/temporalio)
3
+ ![Ruby 3.2 | 3.3 | 3.4](https://img.shields.io/badge/ruby-3.2%20|%203.3%20|%203.4-blue.svg?style=for-the-badge)
4
+ [![MIT](https://img.shields.io/github/license/temporalio/sdk-ruby.svg?style=for-the-badge)](LICENSE)
5
+ [![Gem](https://img.shields.io/gem/v/temporalio?style=for-the-badge)](https://rubygems.org/gems/temporalio)
6
6
 
7
- [Temporal](https://temporal.io/) is a distributed, scalable, durable, and highly available
8
- orchestration engine used to execute asynchronous long-running business logic in a scalable and
9
- resilient way.
7
+ [Temporal](https://temporal.io/) is a distributed, scalable, durable, and highly available orchestration engine used to
8
+ execute asynchronous, long-running business logic in a scalable and resilient way.
10
9
 
11
- "Temporal Ruby SDK" is the framework for authoring workflows and activities using the Ruby
12
- programming language.
10
+ **Temporal Ruby SDK** is the framework for authoring workflows and activities using the Ruby programming language.
13
11
 
14
- ⚠️ UNDER DEVELOPMENT
12
+ Also see:
15
13
 
16
- The Ruby SDK is under development. There are no compatibility guarantees at this time.
14
+ * [Ruby Samples](https://github.com/temporalio/samples-ruby)
15
+ * [API Documentation](https://rubydoc.info/gems/temporalio/0.2.0)
17
16
 
18
- At this point the SDK only supports the **Temporal Client** capabilities:
17
+ ⚠️ UNDER ACTIVE DEVELOPMENT
19
18
 
20
- - Starting a workflow (defined in any other SDK)
21
- - Interacting with a workflow (cancelling, querying, signalling, etc)
22
- - Interceptor and Data Conversion support
23
- - gRPC access to Temporal Server
19
+ This SDK is under active development and has not released a stable version yet. APIs may change in incompatible ways
20
+ until the SDK is marked stable.
24
21
 
25
- As well as **Activity Worker** capabilities:
22
+ **NOTE: This README is for the current branch and not necessarily what's released on RubyGems.**
26
23
 
27
- - Definiting activities
28
- - Activity heartbeats/cancellations
29
- - Running activity workers
24
+ ---
25
+
26
+ <!-- START doctoc generated TOC please keep comment here to allow auto update -->
27
+ <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
28
+ **Contents**
29
+
30
+ - [Quick Start](#quick-start)
31
+ - [Installation](#installation)
32
+ - [Implementing a Workflow and Activity](#implementing-a-workflow-and-activity)
33
+ - [Running a Worker](#running-a-worker)
34
+ - [Executing a Workflow](#executing-a-workflow)
35
+ - [Usage](#usage)
36
+ - [Client](#client)
37
+ - [Cloud Client Using mTLS](#cloud-client-using-mtls)
38
+ - [Cloud Client Using API Key](#cloud-client-using-api-key)
39
+ - [Data Conversion](#data-conversion)
40
+ - [ActiveRecord and ActiveModel](#activerecord-and-activemodel)
41
+ - [Workers](#workers)
42
+ - [Workflows](#workflows)
43
+ - [Workflow Definition](#workflow-definition)
44
+ - [Running Workflows](#running-workflows)
45
+ - [Invoking Activities](#invoking-activities)
46
+ - [Invoking Child Workflows](#invoking-child-workflows)
47
+ - [Timers and Conditions](#timers-and-conditions)
48
+ - [Workflow Fiber Scheduling and Cancellation](#workflow-fiber-scheduling-and-cancellation)
49
+ - [Workflow Futures](#workflow-futures)
50
+ - [Workflow Utilities](#workflow-utilities)
51
+ - [Workflow Exceptions](#workflow-exceptions)
52
+ - [Workflow Logic Constraints](#workflow-logic-constraints)
53
+ - [Workflow Testing](#workflow-testing)
54
+ - [Automatic Time Skipping](#automatic-time-skipping)
55
+ - [Manual Time Skipping](#manual-time-skipping)
56
+ - [Mocking Activities](#mocking-activities)
57
+ - [Workflow Replay](#workflow-replay)
58
+ - [Activities](#activities)
59
+ - [Activity Definition](#activity-definition)
60
+ - [Activity Context](#activity-context)
61
+ - [Activity Heartbeating and Cancellation](#activity-heartbeating-and-cancellation)
62
+ - [Activity Worker Shutdown](#activity-worker-shutdown)
63
+ - [Activity Concurrency and Executors](#activity-concurrency-and-executors)
64
+ - [Activity Testing](#activity-testing)
65
+ - [Platform Support](#platform-support)
66
+ - [Development](#development)
67
+ - [Build](#build)
68
+ - [Build Platform-specific Gem](#build-platform-specific-gem)
69
+ - [Testing](#testing)
70
+ - [Code Formatting and Type Checking](#code-formatting-and-type-checking)
71
+ - [Proto Generation](#proto-generation)
72
+
73
+ <!-- END doctoc generated TOC please keep comment here to allow auto update -->
30
74
 
31
75
  ## Quick Start
32
76
 
33
77
  ### Installation
34
78
 
35
- Add the [temporalio gem](https://rubygems.org/gems/temporalio) to your Gemfile:
79
+ The Ruby SDK works with Ruby 3.2, 3.3, and 3.4.
36
80
 
37
- ```ruby
81
+ Can require in a Gemfile like:
82
+
83
+ ```
38
84
  gem 'temporalio'
39
85
  ```
40
86
 
41
- The SDK is now ready for use. To build from source, see [Dev Setup](#dev-setup).
87
+ Or via `gem install` like:
42
88
 
43
- **NOTE: This README is for the current branch and not necessarily what's released on RubyGems.**
89
+ ```
90
+ gem install temporalio
91
+ ```
44
92
 
45
- ## Usage
93
+ **NOTE**: Only macOS ARM/x64 and Linux ARM/x64 are supported, and the platform-specific gem chosen is based on when the
94
+ gem/bundle install is performed. A source gem is published but cannot be used directly and will fail to build if tried.
95
+ MinGW-based Windows and Linux MUSL do not have gems. See the [Platform Support](#platform-support) section for more
96
+ information.
46
97
 
47
- ### Client
98
+ **NOTE**: Due to [an issue](https://github.com/temporalio/sdk-ruby/issues/162), fibers (and `async` gem) are only
99
+ supported on Ruby versions 3.3 and newer.
100
+
101
+ ### Implementing a Workflow and Activity
102
+
103
+ Activities are classes. Here is an example of a simple activity that can be put in `say_hello_activity.rb`:
48
104
 
49
- A client can be created and used to start a workflow like so:
50
105
 
51
106
  ```ruby
52
- # Establish a gRPC connection to the server
53
- connection = Temporalio::Connection.new('localhost:7233')
107
+ require 'temporalio/activity'
54
108
 
55
- # To enable TLS, simply add the `tls:` argument:
56
- # Temporalio::Connection.new(
57
- # 'localhost:7233',
58
- # tls: Temporalio::Connection::TlsOptions.new(client_cert, client_private_key)
59
- # )
109
+ # Implementation of a simple activity
110
+ class SayHelloActivity < Temporalio::Activity::Definition
111
+ def execute(name)
112
+ "Hello, #{name}!"
113
+ end
114
+ end
115
+ ```
60
116
 
61
- # Initialize a Client with a namespace
62
- client = Temporalio::Client.new(connection, 'my-namespace')
117
+ Workflows are also classes. To create the workflow, put the following in `say_hello_workflow.rb`:
63
118
 
64
- # Start a workflow
65
- handle = client.start_workflow('MyWorkflow', 'some input', id: 'my-id', task_queue: 'my-task-queue')
119
+ ```ruby
120
+ require 'temporalio/workflow'
121
+ require_relative 'say_hello_activity'
66
122
 
67
- # Wait for the workflow to finish processing
68
- result = handle.result
69
- puts "Result: #{result}"
123
+ class SayHelloWorkflow < Temporalio::Workflow::Definition
124
+ def execute(name)
125
+ Temporalio::Workflow.execute_activity(
126
+ SayHelloActivity,
127
+ name,
128
+ schedule_to_close_timeout: 300
129
+ )
130
+ end
131
+ end
70
132
  ```
71
133
 
72
- Some things to note about the above code:
134
+ This is a simple workflow that executes the `SayHelloActivity` activity.
73
135
 
74
- - A `Client` does not have an explicit "close"
75
- - All positional arguments after the workflow name are treated as workflow arguments
76
- - The `handle` represents the workflow that was started and can be used for more than just getting
77
- the result
78
- - Clients can have many more options not shown here (e.g. data converters and interceptors)
136
+ ### Running a Worker
79
137
 
80
- ### Data Conversion
138
+ To run this in a worker, put the following in `worker.rb`:
81
139
 
82
- Data converters are used to convert raw Temporal payloads to/from actual Ruby types. These consist
83
- of 3 distinct types of converters:
140
+ ```ruby
141
+ require 'temporalio/client'
142
+ require 'temporalio/worker'
143
+ require_relative 'say_hello_activity'
144
+ require_relative 'say_hello_workflow'
145
+
146
+ # Create a client
147
+ client = Temporalio::Client.connect('localhost:7233', 'my-namespace')
148
+
149
+ # Create a worker with the client, activities, and workflows
150
+ worker = Temporalio::Worker.new(
151
+ client:,
152
+ task_queue: 'my-task-queue',
153
+ workflows: [SayHelloWorkflow],
154
+ # There are various forms an activity can take, see "Activities" section for details
155
+ activities: [SayHelloActivity]
156
+ )
157
+
158
+ # Run the worker until SIGINT. This can be done in many ways, see "Workers" section for details.
159
+ worker.run(shutdown_signals: ['SIGINT'])
160
+ ```
84
161
 
85
- - **Payload Converters** to convert Ruby values to/from serialized bytes
86
- - **Payload Codecs** to convert bytes to bytes (e.g. for compression or encryption)
87
- - **Failure Converters** to convert exceptions to/from serialized failures
162
+ Running that will run the worker until Ctrl+C is pressed.
88
163
 
89
- The default data converter supports converting multiple types including:
164
+ ### Executing a Workflow
90
165
 
91
- - `nil`
92
- - bytes (`String` with `Encoding::ASCII_8BIT`)
93
- - Anything that [JSON.generate](https://ruby-doc.org/stdlib-3.0.0/libdoc/json/rdoc/JSON.html#method-i-generate)
94
- supports
166
+ To start and wait on the workflow result, with the worker program running elsewhere, put the following in
167
+ `execute_workflow.rb`:
95
168
 
96
- This notably doesn't include any `Date`, `Time`, or `DateTime` objects as they may not work across
97
- different SDKs. A custom payload converter can be implemented to support these.
169
+ ```ruby
170
+ require 'temporalio/client'
171
+ require_relative 'say_hello_workflow'
172
+
173
+ # Create a client
174
+ client = Temporalio::Client.connect('localhost:7233', 'my-namespace')
175
+
176
+ # Run workflow
177
+ result = client.execute_workflow(
178
+ SayHelloWorkflow,
179
+ 'Temporal', # This is the input to the workflow
180
+ id: 'my-workflow-id',
181
+ task_queue: 'my-task-queue'
182
+ )
183
+ puts "Result: #{result}"
184
+ ```
98
185
 
99
- ### Workers
186
+ This will output:
187
+
188
+ ```
189
+ Result: Hello, Temporal!
190
+ ```
100
191
 
101
- Workers host workflows (coming soon) and/or activities. Here's how to run a worker:
192
+ ## Usage
102
193
 
103
- ```ruby
104
- require 'temporalio'
194
+ ### Client
195
+
196
+ A client can be created and used to start a workflow or otherwise interact with Temporal. For example:
105
197
 
106
- # Establish a gRPC connection to the server
107
- connection = Temporalio::Connection.new('localhost:7233')
198
+ ```ruby
199
+ require 'temporalio/client'
108
200
 
109
- # Initialize a new worker with your activities
110
- worker = Temporalio::Worker.new(connection, 'my-namespace', 'my-task-queue', activities: [MyActivity])
201
+ # Create a client
202
+ client = Temporalio::Client.connect('localhost:7233', 'my-namespace')
111
203
 
112
- # Occupy the thread by running the worker
113
- worker.run
204
+ # Start a workflow
205
+ handle = client.start_workflow(
206
+ MyWorkflow,
207
+ 'arg1', 'arg2',
208
+ id: 'my-workflow-id',
209
+ task_queue: 'my-task-queue'
210
+ )
211
+
212
+ # Wait for result
213
+ result = handle.result
214
+ puts "Result: #{result}"
114
215
  ```
115
216
 
116
- Some things to note about the above code:
217
+ Notes about the above code:
218
+
219
+ * Temporal clients are not explicitly closed.
220
+ * To enable TLS, the `tls` option can be set to `true` or a `Temporalio::Client::Connection::TLSOptions` instance.
221
+ * Instead of `start_workflow` + `result` above, `execute_workflow` shortcut can be used if the handle is not needed.
222
+ * Both `start_workflow` and `execute_workflow` accept either the workflow class or the string/symbol name of the
223
+ workflow.
224
+ * The `handle` above is a `Temporalio::Client::WorkflowHandle` which has several other operations that can be performed
225
+ on a workflow. To get a handle to an existing workflow, use `workflow_handle` on the client.
226
+ * Clients are thread safe and are fiber-compatible (but fiber compatibility only supported for Ruby 3.3+ at this time).
117
227
 
118
- - This creates/uses the same connection that is used for initializing a client
119
- - Workers can have many more options not shown here (e.g. data converters and interceptors)
228
+ #### Cloud Client Using mTLS
120
229
 
121
- In order to have more control over running of a worker you can provide a block of code by the end of
122
- which the worker will shut itself down:
230
+ Assuming a client certificate is present at `my-cert.pem` and a client key is present at `my-key.pem`, this is how to
231
+ connect to Temporal Cloud:
123
232
 
124
233
  ```ruby
125
- # Initialize worker_1, worker_2 and worker_3 as in the example above
234
+ require 'temporalio/client'
235
+
236
+ # Create a client
237
+ client = Temporalio::Client.connect(
238
+ 'my-namespace.a1b2c.tmprl.cloud:7233',
239
+ 'my-namespace.a1b2c',
240
+ tls: Temporalio::Client::Connection::TLSOptions.new(
241
+ client_cert: File.read('my-cert.pem'),
242
+ client_private_key: File.read('my-key.pem')
243
+ ))
244
+ ```
126
245
 
127
- # Run the worker for 5 seconds, then shut down
128
- worker_1.run { sleep 5 }
246
+ #### Cloud Client Using API Key
129
247
 
130
- # Or shut the worker down when a workflow completes (very useful for running specs):
131
- client = Temporalio::Client.new(connection, 'my-namespace')
132
- handle = client.start_workflow('MyWorkflow', 'some input', id: 'my-id', task_queue: 'my-task-queue')
133
- worker_2.run { handle.result }
248
+ Assuming the API key is 'my-api-key', this is how to connect to Temporal cloud:
134
249
 
135
- # Or wait for some external signal to stop the worker
136
- stop_queue = Queue.new
137
- Signal.trap('USR1') { stop_queue.close }
138
- worker_3.run { stop_queue.pop }
250
+ ```ruby
251
+ require 'temporalio/client'
252
+
253
+ # Create a client
254
+ client = Temporalio::Client.connect(
255
+ 'my-namespace.a1b2c.tmprl.cloud:7233',
256
+ 'my-namespace.a1b2c',
257
+ api_key: 'my-api-key'
258
+ tls: true
259
+ )
139
260
  ```
140
261
 
141
- You can also shut down a running worker by calling `Temporalio::Worker#shutdown` from a separate
142
- thread at any time.
262
+ #### Data Conversion
263
+
264
+ Data converters are used to convert raw Temporal payloads to/from actual Ruby types. A custom data converter can be set
265
+ via the `data_converter` keyword argument when creating a client. Data converters are a combination of payload
266
+ converters, payload codecs, and failure converters. Payload converters convert Ruby values to/from serialized bytes.
267
+ Payload codecs convert bytes to bytes (e.g. for compression or encryption). Failure converters convert exceptions
268
+ to/from serialized failures.
269
+
270
+ Data converters are in the `Temporalio::Converters` module. The default data converter uses a default payload converter,
271
+ which supports the following types:
272
+
273
+ * `nil`
274
+ * "bytes" (i.e. `String` with `Encoding::ASCII_8BIT` encoding)
275
+ * `Google::Protobuf::MessageExts` instances
276
+ * [JSON module](https://docs.ruby-lang.org/en/master/JSON.html) for everything else
277
+
278
+ This means that normal Ruby objects will use `JSON.generate` when serializing and `JSON.parse` when deserializing (with
279
+ `create_additions: true` set by default). So a Ruby object will often appear as a hash when deserialized. Also, hashes
280
+ that are passed in with symbol keys end up with string keys when deserialized. While "JSON Additions" are supported, it
281
+ is not cross-SDK-language compatible since this is a Ruby-specific construct.
282
+
283
+ The default payload converter is a collection of "encoding payload converters". On serialize, each encoding converter
284
+ will be tried in order until one accepts (default falls through to the JSON one). The encoding converter sets an
285
+ `encoding` metadata value which is used to know which converter to use on deserialize. Custom encoding converters can be
286
+ created, or even the entire payload converter can be replaced with a different implementation.
143
287
 
144
- #### Running multiple workers
288
+ ##### ActiveRecord and ActiveModel
145
289
 
146
- In order to run multiple workers in the same thread you can use the `Temporalio::Worker.run` method:
290
+ By default, `ActiveRecord` and `ActiveModel` objects do not natively support the `JSON` module. A mixin can be created
291
+ to add this support for `ActiveRecord`, for example:
147
292
 
148
293
  ```ruby
149
- # Initialize workers
150
- worker_1 = Temporalio::Worker.new(connection, 'my-namespace-1', 'my-task-queue-1', activities: [MyActivity1, MyActivity2])
151
- worker_2 = Temporalio::Worker.new(connection, 'my-namespace-2', 'my-task-queue-1', activities: [MyActivity3])
152
- worker_3 = Temporalio::Worker.new(connection, 'my-namespace-1', 'my-task-queue-2', activities: [MyActivity4])
294
+ module ActiveRecordJSONSupport
295
+ extend ActiveSupport::Concern
296
+ include ActiveModel::Serializers::JSON
297
+
298
+ included do
299
+ def to_json(*args)
300
+ hash = as_json
301
+ hash[::JSON.create_id] = self.class.name
302
+ hash.to_json(*args)
303
+ end
153
304
 
154
- Temporalio::Worker.run(worker_1, worker_2, worker_3)
305
+ def self.json_create(object)
306
+ object.delete(::JSON.create_id)
307
+ ret = new
308
+ ret.attributes = object
309
+ ret
310
+ end
311
+ end
312
+ end
155
313
  ```
156
314
 
157
- Please note that similar to `Temporalio::Worker#run`, `Temporalio::Worker.run` accepts a block that
158
- behaves the same way — the workers will be shut down when the block finishes.
159
-
160
- You can also configure your worker to listen on process signals to initiate a shutdown:
315
+ Similarly, a mixin for `ActiveModel` that adds `attributes` accessors can leverage this same mixin, for example:
161
316
 
162
317
  ```ruby
163
- Temporalio::Worker.run(worker_1, worker_2, worker_3, shutdown_signals: %w[INT TERM])
318
+ module ActiveModelJSONSupport
319
+ extend ActiveSupport::Concern
320
+ include ActiveRecordJSONSupport
321
+
322
+ included do
323
+ def attributes=(hash)
324
+ hash.each do |key, value|
325
+ send("#{key}=", value)
326
+ end
327
+ end
328
+
329
+ def attributes
330
+ instance_values
331
+ end
332
+ end
333
+ end
164
334
  ```
165
335
 
166
- #### Worker Shutdown
336
+ Now `include ActiveRecordJSONSupport` or `include ActiveModelJSONSupport` will make the models work with Ruby `JSON`
337
+ module and therefore Temporal. Of course any other approach to make the models work with the `JSON` module will work as
338
+ well.
167
339
 
168
- The `Temporalio::Worker#run` (as well as `Temporalio::Worker#shutdown`) invocation will wait on all
169
- activities to complete, so if a long-running activity does not at least respect cancellation, the
170
- shutdown may never complete.
340
+ ### Workers
171
341
 
172
- If a worker was initialized with a `graceful_shutdown_timeout` option then a cancellation will be
173
- issued for every running activity after the set timeout. The bahaviour is mostly identical to a
174
- server requested cancellation and should be handled accordingly. More on this in [Heartbeating and
175
- Cancellation](#heartbeating-and-cancellation).
342
+ Workers host workflows and/or activities. Here's how to run a worker:
176
343
 
177
- ### Activities
344
+ ```ruby
345
+ require 'temporalio/client'
346
+ require 'temporalio/worker'
347
+ require 'my_module'
348
+
349
+ # Create a client
350
+ client = Temporalio::Client.connect('localhost:7233', 'my-namespace')
351
+
352
+ # Create a worker with the client, activities, and workflows
353
+ worker = Temporalio::Worker.new(
354
+ client:,
355
+ task_queue: 'my-task-queue',
356
+ workflows: [MyModule::MyWorkflow],
357
+ # There are various forms an activity can take, see "Activities" section for details
358
+ activities: [MyModule::MyActivity]
359
+ )
360
+
361
+ # Run the worker until block complete
362
+ worker.run do
363
+ something_that_waits_for_completion
364
+ end
365
+ ```
366
+
367
+ Notes about the above code:
368
+
369
+ * A worker uses the same client that is used for other Temporal things.
370
+ * This just shows providing an activity class, but there are other forms, see the "Activities" section for details.
371
+ * The worker `run` method accepts an optional `Temporalio::Cancellation` object that can be used to cancel instead or in
372
+ addition to providing a block that waits for completion.
373
+ * The worker `run` method accepts a `shutdown_signals` array which will trap the signal and start shutdown when
374
+ received.
375
+ * Workers work with threads or fibers (but fiber compatibility only supported for Ruby 3.3+ at this time). Fiber-based
376
+ activities (see "Activities" section) only work if the worker is created within a fiber.
377
+ * The `run` method does not return until the worker is shut down. This means even if shutdown is triggered (e.g. via
378
+ `Cancellation` or block completion), it may not return immediately. Activities not completing may hang worker
379
+ shutdown, see the "Activities" section.
380
+ * Workers can have many more options not shown here (e.g. tuners and interceptors).
381
+ * The `Temporalio::Worker.run_all` class method is available for running multiple workers concurrently.
382
+
383
+ ### Workflows
178
384
 
179
- #### Definition
385
+ #### Workflow Definition
180
386
 
181
- Activities are defined by subclassing `Temporalio::Activity` class:
387
+ Workflows are defined as classes that extend `Temporalio::Workflow::Definition`. The entry point for a workflow is
388
+ `execute` and must be defined. Methods for handling signals, queries, and updates are marked with `workflow_signal`,
389
+ `workflow_query`, and `workflow_update` just before the method is defined. Here is an example of a workflow definition:
182
390
 
183
391
  ```ruby
184
- class SayHelloActivity < Temporalio::Activity
185
- # Optionally specify a custom activity name:
186
- # (The class name `SayHelloActivity` will be used by default)
187
- activity_name 'say-hello'
392
+ require 'temporalio/workflow'
393
+
394
+ class GreetingWorkflow < Temporalio::Workflow::Definition
395
+ workflow_query_attr_reader :current_greeting
396
+
397
+ def execute(params)
398
+ loop do
399
+ # Call activity called CreateGreeting to create greeting and store as attribute
400
+ @current_greeting = Temporalio::Workflow.execute_activity(
401
+ CreateGreeting,
402
+ params,
403
+ schedule_to_close_timeout: 300
404
+ )
405
+ Temporalio::Workflow.logger.debug("Greeting set to #{@current_greeting}")
406
+
407
+ # Wait for param update or complete signal. Note, cancellation can occur by default
408
+ # on wait_condition calls, so Cancellation object doesn't need to be passed
409
+ # explicitly.
410
+ Temporalio::Workflow.wait_condition { @greeting_params_update || @complete }
411
+
412
+ # If there was an update, exchange and rerun. If it's _only_ a complete, finish
413
+ # workflow with the greeting.
414
+ if @greeting_params_update
415
+ params, @greeting_params_update = @greeting_params_update, nil
416
+ else
417
+ return @current_greeting
418
+ end
419
+ end
420
+ end
188
421
 
189
- def execute(name)
190
- return "Hello, #{name}!"
422
+ workflow_update
423
+ def update_greeting_params(greeting_params_update)
424
+ @greeting_params_update = greeting_params_update
425
+ end
426
+
427
+ workflow_signal
428
+ def complete_with_greeting
429
+ @complete = true
191
430
  end
192
431
  end
193
432
  ```
194
433
 
195
- Some things to note about activity definitions:
434
+ Notes about the above code:
435
+
436
+ * `execute` is the primary entrypoint and its result/exception represents the workflow result/failure.
437
+ * `workflow_signal`, `workflow_query` (and the shortcut seen above, `workflow_query_attr_reader`), and `workflow_update`
438
+ implicitly create class methods usable by callers/clients. A workflow definition with no methods actually implemented
439
+ can even be created for use by clients if the workflow is implemented elsewhere and/or in another language.
440
+ * Workflow code must be deterministic. See the "Workflow Logic Constraints" section below.
441
+ * `execute_activity` accepts either the activity class or the string/symbol for the name.
442
+
443
+ The following protected class methods are available on `Temporalio::Workflow::Definition` to customize the overall
444
+ workflow definition/behavior:
445
+
446
+ * `workflow_name` - Accepts a string or symbol to change the name. Otherwise the name is defaulted to the unqualified
447
+ class name.
448
+ * `workflow_dynamic` - Marks a workflow as dynamic. Dynamic workflows do not have names and handle any workflow that is
449
+ not otherwise registered. A worker can only have one dynamic workflow. It is often useful to use `workflow_raw_args`
450
+ with this.
451
+ * `workflow_raw_args` - Have workflow arguments delivered to `execute` (and `initialize` if `workflow_init` in use) as
452
+ `Temporalio::Converters::RawValue`s. These are wrappers for the raw payloads that have not been decoded. They can be
453
+ decoded with `Temporalio::Workflow.payload_converter`. Using this with `*args` splat can be helpful in dynamic
454
+ situations.
455
+ * `workflow_failure_exception_type` - Accepts one or more exception classes that will be considered workflow failure
456
+ instead of task failure. See the "Exceptions" section later on what this means. This can be called multiple times.
457
+ * `workflow_query_attr_reader` - Is a helper that accepts one or more symbols for attributes to expose as `attr_reader`
458
+ _and_ `workflow_query`. This means it is a superset of `attr_reader` and will not work if also using `attr_reader` or
459
+ `attr_accessor`. If a writer is needed alongside this, use `attr_writer`.
460
+
461
+ The following protected class methods can be called just before defining instance methods to customize the
462
+ definition/behavior of the method:
463
+
464
+ * `workflow_init` - Mark an `initialize` method as needing the workflow start arguments. Otherwise, `initialize` must
465
+ accept no required arguments. This must be placed above the `initialize` method or it will fail.
466
+ * `workflow_signal` - Mark the next method as a workflow signal. The signal name is defaulted to the method name but can
467
+ be customized by the `name` kwarg. See the API documentation for more kwargs that can be set. Return values for
468
+ signals are discarded and exceptions raised in signal handlers are treated as if they occurred in the primary workflow
469
+ method. This also defines a class method of the same name to return the definition for use by clients.
470
+ * `workflow_query` - Mark the next method as a workflow query. The query name is defaulted to the method name but can
471
+ be customized by the `name` kwarg. See the API documentation for more kwargs that can be set. The result of the method
472
+ is the result of the query. Queries must never have any side effects, meaning they should never mutate state or try to
473
+ wait on anything. This also defines a class method of the same name to return the definition for use by clients.
474
+ * `workflow_update` - Mark the next method as a workflow update. The update name is defaulted to the method name but can
475
+ be customized by the `name` kwarg. See the API documentation for more kwargs that can be set. The result of the method
476
+ is the result of the update. This also defines a class method of the same name to return the definition for use by
477
+ clients.
478
+ * `workflow_update_validator` - Mark the next method as a validator to an update. This accepts a symbol for the
479
+ `workflow_update` method it validates. Validators are used to do early rejection of updates and must never have any
480
+ side effects, meaning they should never mutate state or try to wait on anything.
481
+
482
+ Workflows can be inherited, but subclass workflow-level decorators override superclass ones, and the same method can't
483
+ be decorated with different handler types/names in the hierarchy.
484
+
485
+ #### Running Workflows
486
+
487
+ To start a workflow from a client, you can `start_workflow` and use the resulting handle:
488
+
489
+ ```ruby
490
+ # Start the workflow
491
+ handle = my_client.start_workflow(
492
+ GreetingWorkflow,
493
+ { salutation: 'Hello', name: 'Temporal' },
494
+ id: 'my-workflow-id',
495
+ task_queue: 'my-task-queue'
496
+ )
497
+
498
+ # Check current greeting via query
499
+ puts "Current greeting: #{handle.query(GreetingWorkflow.current_greeting)}"
500
+
501
+ # Change the params via update
502
+ handle.execute_update(
503
+ GreetingWorkflow.update_greeting_params,
504
+ { salutation: 'Aloha', name: 'John' }
505
+ )
506
+
507
+ # Tell it to complete via signal
508
+ handle.signal(GreetingWorkflow.complete_with_greeting)
509
+
510
+ # Wait for workflow result
511
+ puts "Final greeting: #{handle.result}"
512
+ ```
196
513
 
197
- - Long running activities should regularly heartbeat and handle cancellation
198
- - Activities can only have positional arguments. Best practice is to only take a single argument
199
- that is an object/dataclass of fields that can be added to as needed.
514
+ Some things to note about the above code:
200
515
 
201
- #### Activity Context
516
+ * This uses the `GreetingWorkflow` workflow from the previous section.
517
+ * The output of this code is "Current greeting: Hello, Temporal!" and "Final greeting: Aloha, John!".
518
+ * ID and task queue are required for starting a workflow.
519
+ * Signal, query, and update calls here use the class methods created on the definition for safety. So if the
520
+ `update_greeting_params` method didn't exist or wasn't marked as an update, the code will fail client side before even
521
+ attempting the call. Static typing tooling may also take advantage of this for param/result type checking.
522
+ * A helper `execute_workflow` method is available on the client that is just `start_workflow` + handle `result`.
523
+
524
+ #### Invoking Activities
525
+
526
+ * Activities are executed with `Temporalio::Workflow.execute_activity`, which accepts the activity class or a
527
+ string/symbol activity name.
528
+ * Activity options are kwargs on the `execute_activity` method. Either `schedule_to_close_timeout` or
529
+ `start_to_close_timeout` must be set.
530
+ * Other options like `retry_policy`, `cancellation_type`, etc can also be set.
531
+ * The `cancellation` can be set to a `Cancellation` to send a cancel request to the activity. By default, the
532
+ `cancellation` is the overall `Temporalio::Workflow.cancellation` which is the overarching workflow cancellation.
533
+ * Activity failures are raised from the call as `Temporalio::Error::ActivityError`.
534
+ * `execute_local_activity` exists with mostly the same options for local activities.
535
+
536
+ #### Invoking Child Workflows
537
+
538
+ * Child workflows are started with `Temporalio::Workflow.start_child_workflow`, which accepts the workflow class or
539
+ string/symbol name, arguments, and other options.
540
+ * Result for `start_child_workflow` is a `Temporalio::Workflow::ChildWorkflowHandle` which has the `id`, the ability to
541
+ wait on the `result`, and the ability to `signal` the child.
542
+ * The `start_child_workflow` call does not complete until the start has been accepted by the server.
543
+ * A helper `execute_child_workflow` method is available that is just `start_child_workflow` + handle `result`.
544
+
545
+ #### Timers and Conditions
546
+
547
+ * A timer is represented by `Temporalio::Workflow.sleep`.
548
+ * Timers are also started on `Temporalio::Workflow.timeout`.
549
+ * _Technically_ `Kernel.sleep` and `Timeout.timeout` also delegate to the above calls, but the more explicit workflow
550
+ forms are encouraged because they accept more options and are not subject to Ruby standard library implementation
551
+ changes.
552
+ * Each timer accepts a `Cancellation`, but if none is given, it defaults to `Temporalio::Workflow.cancellation`.
553
+ * `Temporalio::Workflow.wait_condition` accepts a block that waits until the evaluated block result is truthy, then
554
+ returns the value.
555
+ * This function is invoked on each iteration of the internal event loop. This means it cannot have any side effects.
556
+ * This is commonly used for checking if a variable is changed from some other part of a workflow (e.g. a signal
557
+ handler).
558
+ * Each wait conditions accepts a `Cancellation`, but if none is given, it defaults to
559
+ `Temporalio::Workflow.cancellation`.
560
+
561
+ #### Workflow Fiber Scheduling and Cancellation
562
+
563
+ Workflows are backed by a custom, deterministic `Fiber::Scheduler`. All fiber calls inside a workflow use this scheduler
564
+ to ensure coroutines run deterministically.
565
+
566
+ Every workflow contains a `Temporalio::Cancellation` at `Temporalio::Workflow.cancellation`. This is canceled when the
567
+ workflow is canceled. For all workflow calls that accept a cancellation token, this is the default. So if a workflow is
568
+ waiting on `execute_activity` and the workflow is canceled, that cancellation will propagate to the waiting activity.
569
+
570
+ `Cancellation`s may be created to perform cancellation more specifically. A `Cancellation` token derived from the
571
+ workflow one can be created via `my_cancel, my_cancel_proc = Cancellation.new(Temporalio::Workflow.cancellation)`. Then
572
+ `my_cancel` can be passed as `cancellation` to cancel something more specifically when `my_cancel_proc.call` is invoked.
573
+
574
+ `Cancellation`s don't have to be derived from the workflow one, they can just be created standalone or "detached". This
575
+ is useful for executing, say, a cleanup activity in an `ensure` block that needs to run even on cancel. If the cleanup
576
+ activity had instead used the workflow cancellation or one derived from it, then on cancellation it would be cancelled
577
+ before it even started.
578
+
579
+ #### Workflow Futures
580
+
581
+ `Temporalio::Workflow::Future` can be used for running things in the background or concurrently. This is basically a
582
+ safe wrapper around `Fiber.schedule` for starting and `Workflow.wait_condition` for waiting.
583
+
584
+ Nothing uses futures by default, but they work with all workflow code/constructs. For instance, to run 3 activities and
585
+ wait for them all to complete, something like this can be written:
202
586
 
203
- Activity classes have access to `Temporalio::Activity::Context` via the `activity` method. Which
204
- itself provides access to useful methods, specifically:
587
+ ```ruby
588
+ # Start 3 activities in background
589
+ fut1 = Temporalio::Workflow::Future.new do
590
+ Temporalio::Workflow.execute_activity(MyActivity1, schedule_to_close_timeout: 300)
591
+ end
592
+ fut2 = Temporalio::Workflow::Future.new do
593
+ Temporalio::Workflow.execute_activity(MyActivity2, schedule_to_close_timeout: 300)
594
+ end
595
+ fut3 = Temporalio::Workflow::Future.new do
596
+ Temporalio::Workflow.execute_activity(MyActivity3, schedule_to_close_timeout: 300)
597
+ end
205
598
 
206
- - `info` - Returns the immutable info of the currently running activity
207
- - `heartbeat(*details)` - Record a heartbeat
208
- - `cancelled?` - Whether a cancellation has been requested on this activity
209
- - `shield` - Prevent cancel exception from being thrown during the provided block of code
599
+ # Wait for them all to complete
600
+ Temporalio::Workflow::Future.all_of(fut1, fut2, fut3).wait
210
601
 
211
- ##### Heartbeating and Cancellation
602
+ Temporalio::Workflow.logger.debug("Got: #{fut1.result}, #{fut2.result}, #{fut3.result}")
603
+ ```
212
604
 
213
- In order for a non-local activity to be notified of cancellation requests, it must call
214
- `activity.heartbeat`. It is strongly recommended that all but the fastest executing activities call
215
- this method regularly.
605
+ Or, say, to wait on the first of 5 activities or a timeout to complete:
216
606
 
217
- In addition to obtaining cancellation information, heartbeats also support detail data that is
218
- persisted on the server for retrieval during activity retry. If an activity calls
219
- `activity.heartbeat(123, 456)` and then fails and is retried, `activity.info.heartbeat_details` will
220
- return an array containing `123` and `456` on the next run.
607
+ ```ruby
608
+ # Start 5 activities
609
+ act_futs = 5.times.map do |i|
610
+ Temporalio::Workflow::Future.new do
611
+ Temporalio::Workflow.execute_activity(MyActivity, "my-arg-#{i}" schedule_to_close_timeout: 300)
612
+ end
613
+ end
614
+ # Start a timer
615
+ sleep_fut = Temporalio::Workflow::Future.new { Temporalio::Workflow.sleep(30) }
616
+
617
+ # Wait for first act result or sleep fut
618
+ act_result = Temporalio::Workflow::Future.any_of(sleep_fut, *act_futs).wait
619
+ # Fail if timer done first
620
+ raise Temporalio::Error::ApplicationError, 'Timer expired' if sleep_fut.done?
621
+ # Print act result otherwise
622
+ puts "Act result: #{act_result}"
623
+ ```
221
624
 
222
- A cancellation is implemented using the `Thread#raise` method, which will raise a
223
- `Temporalio::Error::ActivityCancelled` during the execution of an activity. This means that your code
224
- might get interrupted at any point and never complete. In order to protect critical parts of your
225
- activities wrap them in `activity.shield`:
625
+ There are several other details not covered here about futures, such as how exceptions are handled, how to use a setter
626
+ proc instead of a block, etc. See the API documentation for details.
627
+
628
+ #### Workflow Utilities
629
+
630
+ In addition to the pieces documented above, additional methods are available on `Temporalio::Workflow` that can be used
631
+ from workflows including:
632
+
633
+ * `in_workflow?` - Returns `true` if in the workflow or `false` otherwise. This is the only method on the class that can
634
+ be called outside of a workflow without raising an exception.
635
+ * `info` - Immutable workflow information.
636
+ * `logger` - A Ruby logger that adds contextual information and takes care not to log on replay.
637
+ * `metric_meter` - A metric meter for making custom metrics that adds contextual information and takes care not to
638
+ record on replay.
639
+ * `random` - A deterministic `Random` instance.
640
+ * `memo` - A read-only hash of the memo (updated via `upsert_memo`).
641
+ * `search_attributes` - A read-only `SearchAttributes` collection (updated via `upsert_search_attributes`).
642
+ * `now` - Current, deterministic UTC time for the workflow.
643
+ * `all_handlers_finished?` - Returns true when all signal and update handlers are done. Useful as
644
+ `Temporalio::Workflow.wait_condition { Temporalio::Workflow.all_handlers_finished? }` for making sure not to return
645
+ from the primary workflow method until all handlers are done.
646
+ * `patched` and `deprecate_patch` - Support for patch-based versioning inside the workflow.
647
+ * `continue_as_new_suggested` - Returns true when the server recommends performing a continue as new.
648
+ * `current_update_info` - Returns `Temporalio::Workflow::UpdateInfo` if the current code is inside an update, or nil
649
+ otherwise.
650
+ * `external_workflow_handle` - Obtain an handle to an external workflow for signalling or cancelling.
651
+ * `payload_converter` - Payload converter if needed for converting raw args.
652
+ * `signal_handlers`, `query_handlers`, and `update_handlers` - Hashes for the current set of handlers keyed by name (or
653
+ nil key for dynamic). `[]=` or `store` can be called on these to update the handlers, though defined handlers are
654
+ encouraged over runtime-set ones.
655
+
656
+ `Temporalio::Workflow::ContinueAsNewError` can be raised to continue-as-new the workflow. It accepts positional args and
657
+ defaults the workflow to the same as the current, though it can be changed with the `workflow` kwarg. See API
658
+ documentation for other details.
659
+
660
+ #### Workflow Exceptions
661
+
662
+ * Workflows can raise exceptions to fail the workflow/update or the "workflow task" (i.e. suspend the workflow, retrying
663
+ until code update allows it to continue).
664
+ * By default, exceptions that are instances of `Temporalio::Error::Failure` (or `Timeout::Error`) will fail the
665
+ workflow/update with that exception.
666
+ * For failing the workflow/update explicitly with a user exception, explicitly raise
667
+ `Temporalio::Error::ApplicationError`. This can be marked non-retryable or include details as needed.
668
+ * Other exceptions that come from activity execution, child execution, cancellation, etc are already instances of
669
+ `Temporalio::Error::Failure` and will fail the workflow/update if uncaught.
670
+ * By default, all other exceptions fail the "workflow task" which means the workflow/update will continually retry until
671
+ the code is fixed. This is helpful for bad code or other non-predictable exceptions. To actually fail the
672
+ workflow/update, use `Temporalio::Error::ApplicationError` as mentioned above.
673
+ * By default, all non-deterministic exceptions that are detected internally fail the "workflow task".
674
+
675
+ The default behavior can be customized at the worker level for all workflows via the
676
+ `workflow_failure_exception_types` worker option or per workflow via the `workflow_failure_exception_type` definition
677
+ method on the workflow itself. When a workflow encounters a "workflow task" fail (i.e. suspend), it will first check
678
+ either of these collections to see if the exception is an instance of any of the types and if so, will turn into a
679
+ workflow/update failure. As a special case, when a non-deterministic exception occurs and
680
+ `Temporalio::Workflow::NondeterminismError` is assignable to any of the types in the collection, that too
681
+ will turn into a workflow/update failure. However unlike other exceptions, non-deterministic exceptions that match
682
+ during update handlers become workflow failures not update failures because a non-deterministic exception is an
683
+ entire-workflow-failure situation.
684
+
685
+ #### Workflow Logic Constraints
686
+
687
+ Temporal Workflows [must be deterministic](https://docs.temporal.io/workflows#deterministic-constraints), which includes
688
+ Ruby workflows. This means there are several things workflows cannot do such as:
689
+
690
+ * Perform IO (network, disk, stdio, etc)
691
+ * Access/alter external mutable state
692
+ * Do any threading
693
+ * Do anything using the system clock (e.g. `Time.Now`)
694
+ * Make any random calls
695
+ * Make any not-guaranteed-deterministic calls
696
+
697
+ #### Workflow Testing
698
+
699
+ Workflow testing can be done in an integration-test fashion against a real server. However, it is hard to simulate
700
+ timeouts and other long time-based code. Using the time-skipping workflow test environment can help there.
701
+
702
+ A non-time-skipping `Temporalio::Testing::WorkflowEnvironment` can be started via `start_local` which supports all
703
+ standard Temporal features. It is actually a real Temporal server lazily downloaded on first use and run as a
704
+ subprocess in the background.
705
+
706
+ A time-skipping `Temporalio::Testing::WorkflowEnvironment` can be started via `start_time_skipping` which is a
707
+ reimplementation of the Temporal server with special time skipping capabilities. This too lazily downloads the process
708
+ to run when first called. Note, this class is not thread safe nor safe for use with independent tests. It can be reused,
709
+ but only for one test at a time because time skipping is locked/unlocked at the environment level. Note, the
710
+ time-skipping test server does not work on ARM-based processors at this time, though macOS ARM users can use it via the
711
+ built-in x64 translation in macOS.
712
+
713
+ ##### Automatic Time Skipping
714
+
715
+ Anytime a workflow result is waited on, the time-skipping server automatically advances to the next event it can. To
716
+ manually advance time before waiting on the result of the workflow, the `WorkflowEnvironment.sleep` method can be used
717
+ on the environment itself. If an activity is running, time-skipping is disabled.
718
+
719
+ Here's a simple example of a workflow that sleeps for 24 hours:
226
720
 
227
721
  ```ruby
228
- class ActivityWithCriticalLogic < Temporalio::Activity
722
+ require 'temporalio/workflow'
723
+
724
+ class WaitADayWorkflow < Temporalio::Workflow::Definition
229
725
  def execute
230
- activity.shield do
231
- run_business_critical_logic_1
232
- end
726
+ Temporalio::Workflow.sleep(1 * 24 * 60 * 60)
727
+ 'all done'
728
+ end
729
+ end
730
+ ```
233
731
 
234
- run_non_critical_logic
732
+ A regular integration test of this workflow on a normal server would be way too slow. However, the time-skipping server
733
+ automatically skips to the next event when we wait on the result. Here's a minitest for that workflow:
235
734
 
236
- activity.shield do
237
- run_business_critical_logic_2
735
+ ```ruby
736
+ class MyTest < Minitest::Test
737
+ def test_wait_a_day
738
+ Temporalio::Testing::WorkflowEnvironment.start_time_skipping do |env|
739
+ worker = Temporalio::Worker.new(
740
+ client: env.client,
741
+ task_queue: "tq-#{SecureRandom.uuid}",
742
+ workflows: [WaitADayWorkflow],
743
+ workflow_executor: Temporalio::Worker::WorkflowExecutor::ThreadPool.default
744
+ )
745
+ worker.run do
746
+ result = env.client.execute_workflow(
747
+ WaitADayWorkflow,
748
+ id: "wf-#{SecureRandom.uuid}",
749
+ task_queue: worker.task_queue
750
+ )
751
+ assert_equal 'all done', result
752
+ end
238
753
  end
239
754
  end
240
755
  end
241
756
  ```
242
757
 
243
- This will ensure that a cancellation request received while inside the `activity.shield` block will
244
- not raise an exception until that block finishes.
758
+ This test will run almost instantly. This is because by calling `execute_workflow` on our client, we are actually
759
+ calling `start_workflow` + handle `result`, and `result` automatically skips time as much as it can (basically until the
760
+ end of the workflow or until an activity is run).
761
+
762
+ To disable automatic time-skipping while waiting for a workflow result, run code inside a block passed to
763
+ `auto_time_skipping_disabled`.
764
+
765
+ ##### Manual Time Skipping
245
766
 
246
- In case the entire activity is considered critical, you can mark it as `shielded!` and ignore
247
- cancellation requests altogether:
767
+ Until a workflow is waited on, all time skipping in the time-skipping environment is done manually via
768
+ `WorkflowEnvironment.sleep`.
769
+
770
+ Here's a workflow that waits for a signal or times out:
248
771
 
249
772
  ```ruby
250
- class CriticalActivity < Temporalio::Activity
251
- shielded!
773
+ require 'temporalio/workflow'
252
774
 
775
+ class SignalWorkflow < Temporalio::Workflow::Definition
253
776
  def execute
254
- ...
777
+ Temporalio::Workflow.timeout(45) do
778
+ Temporalio::Workflow.wait_condition { @signal_received }
779
+ 'got signal'
780
+ rescue Timeout::Error
781
+ 'got timeout'
782
+ end
783
+ end
784
+
785
+ workflow_signal
786
+ def some_signal
787
+ @signal_received = true
255
788
  end
256
789
  end
257
790
  ```
258
791
 
259
- For any long-running activity using this approach it is recommended to periodically check
260
- `activity.cancelled?` flag and respond accordingly.
261
-
262
- Please note that your activities can also get cancelled during a worker shutdown process ([if
263
- configured accordingly](#worker-shutdown)).
792
+ To test a normal signal, you might:
264
793
 
265
- ## Dev Setup
794
+ ```ruby
795
+ class MyTest < Minitest::Test
796
+ def test_signal_workflow_success
797
+ Temporalio::Testing::WorkflowEnvironment.start_time_skipping do |env|
798
+ worker = Temporalio::Worker.new(
799
+ client: env.client,
800
+ task_queue: "tq-#{SecureRandom.uuid}",
801
+ workflows: [SignalWorkflow],
802
+ workflow_executor: Temporalio::Worker::WorkflowExecutor::ThreadPool.default
803
+ )
804
+ worker.run do
805
+ handle = env.client.start_workflow(
806
+ SignalWorkflow,
807
+ id: "wf-#{SecureRandom.uuid}",
808
+ task_queue: worker.task_queue
809
+ )
810
+ handle.signal(SignalWorkflow.some_signal)
811
+ assert_equal 'got signal', handle.result
812
+ end
813
+ end
814
+ end
815
+ end
816
+ ```
266
817
 
267
- Once you've forked/cloned the repository you want to make sure all the submodules are fetched as
268
- well. You can do that using:
818
+ But how would you test the timeout part? Like so:
269
819
 
270
- ```sh
271
- > git submodule update --recursive
820
+ ```ruby
821
+ class MyTest < Minitest::Test
822
+ def test_signal_workflow_timeout
823
+ Temporalio::Testing::WorkflowEnvironment.start_time_skipping do |env|
824
+ worker = Temporalio::Worker.new(
825
+ client: env.client,
826
+ task_queue: "tq-#{SecureRandom.uuid}",
827
+ workflows: [SignalWorkflow],
828
+ workflow_executor: Temporalio::Worker::WorkflowExecutor::ThreadPool.default
829
+ )
830
+ worker.run do
831
+ handle = env.client.start_workflow(
832
+ SignalWorkflow,
833
+ id: "wf-#{SecureRandom.uuid}",
834
+ task_queue: worker.task_queue
835
+ )
836
+ env.sleep(50)
837
+ assert_equal 'got timeout', handle.result
838
+ end
839
+ end
840
+ end
841
+ end
272
842
  ```
273
843
 
274
- From there you should be able to install all the Ruby gems using:
844
+ This test will run almost instantly. The `env.sleep(50)` manually skips 50 seconds of time, allowing the timeout to be
845
+ triggered without actually waiting the full 45 seconds to time out.
275
846
 
276
- ```sh
277
- > bundle install
278
- ```
847
+ ##### Mocking Activities
279
848
 
280
- In order to compile the Rust Bridge you need to have `rust`, `cargo` and `rustup` installed. You
281
- will also need to install the `rustfmt` component:
849
+ When testing workflows, often you don't want to actually run the activities. Activities are just classes that extend
850
+ `Temporalio::Activity::Definition`. Simply write different/empty/fake/asserting ones and pass those to the worker to
851
+ have different activities called during the test. You may need to use `activity_name :MyRealActivityClassName` inside
852
+ the mock activity class to make it appear as the real name.
282
853
 
283
- ```sh
284
- > rustup component add rustfmt
285
- ```
854
+ #### Workflow Replay
286
855
 
287
- Now you should be able to compile a dev build of the Bridge:
856
+ TODO: Workflow replayer not yet implemented
288
857
 
289
- ```sh
290
- > bundle exec rake bridge:build
291
- ```
858
+ ### Activities
292
859
 
293
- You can then run all the specs against a dev build using:
860
+ #### Activity Definition
294
861
 
295
- ```sh
296
- > bundle exec rspec
862
+ Activities can be defined in a few different ways. They are usually classes, but manual definitions are supported too.
863
+
864
+ Here is a common activity definition:
865
+
866
+ ```ruby
867
+ class FindUserActivity < Temporalio::Activity::Definition
868
+ def execute(user_id)
869
+ User.find(user_id)
870
+ end
871
+ end
297
872
  ```
298
873
 
299
- And open an IRB session using:
874
+ Activities are defined as classes that extend `Temporalio::Activity::Definition` and provide an `execute` method. When
875
+ this activity is provided to the worker as a _class_ (e.g. `activities: [FindUserActivity]`), it will be instantiated
876
+ for _every attempt_. Many users may prefer using the same instance across activities, for example:
877
+
878
+ ```ruby
879
+ class FindUserActivity < Temporalio::Activity
880
+ def initialize(db)
881
+ @db = db
882
+ end
300
883
 
301
- ```sh
302
- > bundle console
884
+ def execute(user_id)
885
+ @db[:users].first(id: user_id)
886
+ end
887
+ end
303
888
  ```
889
+
890
+ When this is provided to a worker as an instance of the activity (e.g. `activities: [FindUserActivity.new(my_db)]`) then
891
+ the same instance is reused for each activity.
892
+
893
+ Some notes about activity definition:
894
+
895
+ * Temporal activities are identified by their name (or sometimes referred to as "activity type"). This defaults to the
896
+ unqualified class name of the activity, but can be customized by calling the `activity_name` class method.
897
+ * Long running activities should heartbeat regularly, see "Activity Heartbeating and Cancellation" later.
898
+ * By default every activity attempt is executed in a thread on a thread pool, but fibers are also supported. See
899
+ "Activity Concurrency and Executors" section later for more details.
900
+ * Technically an activity definition can be created manually via `Temporalio::Activity::Definition::Info.new` that
901
+ accepts a proc or a block, but the class form is recommended.
902
+ * `activity_dynamic` can be used to mark an activity dynamic. Dynamic activities do not have names and handle any
903
+ activity that is not otherwise registered. A worker can only have one dynamic activity.
904
+ * `workflow_raw_args` can be used to have activity arguments delivered to `execute` as
905
+ `Temporalio::Converters::RawValue`s. These are wrappers for the raw payloads that have not been converted to types
906
+ (but they have been decoded by the codec if present). They can be converted with `payload_converter` on the context.
907
+
908
+ #### Activity Context
909
+
910
+ When running in an activity, the `Temporalio::Activity::Context` is available via
911
+ `Temporalio::Activity::Context.current` which is backed by a thread/fiber local. In addition to other more advanced
912
+ things, this context provides:
913
+
914
+ * `info` - Information about the running activity.
915
+ * `heartbeat` - Method to call to issue an activity heartbeat (see "Activity Heartbeating and Cancellation" later).
916
+ * `cancellation` - Instance of `Temporalio::Cancellation` canceled when an activity is canceled (see
917
+ "Activity Heartbeating and Cancellation" later).
918
+ * `worker_shutdown_cancellation` - Instance of `Temporalio::Cancellation` canceled when worker is shutting down (see
919
+ "Activity Worker Shutdown" later).
920
+ * `logger` - Logger that automatically appends a hash with some activity info to every message.
921
+
922
+ #### Activity Heartbeating and Cancellation
923
+
924
+ In order for a non-local activity to be notified of server-side cancellation requests, it must regularly invoke
925
+ `heartbeat` on the `Temporalio::Activity::Context` instance (available via `Temporalio::Activity::Context.current`). It
926
+ is strongly recommended that all but the fastest executing activities call this function regularly.
927
+
928
+ In addition to obtaining cancellation information, heartbeats also support detail data that is persisted on the server
929
+ for retrieval during activity retry. If an activity calls `heartbeat(123)` and then fails and is retried,
930
+ `Temporalio::Activity::Context.current.info.heartbeat_details.first` will be `123`.
931
+
932
+ An activity can be canceled for multiple reasons, some server-side and some worker side. Server side cancellation
933
+ reasons include workflow canceling the activity, workflow completing, or activity timing out. On the worker side, the
934
+ activity can be canceled on worker shutdown (see next section). By default cancellation is relayed two ways - by marking
935
+ the `cancellation` on `Temporalio::Activity::Context` as canceled, and by issuing a `Thread.raise` or `Fiber.raise` with
936
+ the `Temporalio::Error::CanceledError`.
937
+
938
+ The `raise`-by-default approach was chosen because it is dangerous to the health of the system and the continued use of
939
+ worker slots to require activities opt-in to checking for cancellation by default. But if this behavior is not wanted,
940
+ `activity_cancel_raise false` class method can be called at the top of the activity which will disable the `raise`
941
+ behavior and just set the `cancellation` as canceled.
942
+
943
+ If needing to shield work from being canceled, the `shield` call on the `Temporalio::Cancellation` object can be used
944
+ with a block for the code to be shielded. The cancellation will not take effect on the cancellation object nor the raise
945
+ call while the work is shielded (regardless of nested depth). Once the shielding is complete, the cancellation will take
946
+ effect, including `Thread.raise`/`Fiber.raise` if that remains enabled.
947
+
948
+ #### Activity Worker Shutdown
949
+
950
+ An activity can react to a worker shutdown specifically and also a normal cancellation will be sent. A worker will not
951
+ complete its shutdown while an activity is in progress.
952
+
953
+ Upon worker shutdown, the `worker_shutdown_cancellation` cancellation on `Temporalio::Activity::Context` will be
954
+ canceled. Then the worker will wait a for a grace period set by the `graceful_shutdown_period` worker option (default 0)
955
+ before issuing actual cancellation to all still-running activities.
956
+
957
+ Worker shutdown will then wait on all activities to complete. If a long-running activity does not respect cancellation,
958
+ the shutdown may never complete.
959
+
960
+ #### Activity Concurrency and Executors
961
+
962
+ By default, activities run in the "thread pool executor" (i.e. `Temporalio::Worker::ActivityExecutor::ThreadPool`). This
963
+ default is shared across all workers and is a naive thread pool that continually makes threads as needed when none are
964
+ idle/available to handle incoming work. If a thread sits idle long enough, it will be killed.
965
+
966
+ The maximum number of concurrent activities a worker will run at a time is configured via its `tuner` option. The
967
+ default is `Temporalio::Worker::Tuner.create_fixed` which defaults to 100 activities at a time for that worker. When
968
+ this value is reached, the worker will stop asking for work from the server until there are slots available again.
969
+
970
+ In addition to the thread pool executor, there is also a fiber executor in the default executor set. To use fibers, call
971
+ `activity_executor :fiber` class method at the top of the activity class (the default of this value is `:default` which
972
+ is the thread pool executor). Activities can only choose the fiber executor if the worker has been created and run in a
973
+ fiber, but thread pool executor is always available. Currently due to
974
+ [an issue](https://github.com/temporalio/sdk-ruby/issues/162), workers can only run in a fiber on Ruby versions 3.3 and
975
+ newer.
976
+
977
+ Technically the executor can be customized. The `activity_executors` worker option accepts a hash with the key as the
978
+ symbol and the value as a `Temporalio::Worker::ActivityExecutor` implementation. Users should usually not need to
979
+ customize this. If general code is needed to run around activities, users should use interceptors instead.
980
+
981
+ #### Activity Testing
982
+
983
+ Unit testing an activity can be done via the `Temporalio::Testing::ActivityEnvironment` class. Simply instantiate the
984
+ class, then invoke `run` with the activity to test and the arguments to give. The result will be the activity result or
985
+ it will raise the error raised in the activity.
986
+
987
+ The constructor of the environment has multiple keyword arguments that can be set to affect the activity context for the
988
+ activity.
989
+
990
+ ### Ractors
991
+
992
+ It was an original goal to have workflows actually be Ractors for deterministic state isolation and have the library
993
+ support Ractors in general. However, due to the SDK's heavy use of the Google Protobuf library which
994
+ [is not Ractor-safe](https://github.com/protocolbuffers/protobuf/issues/19321), the Temporal Ruby SDK does not currently
995
+ work with Ractors.
996
+
997
+ ### Platform Support
998
+
999
+ This SDK is backed by a Ruby C extension written in Rust leveraging the
1000
+ [Temporal Rust Core](https://github.com/temporalio/sdk-core). Gems are currently published for the following platforms:
1001
+
1002
+ * `aarch64-linux`
1003
+ * `x86_64-linux`
1004
+ * `arm64-darwin`
1005
+ * `x86_64-darwin`
1006
+
1007
+ This means Linux and macOS for ARM and x64 have published gems. Currently, a gem is not published for
1008
+ `aarch64-linux-musl` so Alpine Linux users may need to build from scratch or use a libc-based distro.
1009
+
1010
+ Due to [an issue](https://github.com/temporalio/sdk-ruby/issues/172) with Windows and multi-threaded Rust, MinGW-based
1011
+ Windows (i.e. `x64-mingw-ucrt`) is not supported. But WSL is supported using the normal Linux gem.
1012
+
1013
+ At this time a pure source gem is published for documentation reasons, but it cannot be built and will fail if tried.
1014
+ Building from source requires many files across submodules and requires Rust to be installed. See the [Build](#build)
1015
+ section for how to build a the repository.
1016
+
1017
+ The SDK works on Ruby 3.1+, but due to [an issue](https://github.com/temporalio/sdk-ruby/issues/162), fibers (and
1018
+ `async` gem) are only supported on Ruby versions 3.3 and newer.
1019
+
1020
+ ## Development
1021
+
1022
+ ### Build
1023
+
1024
+ Prerequisites:
1025
+
1026
+ * [Ruby](https://www.ruby-lang.org/) >= 3.1 (i.e. `ruby` and `bundle` on the `PATH`)
1027
+ * [Rust](https://www.rust-lang.org/) latest stable (i.e. `cargo` on the `PATH`)
1028
+ * This repository, cloned recursively
1029
+ * Change to the `temporalio/` directory
1030
+
1031
+ First, install dependencies:
1032
+
1033
+ bundle install
1034
+
1035
+ To build shared library for development use:
1036
+
1037
+ bundle exec rake compile
1038
+
1039
+ **NOTE**: This will make the current directory usable for the current Ruby version by putting the shared library
1040
+ `lib/temporalio/internal/bridge/temporalio_bridge.<ext>` in the proper place. But this development shared library may
1041
+ not work for other Ruby versions or other OS/arch combinations. For that, see "Build Platform-specific Gem" below.
1042
+
1043
+ **NOTE**: This is not `compile:dev` because debug-mode in Rust has
1044
+ [an issue](https://github.com/rust-lang/rust/issues/34283) that causes runtime stack size problems.
1045
+
1046
+ To lint, build, and test:
1047
+
1048
+ bundle exec rake
1049
+
1050
+ #### Build Platform-specific Gem
1051
+
1052
+ The standard `bundle exec rake build` will produce a gem in the `pkg` directory, but that gem will not be usable because
1053
+ the shared library is not present (neither the Rust code nor the compiled form). To create a platform-specific gem that
1054
+ can be used, `rb-sys-dock` must be run. See the
1055
+ [Cross-Compilation documentation](https://oxidize-rb.github.io/rb-sys/tutorial/publishing/cross-compilation.html) in the
1056
+ `rb-sys` repository. For example, running:
1057
+
1058
+ bundle exec rb-sys-dock --platform x86_64-linux --ruby-versions 3.2,3.3 --build
1059
+
1060
+ Will create a `pkg/temporalio-<version>-x86_64-linux.gem` file that can be used in x64 Linux environments on both Ruby
1061
+ 3.2 and Ruby 3.3 because it contains the shared libraries. For this specific example, the shared libraries are inside
1062
+ the gem at `lib/temporalio/internal/bridge/3.2/temporalio_bridge.so` and
1063
+ `lib/temporalio/internal/bridge/3.3/temporalio_bridge.so`.
1064
+
1065
+ ### Testing
1066
+
1067
+ This project uses `minitest`. To test:
1068
+
1069
+ bundle exec rake test
1070
+
1071
+ Can add options via `TESTOPTS`. E.g. single test:
1072
+
1073
+ bundle exec rake test TESTOPTS="--name=test_some_method"
1074
+
1075
+ E.g. all starting with prefix:
1076
+
1077
+ bundle exec rake test TESTOPTS="--name=/^test_some_method_prefix/"
1078
+
1079
+ E.g. all for a class:
1080
+
1081
+ bundle exec rake test TESTOPTS="--name=/SomeClassName/"
1082
+
1083
+ E.g. show all test names while executing:
1084
+
1085
+ bundle exec rake test TESTOPTS="--verbose"
1086
+
1087
+ ### Code Formatting and Type Checking
1088
+
1089
+ This project uses `rubocop`:
1090
+
1091
+ bundle exec rake rubocop:autocorrect
1092
+
1093
+ This project uses `steep`. First may need the RBS collection:
1094
+
1095
+ bundle exec rake rbs:install_collection
1096
+
1097
+ Now can run `steep`:
1098
+
1099
+ bundle exec rake steep
1100
+
1101
+ ### Proto Generation
1102
+
1103
+ Run:
1104
+
1105
+ bundle exec rake proto:generate