@temporalio/core-bridge 1.13.2 → 1.14.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 (388) hide show
  1. package/Cargo.lock +135 -100
  2. package/Cargo.toml +3 -2
  3. package/{sdk-core/fsm/rustfsm_trait/LICENSE.txt → LICENSE} +5 -5
  4. package/README.md +0 -1
  5. package/bridge-macros/Cargo.toml +16 -0
  6. package/bridge-macros/src/derive_js_function.rs +126 -0
  7. package/bridge-macros/src/derive_tryfromjs.rs +138 -0
  8. package/bridge-macros/src/derive_tryintojs.rs +151 -0
  9. package/bridge-macros/src/lib.rs +42 -0
  10. package/lib/native.d.ts +13 -6
  11. package/package.json +6 -5
  12. package/releases/aarch64-apple-darwin/index.node +0 -0
  13. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  14. package/releases/x86_64-apple-darwin/index.node +0 -0
  15. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  16. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  17. package/sdk-core/.cargo/config.toml +9 -3
  18. package/sdk-core/.github/workflows/per-pr.yml +42 -5
  19. package/sdk-core/AGENTS.md +17 -19
  20. package/sdk-core/Cargo.toml +6 -7
  21. package/sdk-core/README.md +12 -15
  22. package/sdk-core/arch_docs/diagrams/deps.svg +102 -0
  23. package/sdk-core/{client → crates/client}/Cargo.toml +7 -9
  24. package/sdk-core/{client → crates/client}/src/lib.rs +110 -159
  25. package/sdk-core/{client → crates/client}/src/metrics.rs +1 -1
  26. package/sdk-core/{client → crates/client}/src/raw.rs +73 -44
  27. package/sdk-core/crates/client/src/request_extensions.rs +40 -0
  28. package/sdk-core/{client → crates/client}/src/retry.rs +24 -17
  29. package/sdk-core/crates/client/src/worker/mod.rs +1468 -0
  30. package/sdk-core/{client → crates/client}/src/workflow_handle/mod.rs +4 -4
  31. package/sdk-core/{core-api → crates/common}/Cargo.toml +17 -8
  32. package/sdk-core/crates/common/protos/api_cloud_upstream/VERSION +1 -0
  33. package/sdk-core/{sdk-core-protos → crates/common}/protos/api_cloud_upstream/temporal/api/cloud/account/v1/message.proto +18 -0
  34. package/sdk-core/{sdk-core-protos → crates/common}/protos/api_cloud_upstream/temporal/api/cloud/cloudservice/v1/request_response.proto +38 -11
  35. package/sdk-core/{sdk-core-protos → crates/common}/protos/api_cloud_upstream/temporal/api/cloud/cloudservice/v1/service.proto +21 -4
  36. package/sdk-core/{sdk-core-protos → crates/common}/protos/api_cloud_upstream/temporal/api/cloud/operation/v1/message.proto +6 -6
  37. package/sdk-core/{sdk-core-protos → crates/common}/protos/api_cloud_upstream/temporal/api/cloud/sink/v1/message.proto +22 -0
  38. package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/.github/workflows/create-release.yml +5 -0
  39. package/sdk-core/{core-api → crates/common}/src/envconfig.rs +2 -2
  40. package/sdk-core/{core-api → crates/common}/src/errors.rs +8 -1
  41. package/sdk-core/{fsm/rustfsm_trait/src/lib.rs → crates/common/src/fsm_trait.rs} +1 -27
  42. package/sdk-core/{core-api → crates/common}/src/lib.rs +24 -9
  43. package/sdk-core/{sdk-core-protos/src → crates/common/src/protos}/canned_histories.rs +1 -1
  44. package/sdk-core/{sdk-core-protos/src → crates/common/src/protos}/history_builder.rs +1 -1
  45. package/sdk-core/{sdk-core-protos/src → crates/common/src/protos}/history_info.rs +2 -2
  46. package/sdk-core/{sdk-core-protos/src/lib.rs → crates/common/src/protos/mod.rs} +18 -17
  47. package/sdk-core/{sdk-core-protos/src → crates/common/src/protos}/test_utils.rs +1 -1
  48. package/sdk-core/{core-api → crates/common}/src/telemetry/metrics.rs +447 -50
  49. package/sdk-core/{core-api → crates/common}/src/telemetry.rs +3 -1
  50. package/sdk-core/{core-api → crates/common}/src/worker.rs +112 -18
  51. package/sdk-core/crates/common/tests/worker_task_types_test.rs +129 -0
  52. package/sdk-core/crates/macros/Cargo.toml +23 -0
  53. package/sdk-core/{fsm/rustfsm_procmacro → crates/macros}/src/lib.rs +6 -11
  54. package/sdk-core/{sdk → crates/sdk}/Cargo.toml +10 -10
  55. package/sdk-core/{sdk → crates/sdk}/src/activity_context.rs +8 -6
  56. package/sdk-core/{sdk → crates/sdk}/src/interceptors.rs +1 -1
  57. package/sdk-core/{sdk → crates/sdk}/src/lib.rs +42 -37
  58. package/sdk-core/{sdk → crates/sdk}/src/workflow_context/options.rs +2 -2
  59. package/sdk-core/{sdk → crates/sdk}/src/workflow_context.rs +21 -19
  60. package/sdk-core/{sdk → crates/sdk}/src/workflow_future.rs +1 -1
  61. package/sdk-core/{core → crates/sdk-core}/Cargo.toml +32 -25
  62. package/sdk-core/{tests → crates/sdk-core/benches}/workflow_replay_bench.rs +10 -10
  63. package/sdk-core/crates/sdk-core/machine_coverage/ActivityMachine_Coverage.puml +32 -0
  64. package/sdk-core/crates/sdk-core/machine_coverage/CancelExternalMachine_Coverage.puml +9 -0
  65. package/sdk-core/crates/sdk-core/machine_coverage/CancelWorkflowMachine_Coverage.puml +6 -0
  66. package/sdk-core/crates/sdk-core/machine_coverage/ChildWorkflowMachine_Coverage.puml +27 -0
  67. package/sdk-core/crates/sdk-core/machine_coverage/CompleteWorkflowMachine_Coverage.puml +6 -0
  68. package/sdk-core/crates/sdk-core/machine_coverage/ContinueAsNewWorkflowMachine_Coverage.puml +6 -0
  69. package/sdk-core/crates/sdk-core/machine_coverage/FailWorkflowMachine_Coverage.puml +6 -0
  70. package/sdk-core/crates/sdk-core/machine_coverage/LocalActivityMachine_Coverage.puml +23 -0
  71. package/sdk-core/crates/sdk-core/machine_coverage/ModifyWorkflowPropertiesMachine_Coverage.puml +5 -0
  72. package/sdk-core/crates/sdk-core/machine_coverage/PatchMachine_Coverage.puml +8 -0
  73. package/sdk-core/crates/sdk-core/machine_coverage/SignalExternalMachine_Coverage.puml +12 -0
  74. package/sdk-core/crates/sdk-core/machine_coverage/TimerMachine_Coverage.puml +13 -0
  75. package/sdk-core/crates/sdk-core/machine_coverage/UpdateMachine_Coverage.puml +19 -0
  76. package/sdk-core/crates/sdk-core/machine_coverage/UpsertSearchAttributesMachine_Coverage.puml +5 -0
  77. package/sdk-core/crates/sdk-core/machine_coverage/WorkflowTaskMachine_Coverage.puml +11 -0
  78. package/sdk-core/{core → crates/sdk-core}/src/abstractions.rs +62 -6
  79. package/sdk-core/crates/sdk-core/src/antithesis.rs +60 -0
  80. package/sdk-core/{core → crates/sdk-core}/src/core_tests/activity_tasks.rs +36 -31
  81. package/sdk-core/{core → crates/sdk-core}/src/core_tests/mod.rs +12 -9
  82. package/sdk-core/{core → crates/sdk-core}/src/core_tests/queries.rs +24 -21
  83. package/sdk-core/{core → crates/sdk-core}/src/core_tests/replay_flag.rs +10 -8
  84. package/sdk-core/{core → crates/sdk-core}/src/core_tests/updates.rs +17 -15
  85. package/sdk-core/{core → crates/sdk-core}/src/core_tests/workers.rs +242 -17
  86. package/sdk-core/{core → crates/sdk-core}/src/core_tests/workflow_cancels.rs +1 -1
  87. package/sdk-core/{core → crates/sdk-core}/src/core_tests/workflow_tasks.rs +126 -39
  88. package/sdk-core/{core → crates/sdk-core}/src/debug_client.rs +1 -1
  89. package/sdk-core/{core → crates/sdk-core}/src/ephemeral_server/mod.rs +3 -3
  90. package/sdk-core/crates/sdk-core/src/histfetch.rs +33 -0
  91. package/sdk-core/{core → crates/sdk-core}/src/internal_flags.rs +4 -3
  92. package/sdk-core/{core → crates/sdk-core}/src/lib.rs +85 -43
  93. package/sdk-core/{core → crates/sdk-core}/src/pollers/mod.rs +8 -6
  94. package/sdk-core/{core → crates/sdk-core}/src/pollers/poll_buffer.rs +51 -16
  95. package/sdk-core/{core → crates/sdk-core}/src/protosext/mod.rs +1 -1
  96. package/sdk-core/{core → crates/sdk-core}/src/protosext/protocol_messages.rs +1 -1
  97. package/sdk-core/{core → crates/sdk-core}/src/replay/mod.rs +14 -11
  98. package/sdk-core/{core → crates/sdk-core}/src/retry_logic.rs +19 -1
  99. package/sdk-core/{core → crates/sdk-core}/src/telemetry/log_export.rs +2 -2
  100. package/sdk-core/{core → crates/sdk-core}/src/telemetry/metrics.rs +80 -34
  101. package/sdk-core/{core → crates/sdk-core}/src/telemetry/mod.rs +4 -4
  102. package/sdk-core/{core → crates/sdk-core}/src/telemetry/otel.rs +1 -1
  103. package/sdk-core/{core → crates/sdk-core}/src/telemetry/prometheus_meter.rs +13 -13
  104. package/sdk-core/{core → crates/sdk-core}/src/telemetry/prometheus_server.rs +2 -2
  105. package/sdk-core/{core → crates/sdk-core}/src/test_help/integ_helpers.rs +127 -40
  106. package/sdk-core/{core → crates/sdk-core}/src/test_help/unit_helpers.rs +13 -11
  107. package/sdk-core/{core → crates/sdk-core}/src/worker/activities/activity_heartbeat_manager.rs +2 -2
  108. package/sdk-core/{core → crates/sdk-core}/src/worker/activities/local_activities.rs +14 -12
  109. package/sdk-core/{core → crates/sdk-core}/src/worker/activities.rs +21 -12
  110. package/sdk-core/{core → crates/sdk-core}/src/worker/client/mocks.rs +25 -12
  111. package/sdk-core/{core → crates/sdk-core}/src/worker/client.rs +164 -71
  112. package/sdk-core/crates/sdk-core/src/worker/heartbeat.rs +246 -0
  113. package/sdk-core/crates/sdk-core/src/worker/mod.rs +1462 -0
  114. package/sdk-core/{core → crates/sdk-core}/src/worker/nexus.rs +15 -14
  115. package/sdk-core/{core → crates/sdk-core}/src/worker/slot_provider.rs +12 -13
  116. package/sdk-core/{core → crates/sdk-core}/src/worker/tuner/fixed_size.rs +5 -1
  117. package/sdk-core/{core → crates/sdk-core}/src/worker/tuner/resource_based.rs +453 -57
  118. package/sdk-core/{core → crates/sdk-core}/src/worker/tuner.rs +21 -4
  119. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/driven_workflow.rs +1 -1
  120. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/history_update.rs +2 -2
  121. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/machines/activity_state_machine.rs +147 -37
  122. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/machines/cancel_external_state_machine.rs +8 -9
  123. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/machines/cancel_nexus_op_state_machine.rs +14 -12
  124. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/machines/cancel_workflow_state_machine.rs +6 -7
  125. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/machines/child_workflow_state_machine.rs +31 -37
  126. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/machines/complete_workflow_state_machine.rs +13 -8
  127. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +6 -7
  128. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/machines/fail_workflow_state_machine.rs +6 -7
  129. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/machines/local_activity_state_machine.rs +33 -30
  130. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/machines/mod.rs +22 -17
  131. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +4 -3
  132. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/machines/nexus_operation_state_machine.rs +20 -22
  133. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/machines/patch_state_machine.rs +12 -11
  134. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/machines/signal_external_state_machine.rs +9 -12
  135. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/machines/timer_state_machine.rs +26 -13
  136. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/machines/transition_coverage.rs +1 -2
  137. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/machines/update_state_machine.rs +19 -13
  138. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +20 -18
  139. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/machines/workflow_machines/local_acts.rs +1 -1
  140. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/machines/workflow_machines.rs +61 -70
  141. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/machines/workflow_task_state_machine.rs +13 -15
  142. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/managed_run.rs +55 -37
  143. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/mod.rs +166 -60
  144. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/run_cache.rs +10 -7
  145. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/wft_extraction.rs +4 -2
  146. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/wft_poller.rs +15 -4
  147. package/sdk-core/{core → crates/sdk-core}/src/worker/workflow/workflow_stream.rs +30 -16
  148. package/sdk-core/{tests → crates/sdk-core/tests}/c_bridge_smoke_test.c +1 -1
  149. package/sdk-core/{tests → crates/sdk-core/tests}/cloud_tests.rs +1 -1
  150. package/sdk-core/crates/sdk-core/tests/common/fake_grpc_server.rs +106 -0
  151. package/sdk-core/{tests → crates/sdk-core/tests}/common/http_proxy.rs +1 -1
  152. package/sdk-core/{tests → crates/sdk-core/tests}/common/mod.rs +93 -74
  153. package/sdk-core/{tests → crates/sdk-core/tests}/common/workflows.rs +4 -3
  154. package/sdk-core/crates/sdk-core/tests/fsm_procmacro.rs +6 -0
  155. package/sdk-core/{fsm/rustfsm_procmacro/tests/trybuild → crates/sdk-core/tests/fsm_trybuild}/dupe_transitions_fail.rs +1 -3
  156. package/sdk-core/crates/sdk-core/tests/fsm_trybuild/dupe_transitions_fail.stderr +12 -0
  157. package/sdk-core/{fsm/rustfsm_procmacro/tests/trybuild → crates/sdk-core/tests/fsm_trybuild}/dynamic_dest_pass.rs +2 -4
  158. package/sdk-core/{fsm/rustfsm_procmacro/tests/trybuild → crates/sdk-core/tests/fsm_trybuild}/forgot_name_fail.rs +1 -3
  159. package/sdk-core/{fsm/rustfsm_procmacro/tests/trybuild → crates/sdk-core/tests/fsm_trybuild}/forgot_name_fail.stderr +4 -4
  160. package/sdk-core/{fsm/rustfsm_procmacro/tests/trybuild → crates/sdk-core/tests/fsm_trybuild}/handler_arg_pass.rs +2 -4
  161. package/sdk-core/{fsm/rustfsm_procmacro/tests/trybuild → crates/sdk-core/tests/fsm_trybuild}/handler_pass.rs +2 -4
  162. package/sdk-core/{fsm/rustfsm_procmacro/tests/trybuild → crates/sdk-core/tests/fsm_trybuild}/medium_complex_pass.rs +2 -4
  163. package/sdk-core/{fsm/rustfsm_procmacro/tests/trybuild → crates/sdk-core/tests/fsm_trybuild}/no_handle_conversions_require_into_fail.rs +2 -4
  164. package/sdk-core/crates/sdk-core/tests/fsm_trybuild/no_handle_conversions_require_into_fail.stderr +15 -0
  165. package/sdk-core/{fsm/rustfsm_procmacro/tests/trybuild → crates/sdk-core/tests/fsm_trybuild}/simple_pass.rs +2 -4
  166. package/sdk-core/{fsm/rustfsm_procmacro/tests/trybuild → crates/sdk-core/tests/fsm_trybuild}/struct_event_variant_fail.rs +1 -3
  167. package/sdk-core/crates/sdk-core/tests/fsm_trybuild/struct_event_variant_fail.stderr +5 -0
  168. package/sdk-core/{fsm/rustfsm_procmacro/tests/trybuild → crates/sdk-core/tests/fsm_trybuild}/tuple_more_item_event_variant_fail.rs +1 -3
  169. package/sdk-core/crates/sdk-core/tests/fsm_trybuild/tuple_more_item_event_variant_fail.stderr +5 -0
  170. package/sdk-core/{fsm/rustfsm_procmacro/tests/trybuild → crates/sdk-core/tests/fsm_trybuild}/tuple_zero_item_event_variant_fail.rs +1 -3
  171. package/sdk-core/crates/sdk-core/tests/fsm_trybuild/tuple_zero_item_event_variant_fail.stderr +5 -0
  172. package/sdk-core/{tests → crates/sdk-core/tests}/global_metric_tests.rs +14 -15
  173. package/sdk-core/{tests → crates/sdk-core/tests/heavy_tests}/fuzzy_workflow.rs +3 -3
  174. package/sdk-core/{tests → crates/sdk-core/tests}/heavy_tests.rs +19 -12
  175. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/activity_functions.rs +1 -1
  176. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/client_tests.rs +16 -111
  177. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/ephemeral_server_tests.rs +5 -6
  178. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/heartbeat_tests.rs +23 -19
  179. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/metrics_tests.rs +134 -60
  180. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/pagination_tests.rs +4 -4
  181. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/polling_tests.rs +37 -36
  182. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/queries_tests.rs +12 -10
  183. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/update_tests.rs +41 -29
  184. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/visibility_tests.rs +24 -19
  185. package/sdk-core/crates/sdk-core/tests/integ_tests/worker_heartbeat_tests.rs +1061 -0
  186. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/worker_tests.rs +113 -51
  187. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/worker_versioning_tests.rs +19 -17
  188. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/workflow_tests/activities.rs +35 -30
  189. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/workflow_tests/appdata_propagation.rs +3 -3
  190. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/workflow_tests/cancel_external.rs +14 -9
  191. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/workflow_tests/cancel_wf.rs +13 -8
  192. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/workflow_tests/child_workflows.rs +48 -35
  193. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/workflow_tests/continue_as_new.rs +14 -9
  194. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/workflow_tests/determinism.rs +24 -15
  195. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/workflow_tests/eager.rs +9 -4
  196. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/workflow_tests/local_activities.rs +47 -47
  197. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/workflow_tests/modify_wf_properties.rs +16 -11
  198. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/workflow_tests/nexus.rs +51 -23
  199. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/workflow_tests/patches.rs +22 -10
  200. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/workflow_tests/replay.rs +19 -17
  201. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/workflow_tests/resets.rs +14 -5
  202. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/workflow_tests/signals.rs +24 -15
  203. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/workflow_tests/stickyness.rs +8 -6
  204. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/workflow_tests/timers.rs +28 -18
  205. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/workflow_tests/upsert_search_attrs.rs +18 -13
  206. package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/workflow_tests.rs +46 -41
  207. package/sdk-core/{tests → crates/sdk-core/tests}/main.rs +15 -9
  208. package/sdk-core/{tests → crates/sdk-core/tests}/manual_tests.rs +20 -14
  209. package/sdk-core/{tests → crates/sdk-core/tests}/runner.rs +2 -2
  210. package/sdk-core/{tests → crates/sdk-core/tests}/shared_tests/mod.rs +10 -5
  211. package/sdk-core/{tests → crates/sdk-core/tests}/shared_tests/priority.rs +5 -5
  212. package/sdk-core/{core-c-bridge → crates/sdk-core-c-bridge}/Cargo.toml +13 -10
  213. package/sdk-core/{core-c-bridge → crates/sdk-core-c-bridge}/include/temporal-sdk-core-c-bridge.h +32 -23
  214. package/sdk-core/{core-c-bridge → crates/sdk-core-c-bridge}/src/client.rs +55 -32
  215. package/sdk-core/{core-c-bridge → crates/sdk-core-c-bridge}/src/envconfig.rs +1 -1
  216. package/sdk-core/{core-c-bridge → crates/sdk-core-c-bridge}/src/lib.rs +1 -1
  217. package/sdk-core/{core-c-bridge → crates/sdk-core-c-bridge}/src/metric.rs +1 -1
  218. package/sdk-core/{core-c-bridge → crates/sdk-core-c-bridge}/src/runtime.rs +24 -9
  219. package/sdk-core/{core-c-bridge → crates/sdk-core-c-bridge}/src/testing.rs +1 -1
  220. package/sdk-core/{core-c-bridge → crates/sdk-core-c-bridge}/src/tests/context.rs +11 -10
  221. package/sdk-core/{core-c-bridge → crates/sdk-core-c-bridge}/src/tests/mod.rs +7 -7
  222. package/sdk-core/{core-c-bridge → crates/sdk-core-c-bridge}/src/tests/utils.rs +3 -4
  223. package/sdk-core/{core-c-bridge → crates/sdk-core-c-bridge}/src/worker.rs +111 -58
  224. package/sdk-core/docker-cgroup-tests.sh +24 -0
  225. package/sdk-core/{docker → etc/docker}/docker-compose-ci.yaml +9 -9
  226. package/sdk-core/{docker → etc/docker}/docker-compose-telem.yaml +11 -11
  227. package/sdk-core/{docker → etc/docker}/docker-compose.yaml +8 -8
  228. package/sdk-core/{integ-with-otel.sh → etc/integ-with-otel.sh} +1 -1
  229. package/sdk-core/etc/regen-depgraph.sh +2 -2
  230. package/src/client.rs +24 -33
  231. package/src/helpers/try_from_js.rs +1 -1
  232. package/src/logs.rs +1 -1
  233. package/src/metrics.rs +3 -3
  234. package/src/runtime.rs +42 -28
  235. package/src/testing.rs +3 -3
  236. package/src/worker.rs +70 -36
  237. package/ts/native.ts +13 -6
  238. package/LICENSE.md +0 -23
  239. package/sdk-core/client/src/worker_registry/mod.rs +0 -282
  240. package/sdk-core/core/src/worker/heartbeat.rs +0 -230
  241. package/sdk-core/core/src/worker/mod.rs +0 -990
  242. package/sdk-core/etc/deps.svg +0 -162
  243. package/sdk-core/fsm/Cargo.toml +0 -21
  244. package/sdk-core/fsm/README.md +0 -3
  245. package/sdk-core/fsm/rustfsm_procmacro/Cargo.toml +0 -27
  246. package/sdk-core/fsm/rustfsm_procmacro/LICENSE.txt +0 -21
  247. package/sdk-core/fsm/rustfsm_procmacro/tests/progress.rs +0 -8
  248. package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/dupe_transitions_fail.stderr +0 -12
  249. package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +0 -15
  250. package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/struct_event_variant_fail.stderr +0 -5
  251. package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_more_item_event_variant_fail.stderr +0 -5
  252. package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/tuple_zero_item_event_variant_fail.stderr +0 -5
  253. package/sdk-core/fsm/rustfsm_trait/Cargo.toml +0 -14
  254. package/sdk-core/fsm/src/lib.rs +0 -2
  255. package/sdk-core/sdk-core-protos/Cargo.toml +0 -37
  256. package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/VERSION +0 -1
  257. /package/sdk-core/{client → crates/client}/src/callback_based.rs +0 -0
  258. /package/sdk-core/{client → crates/client}/src/proxy.rs +0 -0
  259. /package/sdk-core/{client → crates/client}/src/replaceable.rs +0 -0
  260. /package/sdk-core/{sdk-core-protos → crates/common}/build.rs +0 -0
  261. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_cloud_upstream/.github/workflows/build.yaml +0 -0
  262. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_cloud_upstream/.github/workflows/push-to-buf.yml +0 -0
  263. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_cloud_upstream/CODEOWNERS +0 -0
  264. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_cloud_upstream/LICENSE +0 -0
  265. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_cloud_upstream/Makefile +0 -0
  266. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_cloud_upstream/README.md +0 -0
  267. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_cloud_upstream/buf.gen.yaml +0 -0
  268. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_cloud_upstream/buf.lock +0 -0
  269. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_cloud_upstream/buf.yaml +0 -0
  270. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_cloud_upstream/temporal/api/cloud/connectivityrule/v1/message.proto +0 -0
  271. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_cloud_upstream/temporal/api/cloud/identity/v1/message.proto +0 -0
  272. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_cloud_upstream/temporal/api/cloud/namespace/v1/message.proto +0 -0
  273. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_cloud_upstream/temporal/api/cloud/nexus/v1/message.proto +0 -0
  274. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_cloud_upstream/temporal/api/cloud/region/v1/message.proto +0 -0
  275. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_cloud_upstream/temporal/api/cloud/resource/v1/message.proto +0 -0
  276. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_cloud_upstream/temporal/api/cloud/usage/v1/message.proto +0 -0
  277. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/.github/CODEOWNERS +0 -0
  278. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  279. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/.github/workflows/ci.yml +0 -0
  280. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/.github/workflows/publish-docs.yml +0 -0
  281. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/.github/workflows/push-to-buf.yml +0 -0
  282. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/.github/workflows/trigger-api-go-delete-release.yml +0 -0
  283. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/.github/workflows/trigger-api-go-publish-release.yml +0 -0
  284. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/.github/workflows/trigger-api-go-update.yml +0 -0
  285. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/LICENSE +0 -0
  286. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/Makefile +0 -0
  287. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/README.md +0 -0
  288. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/api-linter.yaml +0 -0
  289. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/buf.gen.yaml +0 -0
  290. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/buf.lock +0 -0
  291. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/buf.yaml +0 -0
  292. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/google/api/annotations.proto +0 -0
  293. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/google/api/http.proto +0 -0
  294. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/google/protobuf/any.proto +0 -0
  295. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/google/protobuf/descriptor.proto +0 -0
  296. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/google/protobuf/duration.proto +0 -0
  297. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/google/protobuf/empty.proto +0 -0
  298. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/google/protobuf/struct.proto +0 -0
  299. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/google/protobuf/timestamp.proto +0 -0
  300. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/google/protobuf/wrappers.proto +0 -0
  301. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/openapi/openapiv2.json +0 -0
  302. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/openapi/openapiv3.yaml +0 -0
  303. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/openapi/payload_description.txt +0 -0
  304. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/activity/v1/message.proto +0 -0
  305. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/batch/v1/message.proto +0 -0
  306. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/command/v1/message.proto +0 -0
  307. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/common/v1/message.proto +0 -0
  308. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/deployment/v1/message.proto +0 -0
  309. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +0 -0
  310. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/enums/v1/command_type.proto +0 -0
  311. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/enums/v1/common.proto +0 -0
  312. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/enums/v1/deployment.proto +0 -0
  313. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/enums/v1/event_type.proto +0 -0
  314. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +0 -0
  315. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/enums/v1/namespace.proto +0 -0
  316. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/enums/v1/nexus.proto +0 -0
  317. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/enums/v1/query.proto +0 -0
  318. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/enums/v1/reset.proto +0 -0
  319. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/enums/v1/schedule.proto +0 -0
  320. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +0 -0
  321. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/enums/v1/update.proto +0 -0
  322. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/enums/v1/workflow.proto +0 -0
  323. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/errordetails/v1/message.proto +0 -0
  324. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/export/v1/message.proto +0 -0
  325. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/failure/v1/message.proto +0 -0
  326. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/filter/v1/message.proto +0 -0
  327. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/history/v1/message.proto +0 -0
  328. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/namespace/v1/message.proto +0 -0
  329. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/nexus/v1/message.proto +0 -0
  330. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +0 -0
  331. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +0 -0
  332. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/protocol/v1/message.proto +0 -0
  333. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/query/v1/message.proto +0 -0
  334. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/replication/v1/message.proto +0 -0
  335. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/rules/v1/message.proto +0 -0
  336. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/schedule/v1/message.proto +0 -0
  337. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/sdk/v1/enhanced_stack_trace.proto +0 -0
  338. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +0 -0
  339. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/sdk/v1/user_metadata.proto +0 -0
  340. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/sdk/v1/worker_config.proto +0 -0
  341. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/sdk/v1/workflow_metadata.proto +0 -0
  342. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +0 -0
  343. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/update/v1/message.proto +0 -0
  344. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/version/v1/message.proto +0 -0
  345. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/worker/v1/message.proto +0 -0
  346. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/workflow/v1/message.proto +0 -0
  347. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +0 -0
  348. /package/sdk-core/{sdk-core-protos → crates/common}/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +0 -0
  349. /package/sdk-core/{sdk-core-protos → crates/common}/protos/google/rpc/status.proto +0 -0
  350. /package/sdk-core/{sdk-core-protos → crates/common}/protos/grpc/health/v1/health.proto +0 -0
  351. /package/sdk-core/{sdk-core-protos → crates/common}/protos/local/temporal/sdk/core/activity_result/activity_result.proto +0 -0
  352. /package/sdk-core/{sdk-core-protos → crates/common}/protos/local/temporal/sdk/core/activity_task/activity_task.proto +0 -0
  353. /package/sdk-core/{sdk-core-protos → crates/common}/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +0 -0
  354. /package/sdk-core/{sdk-core-protos → crates/common}/protos/local/temporal/sdk/core/common/common.proto +0 -0
  355. /package/sdk-core/{sdk-core-protos → crates/common}/protos/local/temporal/sdk/core/core_interface.proto +0 -0
  356. /package/sdk-core/{sdk-core-protos → crates/common}/protos/local/temporal/sdk/core/external_data/external_data.proto +0 -0
  357. /package/sdk-core/{sdk-core-protos → crates/common}/protos/local/temporal/sdk/core/nexus/nexus.proto +0 -0
  358. /package/sdk-core/{sdk-core-protos → crates/common}/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +0 -0
  359. /package/sdk-core/{sdk-core-protos → crates/common}/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +0 -0
  360. /package/sdk-core/{sdk-core-protos → crates/common}/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +0 -0
  361. /package/sdk-core/{sdk-core-protos → crates/common}/protos/testsrv_upstream/Makefile +0 -0
  362. /package/sdk-core/{sdk-core-protos → crates/common}/protos/testsrv_upstream/api-linter.yaml +0 -0
  363. /package/sdk-core/{sdk-core-protos → crates/common}/protos/testsrv_upstream/buf.yaml +0 -0
  364. /package/sdk-core/{sdk-core-protos → crates/common}/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +0 -0
  365. /package/sdk-core/{sdk-core-protos → crates/common}/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +0 -0
  366. /package/sdk-core/{sdk-core-protos/src → crates/common/src/protos}/constants.rs +0 -0
  367. /package/sdk-core/{sdk-core-protos/src → crates/common/src/protos}/task_token.rs +0 -0
  368. /package/sdk-core/{sdk-core-protos/src → crates/common/src/protos}/utilities.rs +0 -0
  369. /package/sdk-core/{fsm → crates/macros}/LICENSE.txt +0 -0
  370. /package/sdk-core/{sdk → crates/sdk}/src/app_data.rs +0 -0
  371. /package/sdk-core/{core → crates/sdk-core}/src/abstractions/take_cell.rs +0 -0
  372. /package/sdk-core/{core → crates/sdk-core}/src/test_help/mod.rs +0 -0
  373. /package/sdk-core/{core → crates/sdk-core}/src/worker/slot_supplier.rs +0 -0
  374. /package/sdk-core/{histories → crates/sdk-core/tests/histories}/ends_empty_wft_complete.bin +0 -0
  375. /package/sdk-core/{histories → crates/sdk-core/tests/histories}/evict_while_la_running_no_interference-16_history.bin +0 -0
  376. /package/sdk-core/{histories → crates/sdk-core/tests/histories}/evict_while_la_running_no_interference-23_history.bin +0 -0
  377. /package/sdk-core/{histories → crates/sdk-core/tests/histories}/evict_while_la_running_no_interference-85_history.bin +0 -0
  378. /package/sdk-core/{histories → crates/sdk-core/tests/histories}/fail_wf_task.bin +0 -0
  379. /package/sdk-core/{histories → crates/sdk-core/tests/histories}/long_local_activity_with_update-0_history.bin +0 -0
  380. /package/sdk-core/{histories → crates/sdk-core/tests/histories}/long_local_activity_with_update-1_history.bin +0 -0
  381. /package/sdk-core/{histories → crates/sdk-core/tests/histories}/long_local_activity_with_update-2_history.bin +0 -0
  382. /package/sdk-core/{histories → crates/sdk-core/tests/histories}/long_local_activity_with_update-3_history.bin +0 -0
  383. /package/sdk-core/{histories → crates/sdk-core/tests/histories}/old_change_marker_format.bin +0 -0
  384. /package/sdk-core/{histories → crates/sdk-core/tests/histories}/timer_workflow_history.bin +0 -0
  385. /package/sdk-core/{tests → crates/sdk-core/tests}/integ_tests/workflow_tests/priority.rs +0 -0
  386. /package/sdk-core/{core-c-bridge → crates/sdk-core-c-bridge}/build.rs +0 -0
  387. /package/sdk-core/{core-c-bridge → crates/sdk-core-c-bridge}/src/random.rs +0 -0
  388. /package/sdk-core/{cargo-tokio-console.sh → etc/cargo-tokio-console.sh} +0 -0
