temporalio 0.0.1 → 0.1.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 (310) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +180 -7
  3. data/bridge/Cargo.lock +208 -76
  4. data/bridge/Cargo.toml +5 -2
  5. data/bridge/sdk-core/Cargo.toml +1 -1
  6. data/bridge/sdk-core/README.md +20 -10
  7. data/bridge/sdk-core/client/Cargo.toml +1 -1
  8. data/bridge/sdk-core/client/src/lib.rs +227 -59
  9. data/bridge/sdk-core/client/src/metrics.rs +17 -8
  10. data/bridge/sdk-core/client/src/raw.rs +13 -12
  11. data/bridge/sdk-core/client/src/retry.rs +132 -43
  12. data/bridge/sdk-core/core/Cargo.toml +28 -15
  13. data/bridge/sdk-core/core/benches/workflow_replay.rs +13 -10
  14. data/bridge/sdk-core/core/src/abstractions.rs +225 -36
  15. data/bridge/sdk-core/core/src/core_tests/activity_tasks.rs +217 -79
  16. data/bridge/sdk-core/core/src/core_tests/determinism.rs +165 -2
  17. data/bridge/sdk-core/core/src/core_tests/local_activities.rs +565 -34
  18. data/bridge/sdk-core/core/src/core_tests/queries.rs +247 -90
  19. data/bridge/sdk-core/core/src/core_tests/workers.rs +3 -5
  20. data/bridge/sdk-core/core/src/core_tests/workflow_cancels.rs +1 -1
  21. data/bridge/sdk-core/core/src/core_tests/workflow_tasks.rs +430 -67
  22. data/bridge/sdk-core/core/src/ephemeral_server/mod.rs +106 -12
  23. data/bridge/sdk-core/core/src/internal_flags.rs +136 -0
  24. data/bridge/sdk-core/core/src/lib.rs +148 -34
  25. data/bridge/sdk-core/core/src/protosext/mod.rs +1 -1
  26. data/bridge/sdk-core/core/src/replay/mod.rs +185 -41
  27. data/bridge/sdk-core/core/src/telemetry/log_export.rs +190 -0
  28. data/bridge/sdk-core/core/src/telemetry/metrics.rs +219 -140
  29. data/bridge/sdk-core/core/src/telemetry/mod.rs +326 -315
  30. data/bridge/sdk-core/core/src/telemetry/prometheus_server.rs +20 -14
  31. data/bridge/sdk-core/core/src/test_help/mod.rs +85 -21
  32. data/bridge/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +112 -156
  33. data/bridge/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +89 -0
  34. data/bridge/sdk-core/core/src/worker/activities/local_activities.rs +364 -128
  35. data/bridge/sdk-core/core/src/worker/activities.rs +263 -170
  36. data/bridge/sdk-core/core/src/worker/client/mocks.rs +23 -3
  37. data/bridge/sdk-core/core/src/worker/client.rs +48 -6
  38. data/bridge/sdk-core/core/src/worker/mod.rs +186 -75
  39. data/bridge/sdk-core/core/src/worker/workflow/bridge.rs +1 -3
  40. data/bridge/sdk-core/core/src/worker/workflow/driven_workflow.rs +13 -24
  41. data/bridge/sdk-core/core/src/worker/workflow/history_update.rs +879 -226
  42. data/bridge/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +101 -48
  43. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +8 -12
  44. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +6 -9
  45. data/bridge/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +90 -32
  46. data/bridge/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +6 -9
  47. data/bridge/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +7 -10
  48. data/bridge/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +6 -9
  49. data/bridge/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +160 -83
  50. data/bridge/sdk-core/core/src/worker/workflow/machines/mod.rs +36 -54
  51. data/bridge/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +179 -0
  52. data/bridge/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +104 -157
  53. data/bridge/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +8 -12
  54. data/bridge/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +9 -13
  55. data/bridge/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +10 -4
  56. data/bridge/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +14 -11
  57. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +6 -17
  58. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +395 -299
  59. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +12 -20
  60. data/bridge/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +33 -18
  61. data/bridge/sdk-core/core/src/worker/workflow/managed_run.rs +1032 -374
  62. data/bridge/sdk-core/core/src/worker/workflow/mod.rs +525 -392
  63. data/bridge/sdk-core/core/src/worker/workflow/run_cache.rs +40 -57
  64. data/bridge/sdk-core/core/src/worker/workflow/wft_extraction.rs +125 -0
  65. data/bridge/sdk-core/core/src/worker/workflow/wft_poller.rs +3 -6
  66. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +117 -0
  67. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +24 -0
  68. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream.rs +456 -681
  69. data/bridge/sdk-core/core-api/Cargo.toml +6 -4
  70. data/bridge/sdk-core/core-api/src/errors.rs +1 -34
  71. data/bridge/sdk-core/core-api/src/lib.rs +7 -45
  72. data/bridge/sdk-core/core-api/src/telemetry.rs +141 -0
  73. data/bridge/sdk-core/core-api/src/worker.rs +27 -1
  74. data/bridge/sdk-core/etc/deps.svg +115 -140
  75. data/bridge/sdk-core/etc/regen-depgraph.sh +5 -0
  76. data/bridge/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +18 -15
  77. data/bridge/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +1 -1
  78. data/bridge/sdk-core/fsm/rustfsm_trait/src/lib.rs +8 -3
  79. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-16_history.bin +0 -0
  80. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-23_history.bin +0 -0
  81. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-85_history.bin +0 -0
  82. data/bridge/sdk-core/protos/api_upstream/buf.yaml +0 -3
  83. data/bridge/sdk-core/protos/api_upstream/build/go.mod +7 -0
  84. data/bridge/sdk-core/protos/api_upstream/build/go.sum +5 -0
  85. data/bridge/sdk-core/protos/api_upstream/{temporal/api/enums/v1/cluster.proto → build/tools.go} +7 -18
  86. data/bridge/sdk-core/protos/api_upstream/go.mod +6 -0
  87. data/bridge/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +12 -9
  88. data/bridge/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +15 -26
  89. data/bridge/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +13 -2
  90. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +3 -2
  91. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +4 -9
  92. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +3 -2
  93. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +10 -8
  94. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +28 -2
  95. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +2 -2
  96. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/query.proto +2 -2
  97. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +2 -2
  98. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +2 -2
  99. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +2 -2
  100. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +24 -19
  101. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +2 -2
  102. data/bridge/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +2 -2
  103. data/bridge/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +2 -2
  104. data/bridge/sdk-core/protos/api_upstream/temporal/api/filter/v1/message.proto +2 -2
  105. data/bridge/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +62 -26
  106. data/bridge/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +4 -2
  107. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +24 -61
  108. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +2 -21
  109. data/bridge/sdk-core/protos/api_upstream/temporal/api/protocol/v1/message.proto +57 -0
  110. data/bridge/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +2 -2
  111. data/bridge/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +2 -2
  112. data/bridge/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +110 -31
  113. data/bridge/sdk-core/protos/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +63 -0
  114. data/bridge/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +4 -4
  115. data/bridge/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +71 -6
  116. data/bridge/sdk-core/protos/api_upstream/temporal/api/version/v1/message.proto +2 -2
  117. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +3 -2
  118. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +111 -36
  119. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +19 -5
  120. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +1 -0
  121. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +1 -0
  122. data/bridge/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +1 -0
  123. data/bridge/sdk-core/protos/local/temporal/sdk/core/common/common.proto +1 -0
  124. data/bridge/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +1 -0
  125. data/bridge/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +1 -0
  126. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +9 -0
  127. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +9 -1
  128. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +6 -0
  129. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +2 -2
  130. data/bridge/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +2 -2
  131. data/bridge/sdk-core/sdk/Cargo.toml +4 -3
  132. data/bridge/sdk-core/sdk/src/interceptors.rs +36 -3
  133. data/bridge/sdk-core/sdk/src/lib.rs +94 -25
  134. data/bridge/sdk-core/sdk/src/workflow_context.rs +13 -2
  135. data/bridge/sdk-core/sdk/src/workflow_future.rs +10 -13
  136. data/bridge/sdk-core/sdk-core-protos/Cargo.toml +5 -2
  137. data/bridge/sdk-core/sdk-core-protos/build.rs +36 -2
  138. data/bridge/sdk-core/sdk-core-protos/src/history_builder.rs +164 -104
  139. data/bridge/sdk-core/sdk-core-protos/src/history_info.rs +27 -23
  140. data/bridge/sdk-core/sdk-core-protos/src/lib.rs +252 -74
  141. data/bridge/sdk-core/sdk-core-protos/src/task_token.rs +12 -2
  142. data/bridge/sdk-core/test-utils/Cargo.toml +4 -1
  143. data/bridge/sdk-core/test-utils/src/canned_histories.rs +106 -296
  144. data/bridge/sdk-core/test-utils/src/histfetch.rs +1 -1
  145. data/bridge/sdk-core/test-utils/src/lib.rs +161 -50
  146. data/bridge/sdk-core/test-utils/src/wf_input_saver.rs +50 -0
  147. data/bridge/sdk-core/test-utils/src/workflows.rs +29 -0
  148. data/bridge/sdk-core/tests/fuzzy_workflow.rs +130 -0
  149. data/bridge/sdk-core/tests/{load_tests.rs → heavy_tests.rs} +125 -51
  150. data/bridge/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +25 -3
  151. data/bridge/sdk-core/tests/integ_tests/heartbeat_tests.rs +10 -5
  152. data/bridge/sdk-core/tests/integ_tests/metrics_tests.rs +239 -0
  153. data/bridge/sdk-core/tests/integ_tests/polling_tests.rs +4 -60
  154. data/bridge/sdk-core/tests/integ_tests/queries_tests.rs +5 -128
  155. data/bridge/sdk-core/tests/integ_tests/visibility_tests.rs +83 -25
  156. data/bridge/sdk-core/tests/integ_tests/workflow_tests/activities.rs +93 -69
  157. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -0
  158. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +6 -13
  159. data/bridge/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +1 -0
  160. data/bridge/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +6 -2
  161. data/bridge/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -10
  162. data/bridge/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +151 -116
  163. data/bridge/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +54 -0
  164. data/bridge/sdk-core/tests/integ_tests/workflow_tests/patches.rs +7 -28
  165. data/bridge/sdk-core/tests/integ_tests/workflow_tests/replay.rs +115 -24
  166. data/bridge/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -0
  167. data/bridge/sdk-core/tests/integ_tests/workflow_tests/signals.rs +18 -14
  168. data/bridge/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +6 -20
  169. data/bridge/sdk-core/tests/integ_tests/workflow_tests/timers.rs +10 -21
  170. data/bridge/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +6 -4
  171. data/bridge/sdk-core/tests/integ_tests/workflow_tests.rs +27 -18
  172. data/bridge/sdk-core/tests/main.rs +8 -16
  173. data/bridge/sdk-core/tests/runner.rs +75 -36
  174. data/bridge/sdk-core/tests/wf_input_replay.rs +32 -0
  175. data/bridge/src/connection.rs +117 -82
  176. data/bridge/src/lib.rs +356 -42
  177. data/bridge/src/runtime.rs +10 -3
  178. data/bridge/src/test_server.rs +153 -0
  179. data/bridge/src/worker.rs +133 -9
  180. data/lib/gen/temporal/api/batch/v1/message_pb.rb +8 -6
  181. data/lib/gen/temporal/api/command/v1/message_pb.rb +10 -16
  182. data/lib/gen/temporal/api/common/v1/message_pb.rb +5 -1
  183. data/lib/gen/temporal/api/enums/v1/batch_operation_pb.rb +2 -1
  184. data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +3 -3
  185. data/lib/gen/temporal/api/enums/v1/common_pb.rb +2 -1
  186. data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +5 -4
  187. data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +9 -1
  188. data/lib/gen/temporal/api/enums/v1/namespace_pb.rb +1 -1
  189. data/lib/gen/temporal/api/enums/v1/query_pb.rb +1 -1
  190. data/lib/gen/temporal/api/enums/v1/reset_pb.rb +1 -1
  191. data/lib/gen/temporal/api/enums/v1/schedule_pb.rb +1 -1
  192. data/lib/gen/temporal/api/enums/v1/task_queue_pb.rb +1 -1
  193. data/lib/gen/temporal/api/enums/v1/update_pb.rb +7 -10
  194. data/lib/gen/temporal/api/enums/v1/workflow_pb.rb +1 -1
  195. data/lib/gen/temporal/api/errordetails/v1/message_pb.rb +1 -1
  196. data/lib/gen/temporal/api/failure/v1/message_pb.rb +1 -1
  197. data/lib/gen/temporal/api/filter/v1/message_pb.rb +1 -1
  198. data/lib/gen/temporal/api/history/v1/message_pb.rb +34 -25
  199. data/lib/gen/temporal/api/namespace/v1/message_pb.rb +2 -1
  200. data/lib/gen/temporal/api/operatorservice/v1/request_response_pb.rb +14 -51
  201. data/lib/gen/temporal/api/operatorservice/v1/service_pb.rb +1 -1
  202. data/lib/gen/temporal/api/protocol/v1/message_pb.rb +30 -0
  203. data/lib/gen/temporal/api/query/v1/message_pb.rb +1 -1
  204. data/lib/gen/temporal/api/replication/v1/message_pb.rb +1 -1
  205. data/lib/gen/temporal/api/schedule/v1/message_pb.rb +22 -1
  206. data/lib/gen/temporal/api/sdk/v1/task_complete_metadata_pb.rb +23 -0
  207. data/lib/gen/temporal/api/taskqueue/v1/message_pb.rb +2 -2
  208. data/lib/gen/temporal/api/testservice/v1/request_response_pb.rb +49 -0
  209. data/lib/gen/temporal/api/testservice/v1/service_pb.rb +21 -0
  210. data/lib/gen/temporal/api/update/v1/message_pb.rb +49 -3
  211. data/lib/gen/temporal/api/version/v1/message_pb.rb +1 -1
  212. data/lib/gen/temporal/api/workflow/v1/message_pb.rb +2 -1
  213. data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +47 -20
  214. data/lib/gen/temporal/api/workflowservice/v1/service_pb.rb +1 -1
  215. data/lib/gen/temporal/sdk/core/activity_result/activity_result_pb.rb +13 -9
  216. data/lib/gen/temporal/sdk/core/activity_task/activity_task_pb.rb +10 -6
  217. data/lib/gen/temporal/sdk/core/child_workflow/child_workflow_pb.rb +13 -9
  218. data/lib/gen/temporal/sdk/core/common/common_pb.rb +7 -3
  219. data/lib/gen/temporal/sdk/core/core_interface_pb.rb +9 -3
  220. data/lib/gen/temporal/sdk/core/external_data/external_data_pb.rb +7 -3
  221. data/lib/gen/temporal/sdk/core/workflow_activation/workflow_activation_pb.rb +28 -21
  222. data/lib/gen/temporal/sdk/core/workflow_commands/workflow_commands_pb.rb +32 -24
  223. data/lib/gen/temporal/sdk/core/workflow_completion/workflow_completion_pb.rb +12 -5
  224. data/lib/temporalio/activity/context.rb +102 -0
  225. data/lib/temporalio/activity/info.rb +67 -0
  226. data/lib/temporalio/activity.rb +85 -0
  227. data/lib/temporalio/bridge/connect_options.rb +15 -0
  228. data/lib/temporalio/bridge/error.rb +8 -0
  229. data/lib/temporalio/bridge/retry_config.rb +24 -0
  230. data/lib/temporalio/bridge/tls_options.rb +19 -0
  231. data/lib/temporalio/bridge.rb +14 -0
  232. data/lib/{temporal → temporalio}/client/implementation.rb +57 -56
  233. data/lib/{temporal → temporalio}/client/workflow_handle.rb +35 -35
  234. data/lib/{temporal → temporalio}/client.rb +19 -32
  235. data/lib/temporalio/connection/retry_config.rb +44 -0
  236. data/lib/temporalio/connection/service.rb +20 -0
  237. data/lib/temporalio/connection/test_service.rb +92 -0
  238. data/lib/temporalio/connection/tls_options.rb +51 -0
  239. data/lib/temporalio/connection/workflow_service.rb +731 -0
  240. data/lib/temporalio/connection.rb +86 -0
  241. data/lib/{temporal → temporalio}/data_converter.rb +76 -35
  242. data/lib/{temporal → temporalio}/error/failure.rb +6 -6
  243. data/lib/{temporal → temporalio}/error/workflow_failure.rb +4 -2
  244. data/lib/{temporal → temporalio}/errors.rb +19 -1
  245. data/lib/{temporal → temporalio}/failure_converter/base.rb +5 -5
  246. data/lib/{temporal → temporalio}/failure_converter/basic.rb +58 -52
  247. data/lib/temporalio/failure_converter.rb +7 -0
  248. data/lib/temporalio/interceptor/activity_inbound.rb +22 -0
  249. data/lib/temporalio/interceptor/activity_outbound.rb +24 -0
  250. data/lib/{temporal → temporalio}/interceptor/chain.rb +7 -6
  251. data/lib/{temporal → temporalio}/interceptor/client.rb +27 -2
  252. data/lib/temporalio/interceptor.rb +22 -0
  253. data/lib/{temporal → temporalio}/payload_codec/base.rb +5 -5
  254. data/lib/{temporal → temporalio}/payload_converter/base.rb +3 -3
  255. data/lib/{temporal → temporalio}/payload_converter/bytes.rb +4 -3
  256. data/lib/{temporal → temporalio}/payload_converter/composite.rb +7 -5
  257. data/lib/{temporal → temporalio}/payload_converter/encoding_base.rb +4 -4
  258. data/lib/{temporal → temporalio}/payload_converter/json.rb +4 -3
  259. data/lib/{temporal → temporalio}/payload_converter/nil.rb +4 -3
  260. data/lib/temporalio/payload_converter.rb +14 -0
  261. data/lib/{temporal → temporalio}/retry_policy.rb +17 -7
  262. data/lib/{temporal → temporalio}/retry_state.rb +1 -1
  263. data/lib/temporalio/runtime.rb +25 -0
  264. data/lib/temporalio/testing/time_skipping_handle.rb +32 -0
  265. data/lib/temporalio/testing/time_skipping_interceptor.rb +23 -0
  266. data/lib/temporalio/testing/workflow_environment.rb +112 -0
  267. data/lib/temporalio/testing.rb +175 -0
  268. data/lib/{temporal → temporalio}/timeout_type.rb +2 -2
  269. data/lib/temporalio/version.rb +3 -0
  270. data/lib/temporalio/worker/activity_runner.rb +114 -0
  271. data/lib/temporalio/worker/activity_worker.rb +164 -0
  272. data/lib/temporalio/worker/reactor.rb +46 -0
  273. data/lib/temporalio/worker/runner.rb +63 -0
  274. data/lib/temporalio/worker/sync_worker.rb +124 -0
  275. data/lib/temporalio/worker/thread_pool_executor.rb +51 -0
  276. data/lib/temporalio/worker.rb +204 -0
  277. data/lib/temporalio/workflow/async.rb +46 -0
  278. data/lib/{temporal → temporalio}/workflow/execution_info.rb +4 -4
  279. data/lib/{temporal → temporalio}/workflow/execution_status.rb +1 -1
  280. data/lib/temporalio/workflow/future.rb +138 -0
  281. data/lib/{temporal → temporalio}/workflow/id_reuse_policy.rb +6 -6
  282. data/lib/temporalio/workflow/info.rb +76 -0
  283. data/lib/{temporal → temporalio}/workflow/query_reject_condition.rb +5 -5
  284. data/lib/temporalio.rb +12 -3
  285. data/temporalio.gemspec +11 -6
  286. metadata +137 -64
  287. data/bridge/sdk-core/Cargo.lock +0 -2606
  288. data/bridge/sdk-core/bridge-ffi/Cargo.toml +0 -24
  289. data/bridge/sdk-core/bridge-ffi/LICENSE.txt +0 -23
  290. data/bridge/sdk-core/bridge-ffi/build.rs +0 -25
  291. data/bridge/sdk-core/bridge-ffi/include/sdk-core-bridge.h +0 -249
  292. data/bridge/sdk-core/bridge-ffi/src/lib.rs +0 -825
  293. data/bridge/sdk-core/bridge-ffi/src/wrappers.rs +0 -211
  294. data/bridge/sdk-core/core/src/log_export.rs +0 -62
  295. data/bridge/sdk-core/core/src/worker/workflow/machines/mutable_side_effect_state_machine.rs +0 -127
  296. data/bridge/sdk-core/core/src/worker/workflow/machines/side_effect_state_machine.rs +0 -71
  297. data/bridge/sdk-core/protos/api_upstream/temporal/api/cluster/v1/message.proto +0 -83
  298. data/bridge/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +0 -210
  299. data/bridge/sdk-core/sdk/src/conversions.rs +0 -8
  300. data/lib/bridge.so +0 -0
  301. data/lib/gen/temporal/api/cluster/v1/message_pb.rb +0 -67
  302. data/lib/gen/temporal/api/enums/v1/cluster_pb.rb +0 -26
  303. data/lib/gen/temporal/sdk/core/bridge/bridge_pb.rb +0 -222
  304. data/lib/temporal/bridge.rb +0 -14
  305. data/lib/temporal/connection.rb +0 -736
  306. data/lib/temporal/failure_converter.rb +0 -8
  307. data/lib/temporal/payload_converter.rb +0 -14
  308. data/lib/temporal/runtime.rb +0 -22
  309. data/lib/temporal/version.rb +0 -3
  310. data/lib/temporal.rb +0 -8
