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
@@ -2,16 +2,18 @@
2
2
 
3
3
  pub(crate) mod mocks;
4
4
 
5
- use temporal_client::{Client, RetryClient, WorkflowService, WorkflowTaskCompletion};
5
+ use temporal_client::{Client, RetryClient, WorkflowService};
6
6
  use temporal_sdk_core_protos::{
7
7
  coresdk::workflow_commands::QueryResult,
8
8
  temporal::api::{
9
- common::v1::{Payloads, WorkflowExecution},
9
+ command::v1::Command,
10
+ common::v1::{MeteringMetadata, Payloads, WorkflowExecution},
10
11
  enums::v1::{TaskQueueKind, WorkflowTaskFailedCause},
11
12
  failure::v1::Failure,
12
13
  query::v1::WorkflowQueryResult,
13
- taskqueue::v1::{TaskQueue, TaskQueueMetadata},
14
- workflowservice::v1::*,
14
+ sdk::v1::WorkflowTaskCompletedMetadata,
15
+ taskqueue::v1::{StickyExecutionAttributes, TaskQueue, TaskQueueMetadata, VersionId},
16
+ workflowservice::v1::{get_system_info_response::Capabilities, *},
15
17
  },
16
18
  TaskToken,
17
19
  };
@@ -108,6 +110,9 @@ pub(crate) trait WorkerClient: Sync + Send {
108
110
  task_token: TaskToken,
109
111
  query_result: QueryResult,
110
112
  ) -> Result<RespondQueryTaskCompletedResponse>;
113
+
114
+ #[allow(clippy::needless_lifetimes)] // Clippy is wrong here
115
+ fn capabilities<'a>(&'a self) -> Option<&'a get_system_info_response::Capabilities>;
111
116
  }
112
117
 
113
118
  #[async_trait::async_trait]
@@ -133,7 +138,9 @@ impl WorkerClient for WorkerClientBag {
133
138
  } else {
134
139
  self.worker_build_id.clone()
135
140
  },
136
- worker_versioning_build_id: self.versioning_build_id(),
141
+ worker_versioning_id: Some(VersionId {
142
+ worker_build_id: self.versioning_build_id(),
143
+ }),
137
144
  };
138
145
 