@@ -1,990 +0,0 @@
1
- mod activities;
2
- pub(crate) mod client;
3
- mod heartbeat;
4
- mod nexus;
5
- mod slot_provider;
6
- pub(crate) mod tuner;
7
- mod workflow;
8
-
9
- pub use temporal_sdk_core_api::worker::{WorkerConfig, WorkerConfigBuilder};
10
- pub use tuner::{
11
- FixedSizeSlotSupplier, RealSysInfo, ResourceBasedSlotsOptions,
12
- ResourceBasedSlotsOptionsBuilder, ResourceBasedTuner, ResourceSlotOptions, SlotSupplierOptions,
13
- TunerBuilder, TunerHolder, TunerHolderOptions, TunerHolderOptionsBuilder,
14
- };
15
-
16
- pub(crate) use activities::{
17
- ExecutingLAId, LocalActRequest, LocalActivityExecutionResult, LocalActivityResolution,
18
- NewLocalAct,
19
- };
20
- pub(crate) use wft_poller::WFTPollerShared;
21
-
22
- #[allow(unreachable_pub)] // re-exported in test_help::integ_helpers
23
- pub use workflow::LEGACY_QUERY_ID;
24
-
25
- use crate::{
26
- ActivityHeartbeat, CompleteActivityError, PollError, WorkerTrait,
27
- abstractions::{MeteredPermitDealer, PermitDealerContextData, dbg_panic},
28
- errors::CompleteWfError,
29
- pollers::{ActivityTaskOptions, BoxedActPoller, BoxedNexusPoller, LongPollBuffer},
30
- protosext::validate_activity_completion,
31
- sealed::AnyClient,
32
- telemetry::{
33
- TelemetryInstance,
34
- metrics::{
35
- MetricsContext, activity_poller, activity_worker_type, local_activity_worker_type,
36
- nexus_poller, nexus_worker_type, workflow_worker_type,
37
- },
38
- },
39
- worker::{
40
- activities::{LACompleteAction, LocalActivityManager, NextPendingLAAction},
41
- client::WorkerClient,
42
- heartbeat::{HeartbeatFn, WorkerHeartbeatManager},
43
- nexus::NexusManager,
44
- workflow::{
45
- LAReqSink, LocalResolution, WorkflowBasics, Workflows, wft_poller,
46
- wft_poller::make_wft_poller,
47
- },
48
- },
49
- };
50
- use activities::WorkerActivityTasks;
51
- use futures_util::{StreamExt, stream};
52
- use parking_lot::Mutex;
53
- use slot_provider::SlotProvider;
54
- use std::{
55
- convert::TryInto,
56
- future,
57
- sync::{
58
- Arc, OnceLock,
59
- atomic::{AtomicBool, Ordering},
60
- },
61
- time::Duration,
62
- };
63
- use temporal_client::WorkerKey;
64
- use temporal_sdk_core_api::{
65
- errors::{CompleteNexusError, WorkerValidationError},
66
- worker::PollerBehavior,
67
- };
68
- use temporal_sdk_core_protos::{
69
- TaskToken,
70
- coresdk::{
71
- ActivityTaskCompletion,
72
- activity_result::activity_execution_result,
73
- activity_task::ActivityTask,
74
- nexus::{NexusTask, NexusTaskCompletion, nexus_task_completion},
75
- workflow_activation::{WorkflowActivation, remove_from_cache::EvictionReason},
76
- workflow_completion::WorkflowActivationCompletion,
77
- },
78
- temporal::api::{
79
- enums::v1::TaskQueueKind,
80
- taskqueue::v1::{StickyExecutionAttributes, TaskQueue},
81
- },
82
- };
83
- use tokio::sync::{mpsc::unbounded_channel, watch};
84
- use tokio_stream::wrappers::UnboundedReceiverStream;
85
- use tokio_util::sync::CancellationToken;
86
-
87
- #[cfg(any(feature = "test-utilities", test))]
88
- use {
89
- crate::{
90
- pollers::{BoxedPoller, MockPermittedPollBuffer},
91
- protosext::ValidPollWFTQResponse,
92
- },
93
- futures_util::stream::BoxStream,
94
- temporal_sdk_core_protos::temporal::api::workflowservice::v1::{
95
- PollActivityTaskQueueResponse, PollNexusTaskQueueResponse,
96
- },
97
- };
98
-
99
- /// A worker polls on a certain task queue
100
- pub struct Worker {
101
- config: WorkerConfig,
102
- client: Arc<dyn WorkerClient>,
103
- /// Registration key to enable eager workflow start for this worker
104
- worker_key: Mutex<Option<WorkerKey>>,
105
- /// Manages all workflows and WFT processing
106
- workflows: Workflows,
107
- /// Manages activity tasks for this worker/task queue
108
- at_task_mgr: Option<WorkerActivityTasks>,
109
- /// Manages local activities
110
- local_act_mgr: Arc<LocalActivityManager>,
111
- /// Manages Nexus tasks
112
- nexus_mgr: NexusManager,
113
- /// Has shutdown been called?
114
- shutdown_token: CancellationToken,
115
- /// Will be called at the end of each activation completion
116
- #[allow(clippy::type_complexity)] // Sorry clippy, there's no simple way to re-use here.
117
- post_activate_hook: Option<Box<dyn Fn(&Self, PostActivateHookData<'_>) + Send + Sync>>,
118
- /// Set when non-local activities are complete and should stop being polled
119
- non_local_activities_complete: Arc<AtomicBool>,
120
- /// Set when local activities are complete and should stop being polled
121
- local_activities_complete: Arc<AtomicBool>,
122
- /// Used to track all permits have been released
123
- all_permits_tracker: tokio::sync::Mutex<AllPermitsTracker>,
124
- /// Used to shutdown the worker heartbeat task
125
- worker_heartbeat: Option<WorkerHeartbeatManager>,
126
- }
127
-
128
- struct AllPermitsTracker {
129
- wft_permits: watch::Receiver<usize>,
130
- act_permits: watch::Receiver<usize>,
131
- la_permits: watch::Receiver<usize>,
132
- }
133
-
134
- impl AllPermitsTracker {
135
- async fn all_done(&mut self) {
136
- let _ = self.wft_permits.wait_for(|x| *x == 0).await;
137
- let _ = self.act_permits.wait_for(|x| *x == 0).await;
138
- let _ = self.la_permits.wait_for(|x| *x == 0).await;
139
- }
140
- }
141
-
142
- #[async_trait::async_trait]
143
- impl WorkerTrait for Worker {
144
- async fn validate(&self) -> Result<(), WorkerValidationError> {
145
- self.verify_namespace_exists().await?;
146
- Ok(())
147
- }
148
-
149
- async fn poll_workflow_activation(&self) -> Result<WorkflowActivation, PollError> {
150
- self.next_workflow_activation().await
151
- }
152
-
153
- #[instrument(skip(self))]
154
- async fn poll_activity_task(&self) -> Result<ActivityTask, PollError> {
155
- loop {
156
- match self.activity_poll().await.transpose() {
157
- Some(r) => break r,
158
- None => {
159
- tokio::task::yield_now().await;
160
- continue;
161
- }
162
- }
163
- }
164
- }
165
-
166
- #[instrument(skip(self))]
167
- async fn poll_nexus_task(&self) -> Result<NexusTask, PollError> {
168
- self.nexus_mgr.next_nexus_task().await
169
- }
170
-
171
- async fn complete_workflow_activation(
172
- &self,
173
- completion: WorkflowActivationCompletion,
174
- ) -> Result<(), CompleteWfError> {
175
- self.complete_workflow_activation(completion).await
176
- }
177
-
178
- async fn complete_activity_task(
179
- &self,
180
- completion: ActivityTaskCompletion,
181
- ) -> Result<(), CompleteActivityError> {
182
- let task_token = TaskToken(completion.task_token);
183
- let status = if let Some(s) = completion.result.and_then(|r| r.status) {
184
- s
185
- } else {
186
- return Err(CompleteActivityError::MalformedActivityCompletion {
187
- reason: "Activity completion had empty result/status field".to_owned(),
188
- completion: None,
189
- });
190
- };
191
-
192
- self.complete_activity(task_token, status).await
193
- }
194
-
195
- async fn complete_nexus_task(
196
- &self,
197
- completion: NexusTaskCompletion,
198
- ) -> Result<(), CompleteNexusError> {
199
- let status = if let Some(s) = completion.status {
200
- s
201
- } else {
202
- return Err(CompleteNexusError::MalformedNexusCompletion {
203
- reason: "Nexus completion had empty status field".to_owned(),
204
- });
205
- };
206
-
207
- self.complete_nexus_task(TaskToken(completion.task_token), status)
208
- .await
209
- }
210
-
211
- fn record_activity_heartbeat(&self, details: ActivityHeartbeat) {
212
- self.record_heartbeat(details);
213
- }
214
-
215
- fn request_workflow_eviction(&self, run_id: &str) {
216
- self.request_wf_eviction(
217
- run_id,
218
- "Eviction explicitly requested by lang",
219
- EvictionReason::LangRequested,
220
- );
221
- }
222
-
223
- fn get_config(&self) -> &WorkerConfig {
224
- &self.config
225
- }
226
-
227
- /// Begins the shutdown process, tells pollers they should stop. Is idempotent.
228
- fn initiate_shutdown(&self) {
229
- if !self.shutdown_token.is_cancelled() {
230
- info!(
231
- task_queue=%self.config.task_queue,
232
- namespace=%self.config.namespace,
233
- "Initiated shutdown",
234
- );
235
- }
236
- self.shutdown_token.cancel();
237
- // First, disable Eager Workflow Start
238
- if let Some(key) = *self.worker_key.lock() {
239
- self.client.workers().unregister(key);
240
- }
241
- // Second, we want to stop polling of both activity and workflow tasks
242
- if let Some(atm) = self.at_task_mgr.as_ref() {
243
- atm.initiate_shutdown();
244
- }
245
- // Let the manager know that shutdown has been initiated to try to unblock the local
246
- // activity poll in case this worker is an activity-only worker.
247
- self.local_act_mgr.shutdown_initiated();
248
-
249
- if !self.workflows.ever_polled() {
250
- self.local_act_mgr.workflows_have_shutdown();
251
- } else {
252
- // Bump the workflow stream with a pointless input, since if a client initiates shutdown
253
- // and then immediately blocks waiting on a workflow activation poll, it's possible that
254
- // there may not be any more inputs ever, and that poll will never resolve.
255
- self.workflows.send_get_state_info_msg();
256
- }
257
- }
258
-
259
- async fn shutdown(&self) {
260
- self.shutdown().await
261
- }
262
-
263
- async fn finalize_shutdown(self) {
264
- self.finalize_shutdown().await
265
- }
266
- }
267
-
268
- impl Worker {
269
- /// Creates a new [Worker] from a [WorkerClient] instance with real task pollers and optional telemetry.
270
- ///
271
- /// This is a convenience constructor that logs initialization and delegates to
272
- /// [Worker::new_with_pollers()] using [TaskPollers::Real].
273
- pub fn new(
274
- config: WorkerConfig,
275
- sticky_queue_name: Option<String>,
276
- client: Arc<dyn WorkerClient>,
277
- telem_instance: Option<&TelemetryInstance>,
278
- heartbeat_fn: Option<Arc<OnceLock<HeartbeatFn>>>,
279
- ) -> Self {
280
- info!(task_queue=%config.task_queue, namespace=%config.namespace, "Initializing worker");
281
-
282
- Self::new_with_pollers(
283
- config,
284
- sticky_queue_name,
285
- client,
286
- TaskPollers::Real,
287
- telem_instance,
288
- heartbeat_fn,
289
- )
290
- }
291
-
292
- /// Replace client. For eager workflow purposes, this new client will now apply to future
293
- /// eager start requests and the older client will not.
294
- pub fn replace_client<CT>(&self, new_client: CT)
295
- where
296
- CT: Into<AnyClient>,
297
- {
298
- // Unregister worker from current client, register in new client at the end
299
- let mut worker_key = self.worker_key.lock();
300
- let slot_provider = (*worker_key).and_then(|k| self.client.workers().unregister(k));
301
- self.client
302
- .replace_client(super::init_worker_client(&self.config, new_client));
303
- *worker_key =
304
- slot_provider.and_then(|slot_provider| self.client.workers().register(slot_provider));
305
- }
306
-
307
- #[cfg(test)]
308
- pub(crate) fn new_test(config: WorkerConfig, client: impl WorkerClient + 'static) -> Self {
309
- Self::new(config, None, Arc::new(client), None, None)
310
- }
311
-
312
- pub(crate) fn new_with_pollers(
313
- config: WorkerConfig,
314
- sticky_queue_name: Option<String>,
315
- client: Arc<dyn WorkerClient>,
316
- task_pollers: TaskPollers,
317
- telem_instance: Option<&TelemetryInstance>,
318
- heartbeat_fn: Option<Arc<OnceLock<HeartbeatFn>>>,
319
- ) -> Self {
320
- let (metrics, meter) = if let Some(ti) = telem_instance {
321
- (
322
- MetricsContext::top_level(config.namespace.clone(), config.task_queue.clone(), ti),
323
- ti.get_metric_meter(),
324
- )
325
- } else {
326
- (MetricsContext::no_op(), None)
327
- };
328
- let tuner = config
329
- .tuner
330
- .as_ref()
331
- .cloned()
332
- .unwrap_or_else(|| Arc::new(TunerBuilder::from_config(&config).build()));
333
-
334
- metrics.worker_registered();
335
- let shutdown_token = CancellationToken::new();
336
- let slot_context_data = Arc::new(PermitDealerContextData {
337
- task_queue: config.task_queue.clone(),
338
- worker_identity: client.get_identity(),
339
- worker_deployment_version: config.computed_deployment_version(),
340
- });
341
- let wft_slots = MeteredPermitDealer::new(
342
- tuner.workflow_task_slot_supplier(),
343
- metrics.with_new_attrs([workflow_worker_type()]),
344
- if config.max_cached_workflows > 0 {
345
- // Since we always need to be able to poll the normal task queue as well as the
346
- // sticky queue, we need a value of at least 2 here.
347
- Some(std::cmp::max(2, config.max_cached_workflows))
348
- } else {
349
- None
350
- },
351
- slot_context_data.clone(),
352
- meter.clone(),
353
- );
354
- let wft_permits = wft_slots.get_extant_count_rcv();
355
- let act_slots = MeteredPermitDealer::new(
356
- tuner.activity_task_slot_supplier(),
357
- metrics.with_new_attrs([activity_worker_type()]),
358
- None,
359
- slot_context_data.clone(),
360
- meter.clone(),
361
- );
362
- let act_permits = act_slots.get_extant_count_rcv();
363
- let (external_wft_tx, external_wft_rx) = unbounded_channel();
364
- let nexus_slots = MeteredPermitDealer::new(
365
- tuner.nexus_task_slot_supplier(),
366
- metrics.with_new_attrs([nexus_worker_type()]),
367
- None,
368
- slot_context_data.clone(),
369
- meter.clone(),
370
- );
371
- let (wft_stream, act_poller, nexus_poller) = match task_pollers {
372
- TaskPollers::Real => {
373
- let wft_stream = make_wft_poller(
374
- &config,
375
- &sticky_queue_name,
376
- &client,
377
- &metrics,
378
- &shutdown_token,
379
- &wft_slots,
380
- );
381
- let wft_stream = if !client.is_mock() {
382
- // Some replay tests combine a mock client with real pollers,
383
- // and they don't need to use the external stream
384
- stream::select(wft_stream, UnboundedReceiverStream::new(external_wft_rx))
385
- .left_stream()
386
- } else {
387
- wft_stream.right_stream()
388
- };
389
-
390
- let act_poll_buffer = if config.no_remote_activities {
391
- None
392
- } else {
393
- let act_metrics = metrics.with_new_attrs([activity_poller()]);
394
- let ap = LongPollBuffer::new_activity_task(
395
- client.clone(),
396
- config.task_queue.clone(),
397
- config.activity_task_poller_behavior,
398
- act_slots.clone(),
399
- shutdown_token.child_token(),
400
- Some(move |np| act_metrics.record_num_pollers(np)),
401
- ActivityTaskOptions {
402
- max_worker_acts_per_second: config.max_worker_activities_per_second,
403
- max_tps: config.max_task_queue_activities_per_second,
404
- },
405
- );
406
- Some(Box::from(ap) as BoxedActPoller)
407
- };
408
-
409
- let np_metrics = metrics.with_new_attrs([nexus_poller()]);
410
- let nexus_poll_buffer = Box::new(LongPollBuffer::new_nexus_task(
411
- client.clone(),
412
- config.task_queue.clone(),
413
- config.nexus_task_poller_behavior,
414
- nexus_slots.clone(),
415
- shutdown_token.child_token(),
416
- Some(move |np| np_metrics.record_num_pollers(np)),
417
- )) as BoxedNexusPoller;
418
-
419
- #[cfg(any(feature = "test-utilities", test))]
420
- let wft_stream = wft_stream.left_stream();
421
- (wft_stream, act_poll_buffer, nexus_poll_buffer)
422
- }
423
- #[cfg(any(feature = "test-utilities", test))]
424
- TaskPollers::Mocked {
425
- wft_stream,
426
- act_poller,
427
- nexus_poller,
428
- } => {
429
- let ap = act_poller
430
- .map(|ap| MockPermittedPollBuffer::new(Arc::new(act_slots.clone()), ap));
431
- let np = MockPermittedPollBuffer::new(Arc::new(nexus_slots.clone()), nexus_poller);
432
- let wft_semaphore = wft_slots.clone();
433
- let wfs = wft_stream.then(move |s| {
434
- let wft_semaphore = wft_semaphore.clone();
435
- async move {
436
- let permit = wft_semaphore.acquire_owned().await;
437
- s.map(|s| (s, permit))
438
- }
439
- });
440
- let wfs = wfs.right_stream();
441
- (
442
- wfs,
443
- ap.map(|ap| Box::new(ap) as BoxedActPoller),
444
- Box::new(np) as BoxedNexusPoller,
445
- )
446
- }
447
- };
448
-
449
- let (hb_tx, hb_rx) = unbounded_channel();
450
- let la_permit_dealer = MeteredPermitDealer::new(
451
- tuner.local_activity_slot_supplier(),
452
- metrics.with_new_attrs([local_activity_worker_type()]),
453
- None,
454
- slot_context_data.clone(),
455
- meter.clone(),
456
- );
457
- let la_permits = la_permit_dealer.get_extant_count_rcv();
458
- let local_act_mgr = Arc::new(LocalActivityManager::new(
459
- config.namespace.clone(),
460
- la_permit_dealer,
461
- hb_tx,
462
- metrics.clone(),
463
- ));
464
- let at_task_mgr = act_poller.map(|ap| {
465
- WorkerActivityTasks::new(
466
- act_slots,
467
- ap,
468
- client.clone(),
469
- metrics.clone(),
470
- config.max_heartbeat_throttle_interval,
471
- config.default_heartbeat_throttle_interval,
472
- config.graceful_shutdown_period,
473
- config.local_timeout_buffer_for_activities,
474
- )
475
- });
476
- let poll_on_non_local_activities = at_task_mgr.is_some();
477
- if !poll_on_non_local_activities {
478
- info!("Activity polling is disabled for this worker");
479
- };
480
- let la_sink = LAReqSink::new(local_act_mgr.clone());
481
-
482
- let nexus_mgr = NexusManager::new(
483
- nexus_poller,
484
- metrics.clone(),
485
- config.graceful_shutdown_period,
486
- shutdown_token.child_token(),
487
- );
488
-
489
- let deployment_options = match &config.versioning_strategy {
490
- temporal_sdk_core_api::worker::WorkerVersioningStrategy::WorkerDeploymentBased(
491
- opts,
492
- ) => Some(opts.clone()),
493
- _ => None,
494
- };
495
- let provider = SlotProvider::new(
496
- config.namespace.clone(),
497
- config.task_queue.clone(),
498
- wft_slots.clone(),
499
- external_wft_tx,
500
- deployment_options,
501
- );
502
- let worker_key = Mutex::new(client.workers().register(Box::new(provider)));
503
- let sdk_name_and_ver = client.sdk_name_and_version();
504
-
505
- let worker_heartbeat = heartbeat_fn.map(|heartbeat_fn| {
506
- WorkerHeartbeatManager::new(
507
- config.clone(),
508
- client.get_identity(),
509
- heartbeat_fn,
510
- client.clone(),
511
- )
512
- });
513
-
514
- Self {
515
- worker_key,
516
- client: client.clone(),
517
- workflows: Workflows::new(
518
- WorkflowBasics {
519
- worker_config: Arc::new(config.clone()),
520
- shutdown_token: shutdown_token.child_token(),
521
- metrics,
522
- server_capabilities: client.capabilities().unwrap_or_default(),
523
- sdk_name: sdk_name_and_ver.0,
524
- sdk_version: sdk_name_and_ver.1,
525
- default_versioning_behavior: config
526
- .versioning_strategy
527
- .default_versioning_behavior(),
528
- },
529
- sticky_queue_name.map(|sq| StickyExecutionAttributes {
530
- worker_task_queue: Some(TaskQueue {
531
- name: sq,
532
- kind: TaskQueueKind::Sticky as i32,
533
- normal_name: config.task_queue.clone(),
534
- }),
535
- schedule_to_start_timeout: Some(
536
- config
537
- .sticky_queue_schedule_to_start_timeout
538
- .try_into()
539
- .expect("timeout fits into proto"),
540
- ),
541
- }),
542
- client,
543
- wft_slots,
544
- wft_stream,
545
- la_sink,
546
- local_act_mgr.clone(),
547
- hb_rx,
548
- at_task_mgr.as_ref().and_then(|mgr| {
549
- match config.max_task_queue_activities_per_second {
550
- Some(persec) if persec > 0.0 => None,
551
- _ => Some(mgr.get_handle_for_workflows()),
552
- }
553
- }),
554
- telem_instance,
555
- ),
556
- at_task_mgr,
557
- local_act_mgr,
558
- config,
559
- shutdown_token,
560
- post_activate_hook: None,
561
- // Non-local activities are already complete if configured not to poll for them.
562
- non_local_activities_complete: Arc::new(AtomicBool::new(!poll_on_non_local_activities)),
563
- local_activities_complete: Default::default(),
564
- all_permits_tracker: tokio::sync::Mutex::new(AllPermitsTracker {
565
- wft_permits,
566
- act_permits,
567
- la_permits,
568
- }),
569
- nexus_mgr,
570
- worker_heartbeat,
571
- }
572
- }
573
-
574
- /// Will shutdown the worker. Does not resolve until all outstanding workflow tasks have been
575
- /// completed
576
- async fn shutdown(&self) {
577
- self.initiate_shutdown();
578
- if let Some(name) = self.workflows.get_sticky_queue_name() {
579
- // This is a best effort call and we can still shutdown the worker if it fails
580
- match self.client.shutdown_worker(name).await {
581
- Err(err)
582
- if !matches!(
583
- err.code(),
584
- tonic::Code::Unimplemented | tonic::Code::Unavailable
585
- ) =>
586
- {
587
- warn!("Failed to shutdown sticky queue {:?}", err);
588
- }
589
- _ => {}
590
- }
591
- }
592
- // We need to wait for all local activities to finish so no more workflow task heartbeats
593
- // will be generated
594
- self.local_act_mgr
595
- .wait_all_outstanding_tasks_finished()
596
- .await;
597
- // Wait for workflows to finish
598
- self.workflows
599
- .shutdown()
600
- .await
601
- .expect("Workflow processing terminates cleanly");
602
- // Wait for activities to finish
603
- if let Some(acts) = self.at_task_mgr.as_ref() {
604
- acts.shutdown().await;
605
- }
606
- // Wait for nexus tasks to finish
607
- self.nexus_mgr.shutdown().await;
608
- // Wait for all permits to be released, but don't totally hang real-world shutdown.
609
- tokio::select! {
610
- _ = async { self.all_permits_tracker.lock().await.all_done().await } => {},
611
- _ = tokio::time::sleep(Duration::from_secs(1)) => {
612
- dbg_panic!("Waiting for all slot permits to release took too long!");
613
- }
614
- }
615
- if let Some(heartbeat) = self.worker_heartbeat.as_ref() {
616
- heartbeat.shutdown();
617
- }
618
- }
619
-
620
- /// Finish shutting down by consuming the background pollers and freeing all resources
621
- async fn finalize_shutdown(self) {
622
- self.shutdown().await;
623
- if let Some(b) = self.at_task_mgr {
624
- b.shutdown().await;
625
- }
626
- }
627
-
628
- pub(crate) fn shutdown_token(&self) -> CancellationToken {
629
- self.shutdown_token.clone()
630
- }
631
-
632
- /// Returns number of currently cached workflows
633
- pub async fn cached_workflows(&self) -> usize {
634
- self.workflows
635
- .get_state_info()
636
- .await
637
- .map(|r| r.cached_workflows)
638
- .unwrap_or_default()
639
- }
640
-
641
- /// Returns number of currently outstanding workflow tasks
642
- #[cfg(test)]
643
- pub(crate) async fn outstanding_workflow_tasks(&self) -> usize {
644
- self.workflows
645
- .get_state_info()
646
- .await
647
- .map(|r| r.outstanding_wft)
648
- .unwrap_or_default()
649
- }
650
-
651
- #[allow(unused)]
652
- pub(crate) fn available_wft_permits(&self) -> Option<usize> {
653
- self.workflows.available_wft_permits()
654
- }
655
- #[cfg(test)]
656
- pub(crate) fn unused_wft_permits(&self) -> Option<usize> {
657
- self.workflows.unused_wft_permits()
658
- }
659
-
660
- /// Get new activity tasks (may be local or nonlocal). Local activities are returned first
661
- /// before polling the server if there are any.
662
- ///
663
- /// Returns `Ok(None)` in the event of a poll timeout or if the polling loop should otherwise
664
- /// be restarted
665
- async fn activity_poll(&self) -> Result<Option<ActivityTask>, PollError> {
666
- let local_activities_complete = self.local_activities_complete.load(Ordering::Relaxed);
667
- let non_local_activities_complete =
668
- self.non_local_activities_complete.load(Ordering::Relaxed);
669
- if local_activities_complete && non_local_activities_complete {
670
- return Err(PollError::ShutDown);
671
- }
672
- let act_mgr_poll = async {
673
- if non_local_activities_complete {
674
- future::pending::<()>().await;
675
- unreachable!()
676
- }
677
- if let Some(ref act_mgr) = self.at_task_mgr {
678
- let res = act_mgr.poll().await;
679
- if let Err(err) = res.as_ref()
680
- && matches!(err, PollError::ShutDown)
681
- {
682
- self.non_local_activities_complete
683
- .store(true, Ordering::Relaxed);
684
- return Ok(None);
685
- };
686
- res.map(Some)
687
- } else {
688
- // We expect the local activity branch below to produce shutdown when appropriate if
689
- // there are no activity pollers.
690
- future::pending::<()>().await;
691
- unreachable!()
692
- }
693
- };
694
- let local_activities_poll = async {
695
- if local_activities_complete {
696
- future::pending::<()>().await;
697
- unreachable!()
698
- }
699
- match self.local_act_mgr.next_pending().await {
700
- Some(NextPendingLAAction::Dispatch(r)) => Ok(Some(r)),
701
- Some(NextPendingLAAction::Autocomplete(action)) => {
702
- Ok(self.handle_la_complete_action(action))
703
- }
704
- None => {
705
- if self.shutdown_token.is_cancelled() {
706
- self.local_activities_complete
707
- .store(true, Ordering::Relaxed);
708
- }
709
- Ok(None)
710
- }
711
- }
712
- };
713
-
714
- let r = tokio::select! {
715
- biased;
716
-
717
- r = local_activities_poll => r,
718
- r = act_mgr_poll => r,
719
- };
720
- // Since we consider network errors (at this level) fatal, we want to start shutdown if one
721
- // is encountered
722
- if matches!(r, Err(PollError::TonicError(_))) {
723
- self.initiate_shutdown();
724
- }
725
- r
726
- }
727
-
728
- /// Attempt to record an activity heartbeat
729
- pub(crate) fn record_heartbeat(&self, details: ActivityHeartbeat) {
730
- if let Some(at_mgr) = self.at_task_mgr.as_ref() {
731
- let tt = TaskToken(details.task_token.clone());
732
- if let Err(e) = at_mgr.record_heartbeat(details) {
733
- warn!(task_token = %tt, details = ?e, "Activity heartbeat failed.");
734
- }
735
- }
736
- }
737
-
738
- #[instrument(skip(self, task_token, status),
739
- fields(task_token=%&task_token, status=%&status,
740
- task_queue=%self.config.task_queue, workflow_id, run_id))]
741
- pub(crate) async fn complete_activity(
742
- &self,
743
- task_token: TaskToken,
744
- status: activity_execution_result::Status,
745
- ) -> Result<(), CompleteActivityError> {
746
- validate_activity_completion(&status)?;
747
- if task_token.is_local_activity_task() {
748
- let as_la_res: LocalActivityExecutionResult = status.try_into()?;
749
- self.complete_local_act(task_token, as_la_res);
750
- return Ok(());
751
- }
752
-
753
- if let Some(atm) = &self.at_task_mgr {
754
- atm.complete(task_token, status, &*self.client).await;
755
- } else {
756
- error!(
757
- "Tried to complete activity {} on a worker that does not have an activity manager",
758
- task_token
759
- );
760
- }
761
- Ok(())
762
- }
763
-
764
- #[instrument(skip(self), fields(run_id, workflow_id, task_queue=%self.config.task_queue))]
765
- pub(crate) async fn next_workflow_activation(&self) -> Result<WorkflowActivation, PollError> {
766
- let r = self.workflows.next_workflow_activation().await;
767
- // In the event workflows are shutdown or erroring, begin shutdown of everything else. Once
768
- // they are shut down, tell the local activity manager that, so that it can know to cancel
769
- // any remaining outstanding LAs and shutdown.
770
- if let Err(ref e) = r {
771
- // This is covering the situation where WFT pollers dying is the reason for shutdown
772
- self.initiate_shutdown();
773
- if matches!(e, PollError::ShutDown) {
774
- self.local_act_mgr.workflows_have_shutdown();
775
- }
776
- }
777
- r
778
- }
779
-
780
- #[instrument(skip(self, completion),
781
- fields(completion=%&completion, run_id=%completion.run_id, workflow_id,
782
- task_queue=%self.config.task_queue))]
783
- pub(crate) async fn complete_workflow_activation(
784
- &self,
785
- completion: WorkflowActivationCompletion,
786
- ) -> Result<(), CompleteWfError> {
787
- self.workflows
788
- .activation_completed(
789
- completion,
790
- false,
791
- self.post_activate_hook
792
- .as_ref()
793
- .map(|h| |data: PostActivateHookData| h(self, data)),
794
- )
795
- .await?;
796
- Ok(())
797
- }
798
-
799
- #[instrument(
800
- skip(self, tt, status),
801
- fields(task_token=%&tt, status=%&status, task_queue=%self.config.task_queue)
802
- )]
803
- async fn complete_nexus_task(
804
- &self,
805
- tt: TaskToken,
806
- status: nexus_task_completion::Status,
807
- ) -> Result<(), CompleteNexusError> {
808
- self.nexus_mgr
809
- .complete_task(tt, status, &*self.client)
810
- .await
811
- }
812
-
813
- /// Request a workflow eviction
814
- pub(crate) fn request_wf_eviction(
815
- &self,
816
- run_id: &str,
817
- message: impl Into<String>,
818
- reason: EvictionReason,
819
- ) {
820
- self.workflows.request_eviction(run_id, message, reason);
821
- }
822
-
823
- /// Sets a function to be called at the end of each activation completion
824
- pub(crate) fn set_post_activate_hook(
825
- &mut self,
826
- callback: impl Fn(&Self, PostActivateHookData<'_>) + Send + Sync + 'static,
827
- ) {
828
- self.post_activate_hook = Some(Box::new(callback))
829
- }
830
-
831
- fn complete_local_act(&self, task_token: TaskToken, la_res: LocalActivityExecutionResult) {
832
- if self
833
- .handle_la_complete_action(self.local_act_mgr.complete(&task_token, la_res))
834
- .is_some()
835
- {
836
- dbg_panic!("Should never be a task from direct completion");
837
- }
838
- }
839
-
840
- fn handle_la_complete_action(&self, action: LACompleteAction) -> Option<ActivityTask> {
841
- match action {
842
- LACompleteAction::Report {
843
- run_id,
844
- resolution,
845
- task,
846
- } => {
847
- self.notify_local_result(&run_id, LocalResolution::LocalActivity(resolution));
848
- task
849
- }
850
- LACompleteAction::WillBeRetried(task) => task,
851
- LACompleteAction::Untracked => None,
852
- }
853
- }
854
-
855
- fn notify_local_result(&self, run_id: &str, res: LocalResolution) {
856
- self.workflows.notify_of_local_result(run_id, res);
857
- }
858
-
859
- async fn verify_namespace_exists(&self) -> Result<(), WorkerValidationError> {
860
- if let Err(e) = self.client.describe_namespace().await {
861
- // Ignore if unimplemented since we wouldn't want to fail against an old server, for
862
- // example.
863
- if e.code() != tonic::Code::Unimplemented {
864
- return Err(WorkerValidationError::NamespaceDescribeError {
865
- source: e,
866
- namespace: self.config.namespace.clone(),
867
- });
868
- }
869
- }
870
- Ok(())
871
- }
872
- }
873
-
874
- pub(crate) struct PostActivateHookData<'a> {
875
- pub(crate) run_id: &'a str,
876
- pub(crate) replaying: bool,
877
- }
878
-
879
- pub(crate) enum TaskPollers {
880
- Real,
881
- #[cfg(any(feature = "test-utilities", test))]
882
- Mocked {
883
- wft_stream: BoxStream<'static, Result<ValidPollWFTQResponse, tonic::Status>>,
884
- act_poller: Option<BoxedPoller<PollActivityTaskQueueResponse>>,
885
- nexus_poller: BoxedPoller<PollNexusTaskQueueResponse>,
886
- },
887
- }
888
-
889
- fn wft_poller_behavior(config: &WorkerConfig, is_sticky: bool) -> PollerBehavior {
890
- fn calc_max_nonsticky(max_polls: usize, ratio: f32) -> usize {
891
- ((max_polls as f32 * ratio) as usize).max(1)
892
- }
893
-
894
- if let PollerBehavior::SimpleMaximum(m) = config.workflow_task_poller_behavior {
895
- if !is_sticky {
896
- PollerBehavior::SimpleMaximum(calc_max_nonsticky(
897
- m,
898
- config.nonsticky_to_sticky_poll_ratio,
899
- ))
900
- } else {
901
- PollerBehavior::SimpleMaximum(
902
- m.saturating_sub(calc_max_nonsticky(m, config.nonsticky_to_sticky_poll_ratio))
903
- .max(1),
904
- )
905
- }
906
- } else {
907
- config.workflow_task_poller_behavior
908
- }
909
- }
910
-
911
- #[cfg(test)]
912
- mod tests {
913
- use super::*;
914
- use crate::{
915
- advance_fut,
916
- test_help::test_worker_cfg,
917
- worker::client::mocks::{mock_manual_worker_client, mock_worker_client},
918
- };
919
- use futures_util::FutureExt;
920
- use temporal_sdk_core_api::worker::PollerBehavior;
921
- use temporal_sdk_core_protos::temporal::api::workflowservice::v1::PollActivityTaskQueueResponse;
922
-
923
- #[tokio::test]
924
- async fn activity_timeouts_maintain_permit() {
925
- let mut mock_client = mock_worker_client();
926
- mock_client
927
- .expect_poll_activity_task()
928
- .returning(|_, _| Ok(PollActivityTaskQueueResponse::default()));
929
-
930
- let cfg = test_worker_cfg()
931
- .max_outstanding_activities(5_usize)
932
- .build()
933
- .unwrap();
934
- let worker = Worker::new_test(cfg, mock_client);
935
- let fut = worker.poll_activity_task();
936
- advance_fut!(fut);
937
- assert_eq!(
938
- worker.at_task_mgr.as_ref().unwrap().unused_permits(),
939
- Some(5)
940
- );
941
- }
942
-
943
- #[tokio::test]
944
- async fn activity_errs_dont_eat_permits() {
945
- // Return one error followed by simulating waiting on the poll, otherwise the poller will
946
- // loop very fast and be in some indeterminate state.
947
- let mut mock_client = mock_manual_worker_client();
948
- mock_client
949
- .expect_poll_activity_task()
950
- .returning(|_, _| async { Err(tonic::Status::internal("ahhh")) }.boxed())
951
- .times(1);
952
- mock_client
953
- .expect_poll_activity_task()
954
- .returning(|_, _| future::pending().boxed());
955
-
956
- let cfg = test_worker_cfg()
957
- .max_outstanding_activities(5_usize)
958
- .build()
959
- .unwrap();
960
- let worker = Worker::new_test(cfg, mock_client);
961
- assert!(worker.activity_poll().await.is_err());
962
- assert_eq!(worker.at_task_mgr.unwrap().unused_permits(), Some(5));
963
- }
964
-
965
- #[test]
966
- fn max_polls_calculated_properly() {
967
- let cfg = test_worker_cfg()
968
- .workflow_task_poller_behavior(PollerBehavior::SimpleMaximum(5_usize))
969
- .build()
970
- .unwrap();
971
- assert_eq!(
972
- wft_poller_behavior(&cfg, false),
973
- PollerBehavior::SimpleMaximum(1)
974
- );
975
- assert_eq!(
976
- wft_poller_behavior(&cfg, true),
977
- PollerBehavior::SimpleMaximum(4)
978
- );
979
- }
980
-
981
- #[test]
982
- fn max_polls_zero_is_err() {
983
- assert!(
984
- test_worker_cfg()
985
- .workflow_task_poller_behavior(PollerBehavior::SimpleMaximum(0_usize))
986
- .build()
987
- .is_err()
988
- );
989
- }
990
- }