@@ -1,19 +1,29 @@
1
1
  //! This module contains very generic helpers that can be used codebase-wide
2
2
 
3
3
  use crate::MetricsContext;
4
+ use derive_more::DebugCustom;
4
5
  use futures::{stream, Stream, StreamExt};
6
+ use std::sync::atomic::AtomicBool;
5
7
  use std::{
6
8
  fmt::{Debug, Formatter},
7
- future::Future,
8
- sync::Arc,
9
+ sync::{
10
+ atomic::{AtomicUsize, Ordering},
11
+ Arc,
12
+ },
9
13
  };
10
- use tokio::sync::{AcquireError, Notify, OwnedSemaphorePermit, Semaphore, TryAcquireError};
14
+ use tokio::sync::{AcquireError, OwnedSemaphorePermit, Semaphore, TryAcquireError};
15
+ use tokio_util::sync::CancellationToken;
11
16
 
12
17
  /// Wraps a [Semaphore] with a function call that is fed the available permits any time a permit is
13
18
  /// acquired or restored through the provided methods
14
19
  #[derive(Clone)]
15
20
  pub(crate) struct MeteredSemaphore {
16
21
  sem: Arc<Semaphore>,
22
+ /// The number of permit owners who have acquired a permit from the semaphore, but are not yet
23
+ /// meaningfully using that permit. This is useful for giving a more semantically accurate count
24
+ /// of used task slots, since we typically wait for a permit first before polling, but that slot
25
+ /// isn't used in the sense the user expects until we actually also get the corresponding task.
26
+ unused_claimants: Arc<AtomicUsize>,
17
27
  metrics_ctx: MetricsContext,
18
28
  record_fn: fn(&MetricsContext, usize),
19
29
  }
