temporalio 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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