139
146
  Ok(self
@@ -159,7 +166,9 @@ impl WorkerClient for WorkerClientBag {
159
166
  task_queue_metadata: max_tasks_per_sec.map(|tps| TaskQueueMetadata {
160
167
  max_tasks_per_second: Some(tps),
161
168
  }),
162
- worker_versioning_build_id: self.versioning_build_id(),
169
+ worker_versioning_id: Some(VersionId {
170
+ worker_build_id: self.versioning_build_id(),
171
+ }),
163
172
  };
164
173
 
165
174
  Ok(self
@@ -181,6 +190,10 @@ impl WorkerClient for WorkerClientBag {
181
190
  sticky_attributes: request.sticky_attributes,
182
191
  return_new_workflow_task: request.return_new_workflow_task,
183
192
  force_create_new_workflow_task: request.force_create_new_workflow_task,
193
+ worker_versioning_id: Some(VersionId {
194
+ worker_build_id: self.versioning_build_id(),
195
+ }),
196
+ messages: vec![],
184
197
  binary_checksum: self.worker_build_id.clone(),
185
198
  query_results: request
186
199
  .query_responses
@@ -198,6 +211,8 @@ impl WorkerClient for WorkerClientBag {
198
211
  })
199
212
  .collect(),
200
213
  namespace: self.namespace.clone(),
214
+ sdk_metadata: Some(request.sdk_metadata),
215
+ metering_metadata: Some(request.metering_metadata),
201
216
  };
202
217
  Ok(self
203
218
  .client
@@ -294,6 +309,7 @@ impl WorkerClient for WorkerClientBag {
294
309
  identity: self.identity.clone(),
295
310
  binary_checksum: self.worker_build_id.clone(),
296
311
  namespace: self.namespace.clone(),
312
+ messages: vec![],
297
313
  };
298
314
  Ok(self
299
315
  .client
@@ -344,4 +360,30 @@ impl WorkerClient for WorkerClientBag {
344
360
  .await?
345
361
  .into_inner())
346
362
  }
363
+
364
+ fn capabilities(&self) -> Option<&Capabilities> {
365
+ self.client.get_client().inner().capabilities()
366
+ }
367
+ }
368
+
369
+ /// A version of [RespondWorkflowTaskCompletedRequest] that will finish being filled out by the
370
+ /// server client
371
+ #[derive(Debug, Clone, PartialEq)]
372
+ pub(crate) struct WorkflowTaskCompletion {
373
+ /// The task token that would've been received from polling for a workflow activation
374
+ pub task_token: TaskToken,
375
+ /// A list of new commands to send to the server, such as starting a timer.
376
+ pub commands: Vec<Command>,
377
+ /// If set, indicate that next task should be queued on sticky queue with given attributes.
378
+ pub sticky_attributes: Option<StickyExecutionAttributes>,
379
+ /// Responses to queries in the `queries` field of the workflow task.
380
+ pub query_responses: Vec<QueryResult>,
381
+ /// Indicate that the task completion should return a new WFT if one is available
382
+ pub return_new_workflow_task: bool,
383
+ /// Force a new WFT to be created after this completion
384
+ pub force_create_new_workflow_task: bool,
385
+ /// SDK-specific metadata to send
386
+ pub sdk_metadata: WorkflowTaskCompletedMetadata,
387
+ /// Metering info
388
+ pub metering_metadata: MeteringMetadata,
347
389
  }
@@ -3,6 +3,8 @@ pub(crate) mod client;
3
3
  mod workflow;
4
4
 
5
5
  pub use temporal_sdk_core_api::worker::{WorkerConfig, WorkerConfigBuilder};
6
+ #[cfg(feature = "save_wf_inputs")]
7
+ pub use workflow::replay_wf_state_inputs;
6
8
 
7
9
  pub(crate) use activities::{
8
10
  ExecutingLAId, LocalActRequest, LocalActivityExecutionResult, LocalActivityResolution,
@@ -19,20 +21,30 @@ use crate::{
19
21
  WorkflowTaskPoller,
20
22
  },
21
23
  protosext::{validate_activity_completion, ValidPollWFTQResponse},
22
- telemetry::metrics::{
23
- activity_poller, local_activity_worker_type, workflow_poller, workflow_sticky_poller,
24
- MetricsContext,
24
+ telemetry::{
25
+ metrics::{
26
+ activity_poller, local_activity_worker_type, workflow_poller, workflow_sticky_poller,
27
+ MetricsContext,
28
+ },
29
+ TelemetryInstance,
25
30
  },
26
31
  worker::{
27
32
  activities::{DispatchOrTimeoutLA, LACompleteAction, LocalActivityManager},
28
33
  client::WorkerClient,
29
- workflow::{LocalResolution, WorkflowBasics, Workflows},
34
+ workflow::{LAReqSink, LocalResolution, WorkflowBasics, Workflows},
30
35
  },
31
36
  ActivityHeartbeat, CompleteActivityError, PollActivityError, PollWfError, WorkerTrait,
32
37
  };
33
38
  use activities::{LocalInFlightActInfo, WorkerActivityTasks};
34
39
  use futures::Stream;
35
- use std::{convert::TryInto, sync::Arc};
40
+ use std::{
41
+ convert::TryInto,
42
+ future,
43
+ sync::{
44
+ atomic::{AtomicBool, Ordering},
45
+ Arc,
46
+ },
47
+ };
36
48
  use temporal_sdk_core_protos::{
37
49
  coresdk::{
38
50
  activity_result::activity_execution_result,
@@ -44,10 +56,11 @@ use temporal_sdk_core_protos::{
44
56
  temporal::api::{
45
57
  enums::v1::TaskQueueKind,
46
58
  taskqueue::v1::{StickyExecutionAttributes, TaskQueue},
47
- workflowservice::v1::PollActivityTaskQueueResponse,
59
+ workflowservice::v1::{get_system_info_response, PollActivityTaskQueueResponse},
48
60
  },
49
61
  TaskToken,
50
62
  };
63
+ use tokio::sync::mpsc::unbounded_channel;
51
64
  use tokio_util::sync::CancellationToken;
52
65
 
53
66
  /// A worker polls on a certain task queue
@@ -66,6 +79,10 @@ pub struct Worker {
66
79
  /// Will be called at the end of each activation completion
67
80
  #[allow(clippy::type_complexity)] // Sorry clippy, there's no simple way to re-use here.
68
81
  post_activate_hook: Option<Box<dyn Fn(&Self, &str, usize) + Send + Sync>>,
82
+ /// Set when non-local activities are complete and should stop being polled
83
+ non_local_activities_complete: Arc<AtomicBool>,
84
+ /// Set when local activities are complete and should stop being polled
85
+ local_activities_complete: Arc<AtomicBool>,
69
86
  }
70
87
 
71
88
  #[async_trait::async_trait]
@@ -74,7 +91,7 @@ impl WorkerTrait for Worker {
74
91
  self.next_workflow_activation().await
75
92
  }
76
93
 
77
- #[instrument(level = "debug", skip(self))]
94
+ #[instrument(skip(self))]
78
95
  async fn poll_activity_task(&self) -> Result<ActivityTask, PollActivityError> {
79
96
  loop {
80
97
  match self.activity_poll().await.transpose() {
@@ -94,7 +111,6 @@ impl WorkerTrait for Worker {
94
111
  self.complete_workflow_activation(completion).await
95
112
  }
96
113
 
97
- #[instrument(level = "debug", skip(self, completion), fields(completion=%&completion))]
98
114
  async fn complete_activity_task(
99
115
  &self,
100
116
  completion: ActivityTaskCompletion,
@@ -135,7 +151,14 @@ impl WorkerTrait for Worker {
135
151
  if let Some(atm) = self.at_task_mgr.as_ref() {
136
152
  atm.notify_shutdown();
137
153
  }
138
- info!("Initiated shutdown");
154
+ // Let the manager know that shutdown has been initiated to try to unblock the local activity poll in case this
155
+ // worker is an activity-only worker.
156
+ self.local_act_mgr.shutdown_initiated();
157
+ info!(
158
+ task_queue=%self.config.task_queue,
159
+ namespace=%self.config.namespace,
160
+ "Initiated shutdown",
161
+ );
139
162
  }
140
163
 
141
164
  async fn shutdown(&self) {
@@ -153,9 +176,17 @@ impl Worker {
153
176
  config: WorkerConfig,
154
177
  sticky_queue_name: Option<String>,
155
178
  client: Arc<dyn WorkerClient>,
156
- metrics: MetricsContext,
179
+ telem_instance: Option<&TelemetryInstance>,
157
180
  ) -> Self {
158
- info!(task_queue = %config.task_queue, "Initializing worker");
181
+ info!(task_queue=%config.task_queue,
182
+ namespace=%config.namespace,
183
+ "Initializing worker");
184
+ let metrics = if let Some(ti) = telem_instance {
185
+ MetricsContext::top_level(config.namespace.clone(), ti)
186
+ .with_task_q(config.task_queue.clone())
187
+ } else {
188
+ MetricsContext::no_op()
189
+ };
159
190
  metrics.worker_registered();
160
191
 
161
192
  let shutdown_token = CancellationToken::new();
@@ -218,31 +249,34 @@ impl Worker {
218
249
  wft_stream,
219
250
  act_poll_buffer,
220
251
  metrics,
252
+ telem_instance,
221
253
  shutdown_token,
222
254
  )
223
255
  }
224
256
 
225
257
  #[cfg(test)]
226
258
  pub(crate) fn new_test(config: WorkerConfig, client: impl WorkerClient + 'static) -> Self {
227
- Self::new(config, None, Arc::new(client), Default::default())
259
+ Self::new(config, None, Arc::new(client), None)
228
260
  }
229
261
 
262
+ #[allow(clippy::too_many_arguments)] // Not much worth combining here
230
263
  pub(crate) fn new_with_pollers(
231
- config: WorkerConfig,
264
+ mut config: WorkerConfig,
232
265
  sticky_queue_name: Option<String>,
233
266
  client: Arc<dyn WorkerClient>,
234
267
  wft_stream: impl Stream<Item = Result<ValidPollWFTQResponse, tonic::Status>> + Send + 'static,
235
268
  act_poller: Option<BoxedActPoller>,
236
269
  metrics: MetricsContext,
270
+ telem_instance: Option<&TelemetryInstance>,
237
271
  shutdown_token: CancellationToken,
238
272
  ) -> Self {
273
+ let (hb_tx, hb_rx) = unbounded_channel();
239
274
  let local_act_mgr = Arc::new(LocalActivityManager::new(
240
275
  config.max_outstanding_local_activities,
241
276
  config.namespace.clone(),
277
+ hb_tx,
242
278
  metrics.with_new_attrs([local_activity_worker_type()]),
243
279
  ));
244
- let lam_clone = local_act_mgr.clone();
245
- let local_act_req_sink = move |requests| lam_clone.enqueue(requests);
246
280
  let at_task_mgr = act_poller.map(|ap| {
247
281
  WorkerActivityTasks::new(
248
282
  config.max_outstanding_activities,
@@ -254,17 +288,20 @@ impl Worker {
254
288
  config.default_heartbeat_throttle_interval,
255
289
  )
256
290
  });
291
+ let poll_on_non_local_activities = at_task_mgr.is_some();
292
+ if !poll_on_non_local_activities {
293
+ info!("Activity polling is disabled for this worker");
294
+ };
295
+ let la_sink = LAReqSink::new(local_act_mgr.clone(), config.wf_state_inputs.clone());
257
296
  Self {
258
297
  wf_client: client.clone(),
259
298
  workflows: Workflows::new(
260
- WorkflowBasics {
261
- max_cached_workflows: config.max_cached_workflows,
262
- max_outstanding_wfts: config.max_outstanding_workflow_tasks,
263
- shutdown_token: shutdown_token.child_token(),
299
+ build_wf_basics(
300
+ &mut config,
264
301
  metrics,
265
- namespace: config.namespace.clone(),
266
- task_queue: config.task_queue.clone(),
267
- },
302
+ shutdown_token.child_token(),
303
+ client.capabilities().cloned().unwrap_or_default(),
304
+ ),
268
305
  sticky_queue_name.map(|sq| StickyExecutionAttributes {
269
306
  worker_task_queue: Some(TaskQueue {
270
307
  name: sq,
@@ -279,16 +316,22 @@ impl Worker {
279
316
  }),
280
317
  client,
281
318
  wft_stream,
282
- local_act_req_sink,
319
+ la_sink,
320
+ local_act_mgr.clone(),
321
+ hb_rx,
283
322
  at_task_mgr
284
323
  .as_ref()
285
324
  .map(|mgr| mgr.get_handle_for_workflows()),
325
+ telem_instance,
286
326
  ),
287
327
  at_task_mgr,
288
328
  local_act_mgr,
289
329
  config,
290
330
  shutdown_token,
291
331
  post_activate_hook: None,
332
+ // Complete if there configured not to poll on non-local activities.
333
+ non_local_activities_complete: Arc::new(AtomicBool::new(!poll_on_non_local_activities)),
334
+ local_activities_complete: Default::default(),
292
335
  }
293
336
  }
294
337
 
@@ -298,15 +341,16 @@ impl Worker {
298
341
  self.initiate_shutdown();
299
342
  // Next we need to wait for all local activities to finish so no more workflow task
300
343
  // heartbeats will be generated
301
- self.local_act_mgr.shutdown_and_wait_all_finished().await;
302
344
  // Wait for workflows to finish
303
345
  self.workflows
304
346
  .shutdown()
305
347
  .await
306
348
  .expect("Workflow processing terminates cleanly");
349
+ let lam = self.local_act_mgr.clone();
350
+ lam.wait_all_outstanding_tasks_finished().await;
307
351
  // Wait for activities to finish
308
352
  if let Some(acts) = self.at_task_mgr.as_ref() {
309
- acts.wait_all_finished().await;
353
+ acts.shutdown().await;
310
354
  }
311
355
  }
312
356
 
@@ -317,6 +361,10 @@ impl Worker {
317
361
  }
318
362
  }
319
363
 
364
+ pub(crate) fn shutdown_token(&self) -> CancellationToken {
365
+ self.shutdown_token.clone()
366
+ }
367
+
320
368
  /// Returns number of currently cached workflows
321
369
  pub async fn cached_workflows(&self) -> usize {
322
370
  self.workflows
@@ -336,13 +384,9 @@ impl Worker {
336
384
  .unwrap_or_default()
337
385
  }
338
386
 
339
- #[cfg(test)]
387
+ #[allow(unused)]
340
388
  pub(crate) async fn available_wft_permits(&self) -> usize {
341
- self.workflows
342
- .get_state_info()
343
- .await
344
- .expect("You can only check for available permits before shutdown")
345
- .available_wft_permits
389
+ self.workflows.available_wft_permits()
346
390
  }
347
391
 
348
392
  /// Get new activity tasks (may be local or nonlocal). Local activities are returned first
@@ -351,35 +395,63 @@ impl Worker {
351
395
  /// Returns `Ok(None)` in the event of a poll timeout or if the polling loop should otherwise
352
396
  /// be restarted
353
397
  async fn activity_poll(&self) -> Result<Option<ActivityTask>, PollActivityError> {
398
+ let local_activities_complete = self.local_activities_complete.load(Ordering::Relaxed);
399
+ let non_local_activities_complete =
400
+ self.non_local_activities_complete.load(Ordering::Relaxed);
401
+ if local_activities_complete && non_local_activities_complete {
402
+ return Err(PollActivityError::ShutDown);
403
+ }
354
404
  let act_mgr_poll = async {
405
+ if non_local_activities_complete {
406
+ future::pending::<()>().await;
407
+ unreachable!()
408
+ }
355
409
  if let Some(ref act_mgr) = self.at_task_mgr {
356
- act_mgr.poll().await
410
+ let res = act_mgr.poll().await;
411
+ if let Err(err) = res.as_ref() {
412
+ if matches!(err, PollActivityError::ShutDown) {
413
+ self.non_local_activities_complete
414
+ .store(true, Ordering::Relaxed);
415
+ return Ok(None);
416
+ }
417
+ };
418
+ res.map(Some)
357
419
  } else {
358
- info!("Activity polling is disabled for this worker");
359
- self.shutdown_token.cancelled().await;
360
- Err(PollActivityError::ShutDown)
420
+ // We expect the local activity branch below to produce shutdown when appropriate if
421
+ // there are no activity pollers.
422
+ future::pending::<()>().await;
423
+ unreachable!()
424
+ }
425
+ };
426
+ let local_activities_poll = async {
427
+ if local_activities_complete {
428
+ future::pending::<()>().await;
429
+ unreachable!()
430
+ }
431
+ match self.local_act_mgr.next_pending().await {
432
+ Some(DispatchOrTimeoutLA::Dispatch(r)) => Ok(Some(r)),
433
+ Some(DispatchOrTimeoutLA::Timeout {
434
+ run_id,
435
+ resolution,
436
+ task,
437
+ }) => {
438
+ self.notify_local_result(&run_id, LocalResolution::LocalActivity(resolution));
439
+ Ok(task)
440
+ }
441
+ None => {
442
+ if self.shutdown_token.is_cancelled() {
443
+ self.local_activities_complete
444
+ .store(true, Ordering::Relaxed);
445
+ }
446
+ Ok(None)
447
+ }
361
448
  }
362
449
  };
363
450
 
364
451
  tokio::select! {
365
452
  biased;
366
453
 
367
- r = self.local_act_mgr.next_pending() => {
368
- match r {
369
- Some(DispatchOrTimeoutLA::Dispatch(r)) => Ok(Some(r)),
370
- Some(DispatchOrTimeoutLA::Timeout { run_id, resolution, task }) => {
371
- self.notify_local_result(
372
- &run_id, LocalResolution::LocalActivity(resolution));
373
- Ok(task)
374
- },
375
- None => {
376
- if self.shutdown_token.is_cancelled() {
377
- return Err(PollActivityError::ShutDown);
378
- }
379
- Ok(None)
380
- }
381
- }
382
- },
454
+ r = local_activities_poll => r,
383
455
  r = act_mgr_poll => r,
384
456
  }
385
457
  }
@@ -394,6 +466,9 @@ impl Worker {
394
466
  }
395
467
  }
396
468
 
469
+ #[instrument(skip(self, task_token, status),
470
+ fields(task_token=%&task_token, status=%&status,
471
+ task_queue=%self.config.task_queue, workflow_id, run_id))]
397
472
  pub(crate) async fn complete_activity(
398
473
  &self,
399
474
  task_token: TaskToken,
@@ -433,22 +508,35 @@ impl Worker {
433
508
  Ok(())
434
509
  }
435
510
 
436
- #[instrument(level = "debug", skip(self), fields(run_id))]
511
+ #[instrument(skip(self), fields(run_id, workflow_id, task_queue=%self.config.task_queue))]
437
512
  pub(crate) async fn next_workflow_activation(&self) -> Result<WorkflowActivation, PollWfError> {
438
- self.workflows.next_workflow_activation().await
513
+ let r = self.workflows.next_workflow_activation().await;
514
+ // In the event workflows are shutdown, begin shutdown of everything else, since that's
515
+ // about to happen anyway. Tell the local activity manager that, so that it can know to
516
+ // cancel any remaining outstanding LAs and shutdown.
517
+ if matches!(r, Err(PollWfError::ShutDown)) {
518
+ // This is covering the situation where WFT pollers dying is the reason for shutdown
519
+ self.initiate_shutdown();
520
+ self.local_act_mgr.workflows_have_shutdown();
521
+ }
522
+ r
439
523
  }
440
524
 
441
- #[instrument(level = "debug", skip(self, completion),
442
- fields(completion=%&completion, run_id=%completion.run_id))]
525
+ #[instrument(skip(self, completion),
526
+ fields(completion=%&completion, run_id=%completion.run_id, workflow_id,
527
+ task_queue=%self.config.task_queue))]
443
528
  pub(crate) async fn complete_workflow_activation(
444
529
  &self,
445
530
  completion: WorkflowActivationCompletion,
446
531
  ) -> Result<(), CompleteWfError> {
447
- let run_id = completion.run_id.clone();
448
- let most_recent_event = self.workflows.activation_completed(completion).await?;
449
- if let Some(h) = &self.post_activate_hook {
450
- h(self, &run_id, most_recent_event);
451
- }
532
+ self.workflows
533
+ .activation_completed(
534
+ completion,
535
+ self.post_activate_hook.as_ref().map(|h| {
536
+ |run_id: &str, most_recent_event: usize| h(self, run_id, most_recent_event)
537
+ }),
538
+ )
539
+ .await?;
452
540
  Ok(())
453
541
  }
454
542
 
@@ -470,16 +558,6 @@ impl Worker {
470
558
  self.post_activate_hook = Some(Box::new(callback))
471
559
  }
472
560
 
473
- /// Used for replay workers - causes the worker to shutdown when the given run reaches the
474
- /// given event number
475
- pub(crate) fn set_shutdown_on_run_reaches_event(&mut self, run_id: String, last_event: i64) {
476
- self.set_post_activate_hook(move |worker, activated_run_id, last_processed_event| {
477
- if activated_run_id == run_id && last_processed_event >= last_event as usize {
478
- worker.initiate_shutdown();
479
- }
480
- });
481
- }
482
-
483
561
  fn complete_local_act(
484
562
  &self,
485
563
  la_res: LocalActivityExecutionResult,
@@ -494,7 +572,7 @@ impl Worker {
494
572
  runtime: info.dispatch_time.elapsed(),
495
573
  attempt: info.attempt,
496
574
  backoff,
497
- original_schedule_time: Some(info.la_info.schedule_time),
575
+ original_schedule_time: info.la_info.schedule_cmd.original_schedule_time,
498
576
  }),
499
577
  )
500
578
  }
@@ -504,14 +582,39 @@ impl Worker {
504
582
  }
505
583
  }
506
584
 
585
+ fn build_wf_basics(
586
+ config: &mut WorkerConfig,
587
+ metrics: MetricsContext,
588
+ shutdown_token: CancellationToken,
589
+ server_capabilities: get_system_info_response::Capabilities,
590
+ ) -> WorkflowBasics {
591
+ WorkflowBasics {
592
+ max_cached_workflows: config.max_cached_workflows,
593
+ max_outstanding_wfts: config.max_outstanding_workflow_tasks,
594
+ shutdown_token,
595
+ metrics,
596
+ namespace: config.namespace.clone(),
597
+ task_queue: config.task_queue.clone(),
598
+ ignore_evicts_on_shutdown: config.ignore_evicts_on_shutdown,
599
+ fetching_concurrency: config.fetching_concurrency,
600
+ server_capabilities,
601
+ #[cfg(feature = "save_wf_inputs")]
602
+ wf_state_inputs: config.wf_state_inputs.take(),
603
+ }
604
+ }
605
+
507
606
  #[cfg(test)]
508
607
  mod tests {
509
608
  use super::*;
510
- use crate::{test_help::test_worker_cfg, worker::client::mocks::mock_workflow_client};
609
+ use crate::{
610
+ advance_fut, test_help::test_worker_cfg, worker::client::mocks::mock_workflow_client,
611
+ };
612
+ use futures::FutureExt;
613
+
511
614
  use temporal_sdk_core_protos::temporal::api::workflowservice::v1::PollActivityTaskQueueResponse;
512
615
 
513
616
  #[tokio::test]
514
- async fn activity_timeouts_dont_eat_permits() {
617
+ async fn activity_timeouts_maintain_permit() {
515
618
  let mut mock_client = mock_workflow_client();
516
619
  mock_client
517
620
  .expect_poll_activity_task()
@@ -522,8 +625,16 @@ mod tests {
522
625
  .build()
523
626
  .unwrap();
524
627
  let worker = Worker::new_test(cfg, mock_client);
525
- assert_eq!(worker.activity_poll().await.unwrap(), None);
526
- assert_eq!(worker.at_task_mgr.unwrap().remaining_activity_capacity(), 5);
628
+ let fut = worker.poll_activity_task();
629
+ advance_fut!(fut);
630
+ assert_eq!(
631
+ worker
632
+ .at_task_mgr
633
+ .as_ref()
634
+ .unwrap()
635
+ .remaining_activity_capacity(),
636
+ 4
637
+ );
527
638
  }
528
639
 
529
640
  #[tokio::test]
@@ -25,11 +25,9 @@ impl WorkflowBridge {
25
25
  }
26
26
  }
27
27
 
28
- #[async_trait::async_trait]
29
28
  impl WorkflowFetcher for WorkflowBridge {
30
- async fn fetch_workflow_iteration_output(&mut self) -> Vec<WFCommand> {
29
+ fn fetch_workflow_iteration_output(&mut self) -> Vec<WFCommand> {
31
30
  let in_cmds = self.incoming_commands.try_recv();
32
-
33
31
  let in_cmds = in_cmds.unwrap_or_else(|_| vec![WFCommand::NoCommandsFromLang]);
34
32
  debug!(in_cmds = %in_cmds.display(), "wf bridge iteration fetch");
35
33
  in_cmds