@@ -26,6 +36,7 @@ impl MeteredSemaphore {
26
36
  ) -> Self {
27
37
  Self {
28
38
  sem: Arc::new(Semaphore::new(inital_permits)),
39
+ unused_claimants: Arc::new(AtomicUsize::new(0)),
29
40
  metrics_ctx,
30
41
  record_fn,
31
42
  }
@@ -37,42 +48,154 @@ impl MeteredSemaphore {
37
48
 
38
49
  pub async fn acquire_owned(&self) -> Result<OwnedMeteredSemPermit, AcquireError> {
39
50
  let res = self.sem.clone().acquire_owned().await?;
40
- self.record();
41
- Ok(OwnedMeteredSemPermit {
42
- inner: res,
43
- record_fn: self.record_drop_owned(),
44
- })
51
+ Ok(self.build_owned(res))
45
52
  }
46
53
 
47
54
  pub fn try_acquire_owned(&self) -> Result<OwnedMeteredSemPermit, TryAcquireError> {
48
55
  let res = self.sem.clone().try_acquire_owned()?;
56
+ Ok(self.build_owned(res))
57
+ }
58
+
59
+ fn build_owned(&self, res: OwnedSemaphorePermit) -> OwnedMeteredSemPermit {
60
+ self.unused_claimants.fetch_add(1, Ordering::Release);
49
61
  self.record();
50
- Ok(OwnedMeteredSemPermit {
62
+ OwnedMeteredSemPermit {
51
63
  inner: res,
52
- record_fn: self.record_drop_owned(),
53
- })
64
+ unused_claimants: Some(self.unused_claimants.clone()),
65
+ record_fn: self.record_owned(),
66
+ }
54
67
  }
55
68
 
56
69
  fn record(&self) {
57
- (self.record_fn)(&self.metrics_ctx, self.sem.available_permits());
70
+ (self.record_fn)(
71
+ &self.metrics_ctx,
72
+ self.sem.available_permits() + self.unused_claimants.load(Ordering::Acquire),
73
+ );
58
74
  }
59
75
 
60
- fn record_drop_owned(&self) -> Box<dyn Fn() + Send + Sync> {
76
+ fn record_owned(&self) -> Box<dyn Fn(bool) + Send + Sync> {
61
77
  let rcf = self.record_fn;
62
78
  let mets = self.metrics_ctx.clone();
63
79
  let sem = self.sem.clone();
64
- Box::new(move || rcf(&mets, sem.available_permits() + 1))
80
+ let uc = self.unused_claimants.clone();
81
+ // When being called from the drop impl, the semaphore permit isn't actually dropped yet,
82
+ // so account for that.
83
+ Box::new(move |add_one: bool| {
84
+ let extra = usize::from(add_one);
85
+ rcf(
86
+ &mets,
87
+ sem.available_permits() + uc.load(Ordering::Acquire) + extra,
88
+ )
89
+ })
90
+ }
91
+ }
92
+
93
+ /// A version of [MeteredSemaphore] that can be closed and supports waiting for close to complete.
94
+ /// Once closed, no permits will be handed out.
95
+ /// Close completes when all permits have been returned.
96
+ pub(crate) struct ClosableMeteredSemaphore {
97
+ inner: Arc<MeteredSemaphore>,
98
+ outstanding_permits: AtomicUsize,
99
+ close_requested: AtomicBool,
100
+ close_complete_token: CancellationToken,
101
+ }
102
+
103
+ impl ClosableMeteredSemaphore {
104
+ pub fn new_arc(sem: Arc<MeteredSemaphore>) -> Arc<Self> {
105
+ Arc::new(Self {
106
+ inner: sem,
107
+ outstanding_permits: Default::default(),
108
+ close_requested: AtomicBool::new(false),
109
+ close_complete_token: CancellationToken::new(),
110
+ })
111
+ }
112
+ }
113
+
114
+ impl ClosableMeteredSemaphore {
115
+ #[cfg(test)]
116
+ pub fn available_permits(&self) -> usize {
117
+ self.inner.available_permits()
118
+ }
119
+
120
+ /// Request to close the semaphore and prevent new permits from being acquired.
121
+ pub fn close(&self) {
122
+ self.close_requested.store(true, Ordering::Release);
123
+ if self.outstanding_permits.load(Ordering::Acquire) == 0 {
124
+ self.close_complete_token.cancel();
125
+ }
126
+ }
127
+
128
+ /// Returns after close has been requested and all outstanding permits have been returned.
129
+ pub async fn close_complete(&self) {
130
+ self.close_complete_token.cancelled().await;
131
+ }
132
+
133
+ /// Acquire a permit if one is available and close was not requested.
134
+ pub fn try_acquire_owned(
135
+ self: &Arc<Self>,
136
+ ) -> Result<TrackedOwnedMeteredSemPermit, TryAcquireError> {
137
+ if self.close_requested.load(Ordering::Acquire) {
138
+ return Err(TryAcquireError::Closed);
139
+ }
140
+ self.outstanding_permits.fetch_add(1, Ordering::Release);
141
+ let res = self.inner.try_acquire_owned();
142
+ if res.is_err() {
143
+ self.outstanding_permits.fetch_sub(1, Ordering::Release);
144
+ }
145
+ res.map(|permit| TrackedOwnedMeteredSemPermit {
146
+ inner: Some(permit),
147
+ on_drop: self.on_permit_dropped(),
148
+ })
149
+ }
150
+
151
+ fn on_permit_dropped(self: &Arc<Self>) -> Box<dyn Fn() + Send + Sync> {
152
+ let sem = self.clone();
153
+ Box::new(move || {
154
+ sem.outstanding_permits.fetch_sub(1, Ordering::Release);
155
+ if sem.close_requested.load(Ordering::Acquire)
156
+ && sem.outstanding_permits.load(Ordering::Acquire) == 0
157
+ {
158
+ sem.close_complete_token.cancel();
159
+ }
160
+ })
161
+ }
162
+ }
163
+
164
+ /// Tracks an OwnedMeteredSemPermit and calls on_drop when dropped.
165
+ #[derive(DebugCustom)]
166
+ #[debug(fmt = "Tracked({inner:?})")]
167
+ pub(crate) struct TrackedOwnedMeteredSemPermit {
168
+ inner: Option<OwnedMeteredSemPermit>,
169
+ on_drop: Box<dyn Fn() + Send + Sync>,
170
+ }
171
+ impl From<TrackedOwnedMeteredSemPermit> for OwnedMeteredSemPermit {
172
+ fn from(mut value: TrackedOwnedMeteredSemPermit) -> Self {
173
+ value
174
+ .inner
175
+ .take()
176
+ .expect("Inner permit should be available")
177
+ }
178
+ }
179
+ impl Drop for TrackedOwnedMeteredSemPermit {
180
+ fn drop(&mut self) {
181
+ (self.on_drop)();
65
182
  }
66
183
  }
67
184
 
68
185
  /// Wraps an [OwnedSemaphorePermit] to update metrics when it's dropped
69
186
  pub(crate) struct OwnedMeteredSemPermit {
70
187
  inner: OwnedSemaphorePermit,
71
- record_fn: Box<dyn Fn() + Send + Sync>,
188
+ /// See [MeteredSemaphore::unused_claimants]. If present when dropping, used to decrement the
189
+ /// count.
190
+ unused_claimants: Option<Arc<AtomicUsize>>,
191
+ record_fn: Box<dyn Fn(bool) + Send + Sync>,
72
192
  }
73
193
  impl Drop for OwnedMeteredSemPermit {
74
194
  fn drop(&mut self) {
75
- (self.record_fn)()
195
+ if let Some(uc) = self.unused_claimants.take() {
196
+ uc.fetch_sub(1, Ordering::Release);
197
+ }
198
+ (self.record_fn)(true)
76
199
  }
77
200
  }
78
201
  impl Debug for OwnedMeteredSemPermit {
@@ -80,26 +203,57 @@ impl Debug for OwnedMeteredSemPermit {
80
203
  self.inner.fmt(f)
81
204
  }
82
205
  }
206
+ impl OwnedMeteredSemPermit {
207
+ /// Should be called once this permit is actually being "used" for the work it was meant to
208
+ /// permit.
209
+ pub(crate) fn into_used(mut self) -> UsedMeteredSemPermit {
210
+ if let Some(uc) = self.unused_claimants.take() {
211
+ uc.fetch_sub(1, Ordering::Release);
212
+ (self.record_fn)(false)
213
+ }
214
+ UsedMeteredSemPermit(self)
215
+ }
216
+ }
217
+
218
+ #[derive(Debug)]
219
+ pub(crate) struct UsedMeteredSemPermit(OwnedMeteredSemPermit);
220
+ impl UsedMeteredSemPermit {
221
+ #[cfg(feature = "save_wf_inputs")]
222
+ pub(crate) fn fake_deserialized() -> Self {
223
+ let sem = Arc::new(Semaphore::new(1));
224
+ let inner = sem.try_acquire_owned().unwrap();
225
+ Self(OwnedMeteredSemPermit {
226
+ inner,
227
+ unused_claimants: None,
228
+ record_fn: Box::new(|_| {}),
229
+ })
230
+ }
231
+ }
83
232
 
84
233
  /// From the input stream, create a new stream which only pulls from the input stream when allowed.
85
- /// When allowed is determined by the passed in `proceeder` which must return a future every time
86
- /// it's called. The input stream is only pulled from when that future resolves.
87
- pub(crate) fn stream_when_allowed<S, F, FF>(
234
+ /// When allowed is determined by the passed in `proceeder` emitting an item. The input stream is
235
+ /// only pulled from when that future resolves.
236
+ ///
237
+ /// This is *almost* identical to `zip`, but does not terminate early if the input stream closes.
238
+ /// The proceeder must allow the poll before the returned stream closes. If the proceeder terminates
239
+ /// the overall stream will terminate.
240
+ pub(crate) fn stream_when_allowed<S, AS>(
88
241
  input: S,
89
- proceeder: FF,
90
- ) -> impl Stream<Item = (S::Item, F::Output)>
242
+ proceeder: AS,
243
+ ) -> impl Stream<Item = (S::Item, AS::Item)>
91
244
  where
92
245
  S: Stream + Send + 'static,
93
- F: Future,
94
- FF: FnMut() -> F,
246
+ AS: Stream + Send + 'static,
95
247
  {
96
- let acceptable_notify = Arc::new(Notify::new());
97
- acceptable_notify.notify_one();
98
248
  let stream = stream::unfold(
99
- (proceeder, input.boxed()),
249
+ (proceeder.boxed(), input.boxed()),
100
250
  |(mut proceeder, mut input)| async {
101
- let v = proceeder().await;
102
- input.next().await.map(|i| ((i, v), (proceeder, input)))
251
+ let v = proceeder.next().await;
252
+ if let Some(v) = v {
253
+ input.next().await.map(|i| ((i, v), (proceeder, input)))
254
+ } else {
255
+ None
256
+ }
103
257
  },
104
258
  );
105
259
  stream
@@ -108,7 +262,7 @@ where
108
262
  macro_rules! dbg_panic {
109
263
  ($($arg:tt)*) => {
110
264
  error!($($arg)*);
111
- debug_assert!(true, $($arg)*);
265
+ debug_assert!(false, $($arg)*);
112
266
  };
113
267
  }
114
268
  pub(crate) use dbg_panic;
@@ -117,19 +271,15 @@ pub(crate) use dbg_panic;
117
271
  mod tests {
118
272
  use super::*;
119
273
  use futures::pin_mut;
120
- use std::{cell::RefCell, task::Poll};
274
+ use std::task::Poll;
121
275
  use tokio::sync::mpsc::unbounded_channel;
276
+ use tokio_stream::wrappers::UnboundedReceiverStream;
122
277
 
123
- // This is fine. Test only / guaranteed to happen serially.
124
- #[allow(clippy::await_holding_refcell_ref)]
125
278
  #[test]
126
279
  fn stream_when_allowed_works() {
127
280
  let inputs = stream::iter([1, 2, 3]);
128
281
  let (allow_tx, allow_rx) = unbounded_channel();
129
- let allow_rx = RefCell::new(allow_rx);
130
- let when_allowed = stream_when_allowed(inputs, || async {
131
- allow_rx.borrow_mut().recv().await.unwrap()
132
- });
282
+ let when_allowed = stream_when_allowed(inputs, UnboundedReceiverStream::new(allow_rx));
133
283
 
134
284
  let waker = futures::task::noop_waker_ref();
135
285
  let mut cx = std::task::Context::from_waker(waker);
@@ -163,4 +313,43 @@ mod tests {
163
313
  allow_tx.send(()).unwrap();
164
314
  assert_eq!(when_allowed.poll_next_unpin(&mut cx), Poll::Ready(None));
165
315
  }
316
+
317
+ #[tokio::test]
318
+ async fn closable_semaphore_permit_drop_returns_permit() {
319
+ let inner = MeteredSemaphore::new(2, MetricsContext::no_op(), |_, _| {});
320
+ let sem = ClosableMeteredSemaphore::new_arc(Arc::new(inner));
321
+ let perm = sem.try_acquire_owned().unwrap();
322
+ let permits = sem.outstanding_permits.load(Ordering::Acquire);
323
+ assert_eq!(permits, 1);
324
+ drop(perm);
325
+ let permits = sem.outstanding_permits.load(Ordering::Acquire);
326
+ assert_eq!(permits, 0);
327
+ }
328
+
329
+ #[tokio::test]
330
+ async fn closable_semaphore_permit_drop_after_close_resolves_close_complete() {
331
+ let inner = MeteredSemaphore::new(2, MetricsContext::no_op(), |_, _| {});
332
+ let sem = ClosableMeteredSemaphore::new_arc(Arc::new(inner));
333
+ let perm = sem.try_acquire_owned().unwrap();
334
+ sem.close();
335
+ drop(perm);
336
+ sem.close_complete().await;
337
+ }
338
+
339
+ #[tokio::test]
340
+ async fn closable_semaphore_close_complete_ready_if_unused() {
341
+ let inner = MeteredSemaphore::new(2, MetricsContext::no_op(), |_, _| {});
342
+ let sem = ClosableMeteredSemaphore::new_arc(Arc::new(inner));
343
+ sem.close();
344
+ sem.close_complete().await;
345
+ }
346
+
347
+ #[tokio::test]
348
+ async fn closable_semaphore_does_not_hand_out_permits_after_closed() {
349
+ let inner = MeteredSemaphore::new(2, MetricsContext::no_op(), |_, _| {});
350
+ let sem = ClosableMeteredSemaphore::new_arc(Arc::new(inner));
351
+ sem.close();
352
+ let perm = sem.try_acquire_owned().unwrap_err();
353
+ assert_matches!(perm, TryAcquireError::Closed);
354
+ }
166
355
  }