@temporalio/core-bridge 1.9.2 → 1.10.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 (177) hide show
  1. package/Cargo.lock +754 -473
  2. package/Cargo.toml +3 -3
  3. package/lib/index.d.ts +33 -2
  4. package/lib/index.js.map +1 -1
  5. package/package.json +4 -4
  6. package/releases/aarch64-apple-darwin/index.node +0 -0
  7. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  8. package/releases/x86_64-apple-darwin/index.node +0 -0
  9. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  10. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  11. package/scripts/build.js +4 -3
  12. package/sdk-core/.cargo/config.toml +2 -4
  13. package/sdk-core/.github/workflows/heavy.yml +1 -1
  14. package/sdk-core/.github/workflows/per-pr.yml +6 -4
  15. package/sdk-core/Cargo.toml +10 -3
  16. package/sdk-core/README.md +4 -6
  17. package/sdk-core/client/Cargo.toml +13 -5
  18. package/sdk-core/client/src/lib.rs +123 -34
  19. package/sdk-core/client/src/metrics.rs +70 -18
  20. package/sdk-core/client/src/proxy.rs +85 -0
  21. package/sdk-core/client/src/raw.rs +67 -5
  22. package/sdk-core/client/src/worker_registry/mod.rs +5 -3
  23. package/sdk-core/client/src/workflow_handle/mod.rs +3 -1
  24. package/sdk-core/core/Cargo.toml +31 -37
  25. package/sdk-core/core/src/abstractions/take_cell.rs +3 -3
  26. package/sdk-core/core/src/abstractions.rs +176 -108
  27. package/sdk-core/core/src/core_tests/activity_tasks.rs +4 -13
  28. package/sdk-core/core/src/core_tests/determinism.rs +2 -1
  29. package/sdk-core/core/src/core_tests/local_activities.rs +3 -3
  30. package/sdk-core/core/src/core_tests/mod.rs +3 -3
  31. package/sdk-core/core/src/core_tests/queries.rs +42 -5
  32. package/sdk-core/core/src/core_tests/workers.rs +2 -3
  33. package/sdk-core/core/src/core_tests/workflow_tasks.rs +115 -15
  34. package/sdk-core/core/src/ephemeral_server/mod.rs +109 -136
  35. package/sdk-core/core/src/internal_flags.rs +8 -8
  36. package/sdk-core/core/src/lib.rs +16 -11
  37. package/sdk-core/core/src/pollers/mod.rs +11 -5
  38. package/sdk-core/core/src/pollers/poll_buffer.rs +48 -29
  39. package/sdk-core/core/src/protosext/mod.rs +32 -32
  40. package/sdk-core/core/src/protosext/protocol_messages.rs +14 -24
  41. package/sdk-core/core/src/retry_logic.rs +2 -2
  42. package/sdk-core/core/src/telemetry/log_export.rs +10 -9
  43. package/sdk-core/core/src/telemetry/metrics.rs +233 -330
  44. package/sdk-core/core/src/telemetry/mod.rs +11 -38
  45. package/sdk-core/core/src/telemetry/otel.rs +355 -0
  46. package/sdk-core/core/src/telemetry/prometheus_server.rs +36 -23
  47. package/sdk-core/core/src/test_help/mod.rs +80 -59
  48. package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +6 -6
  49. package/sdk-core/core/src/worker/activities/local_activities.rs +46 -43
  50. package/sdk-core/core/src/worker/activities.rs +45 -46
  51. package/sdk-core/core/src/worker/client/mocks.rs +8 -7
  52. package/sdk-core/core/src/worker/client.rs +40 -39
  53. package/sdk-core/core/src/worker/mod.rs +72 -42
  54. package/sdk-core/core/src/worker/slot_provider.rs +28 -28
  55. package/sdk-core/core/src/worker/slot_supplier.rs +1 -0
  56. package/sdk-core/core/src/worker/tuner/fixed_size.rs +52 -0
  57. package/sdk-core/core/src/worker/tuner/resource_based.rs +561 -0
  58. package/sdk-core/core/src/worker/tuner.rs +122 -0
  59. package/sdk-core/core/src/worker/workflow/driven_workflow.rs +6 -6
  60. package/sdk-core/core/src/worker/workflow/history_update.rs +27 -53
  61. package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +4 -17
  62. package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -10
  63. package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +4 -11
  64. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +17 -35
  65. package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +0 -8
  66. package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +1 -5
  67. package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +0 -5
  68. package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +0 -5
  69. package/sdk-core/core/src/worker/workflow/machines/mod.rs +0 -14
  70. package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +0 -5
  71. package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +0 -5
  72. package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -10
  73. package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +3 -10
  74. package/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +12 -8
  75. package/sdk-core/core/src/worker/workflow/machines/update_state_machine.rs +0 -10
  76. package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +6 -13
  77. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +27 -37
  78. package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +3 -14
  79. package/sdk-core/core/src/worker/workflow/managed_run.rs +84 -54
  80. package/sdk-core/core/src/worker/workflow/mod.rs +63 -160
  81. package/sdk-core/core/src/worker/workflow/run_cache.rs +22 -13
  82. package/sdk-core/core/src/worker/workflow/wft_extraction.rs +16 -3
  83. package/sdk-core/core/src/worker/workflow/wft_poller.rs +15 -12
  84. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +39 -78
  85. package/sdk-core/core-api/Cargo.toml +6 -5
  86. package/sdk-core/core-api/src/errors.rs +8 -0
  87. package/sdk-core/core-api/src/telemetry/metrics.rs +75 -4
  88. package/sdk-core/core-api/src/telemetry.rs +7 -1
  89. package/sdk-core/core-api/src/worker.rs +212 -56
  90. package/sdk-core/fsm/Cargo.toml +3 -0
  91. package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +1 -1
  92. package/sdk-core/sdk/Cargo.toml +5 -7
  93. package/sdk-core/sdk/src/app_data.rs +3 -3
  94. package/sdk-core/sdk/src/lib.rs +5 -3
  95. package/sdk-core/sdk/src/workflow_context/options.rs +1 -1
  96. package/sdk-core/sdk/src/workflow_context.rs +10 -9
  97. package/sdk-core/sdk/src/workflow_future.rs +1 -1
  98. package/sdk-core/sdk-core-protos/Cargo.toml +8 -6
  99. package/sdk-core/sdk-core-protos/build.rs +1 -10
  100. package/sdk-core/sdk-core-protos/protos/api_upstream/.github/PULL_REQUEST_TEMPLATE.md +3 -0
  101. package/sdk-core/sdk-core-protos/protos/api_upstream/.github/workflows/ci.yml +26 -0
  102. package/sdk-core/sdk-core-protos/protos/api_upstream/Makefile +42 -20
  103. package/sdk-core/sdk-core-protos/protos/api_upstream/README.md +2 -0
  104. package/sdk-core/sdk-core-protos/protos/api_upstream/api-linter.yaml +36 -26
  105. package/sdk-core/sdk-core-protos/protos/api_upstream/buf.lock +2 -0
  106. package/sdk-core/sdk-core-protos/protos/api_upstream/google/protobuf/struct.proto +95 -0
  107. package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv2.json +9632 -0
  108. package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv3.yaml +7337 -0
  109. package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/payload_description.txt +2 -0
  110. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/command/v1/message.proto +45 -11
  111. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/common/v1/message.proto +22 -4
  112. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/command_type.proto +2 -0
  113. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/common.proto +44 -0
  114. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/event_type.proto +18 -3
  115. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +20 -0
  116. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +30 -0
  117. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/update.proto +7 -8
  118. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/workflow.proto +23 -5
  119. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/errordetails/v1/message.proto +20 -0
  120. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/failure/v1/message.proto +25 -0
  121. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/history/v1/message.proto +141 -15
  122. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/namespace/v1/message.proto +12 -0
  123. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/nexus/v1/message.proto +193 -0
  124. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +73 -6
  125. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +46 -4
  126. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/schedule/v1/message.proto +4 -0
  127. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/sdk/v1/workflow_metadata.proto +2 -2
  128. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +116 -0
  129. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflow/v1/message.proto +134 -0
  130. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +274 -29
  131. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +57 -1
  132. package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +10 -12
  133. package/sdk-core/sdk-core-protos/src/history_builder.rs +1 -1
  134. package/sdk-core/sdk-core-protos/src/lib.rs +54 -51
  135. package/sdk-core/sdk-core-protos/src/task_token.rs +11 -2
  136. package/sdk-core/test-utils/Cargo.toml +7 -4
  137. package/sdk-core/test-utils/src/histfetch.rs +1 -1
  138. package/sdk-core/test-utils/src/lib.rs +44 -62
  139. package/sdk-core/tests/fuzzy_workflow.rs +5 -2
  140. package/sdk-core/tests/heavy_tests.rs +114 -17
  141. package/sdk-core/tests/integ_tests/activity_functions.rs +1 -1
  142. package/sdk-core/tests/integ_tests/client_tests.rs +2 -2
  143. package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +38 -26
  144. package/sdk-core/tests/integ_tests/metrics_tests.rs +126 -17
  145. package/sdk-core/tests/integ_tests/polling_tests.rs +118 -2
  146. package/sdk-core/tests/integ_tests/update_tests.rs +3 -5
  147. package/sdk-core/tests/integ_tests/visibility_tests.rs +3 -3
  148. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +1 -1
  149. package/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +1 -1
  150. package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -1
  151. package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -1
  152. package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +3 -3
  153. package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +5 -4
  154. package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -2
  155. package/sdk-core/tests/integ_tests/workflow_tests/eager.rs +6 -10
  156. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +9 -7
  157. package/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +1 -1
  158. package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +14 -9
  159. package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -1
  160. package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +6 -13
  161. package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +9 -6
  162. package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +5 -5
  163. package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +1 -1
  164. package/sdk-core/tests/integ_tests/workflow_tests.rs +115 -11
  165. package/sdk-core/tests/main.rs +2 -2
  166. package/src/conversions.rs +57 -0
  167. package/src/lib.rs +1 -0
  168. package/src/runtime.rs +51 -35
  169. package/ts/index.ts +67 -3
  170. package/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +0 -117
  171. package/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +0 -24
  172. package/sdk-core/sdk/src/payload_converter.rs +0 -11
  173. package/sdk-core/sdk-core-protos/protos/api_upstream/.buildkite/Dockerfile +0 -2
  174. package/sdk-core/sdk-core-protos/protos/api_upstream/.buildkite/docker-compose.yml +0 -15
  175. package/sdk-core/sdk-core-protos/protos/api_upstream/.buildkite/pipeline.yml +0 -10
  176. package/sdk-core/test-utils/src/wf_input_saver.rs +0 -50
  177. package/sdk-core/tests/wf_input_replay.rs +0 -32
@@ -37,7 +37,7 @@ use temporal_sdk_core_api::{
37
37
  };
38
38
  use temporal_sdk_core_protos::{
39
39
  coresdk::{
40
- workflow_activation::WorkflowActivation,
40
+ workflow_activation::{workflow_activation_job, WorkflowActivation},
41
41
  workflow_commands::workflow_command,
42
42
  workflow_completion::{self, workflow_activation_completion, WorkflowActivationCompletion},
43
43
  },
@@ -51,15 +51,15 @@ use temporal_sdk_core_protos::{
51
51
  },
52
52
  },
53
53
  };
54
- use temporal_sdk_core_test_utils::TestWorker;
54
+ use temporal_sdk_core_test_utils::{TestWorker, NAMESPACE};
55
55
  use tokio::sync::{mpsc::unbounded_channel, Notify};
56
56
  use tokio_stream::wrappers::UnboundedReceiverStream;
57
57
 
58
- pub const TEST_Q: &str = "q";
58
+ pub(crate) const TEST_Q: &str = "q";
59
59
 
60
- pub fn test_worker_cfg() -> WorkerConfigBuilder {
60
+ pub(crate) fn test_worker_cfg() -> WorkerConfigBuilder {
61
61
  let mut wcb = WorkerConfigBuilder::default();
62
- wcb.namespace("default")
62
+ wcb.namespace(NAMESPACE)
63
63
  .task_queue(TEST_Q)
64
64
  .worker_build_id("test_bin_id")
65
65
  .ignore_evicts_on_shutdown(true)
@@ -71,7 +71,7 @@ pub fn test_worker_cfg() -> WorkerConfigBuilder {
71
71
  /// When constructing responses for mocks, indicates how a given response should be built
72
72
  #[derive(derive_more::From)]
73
73
  #[allow(clippy::large_enum_variant)] // Test only code, whatever.
74
- pub enum ResponseType {
74
+ pub(crate) enum ResponseType {
75
75
  ToTaskNum(usize),
76
76
  /// Returns just the history after the WFT completed of the provided task number - 1, through to
77
77
  /// the next WFT started. Simulating the incremental history for just the provided task number
@@ -84,8 +84,9 @@ pub enum ResponseType {
84
84
  AllHistory,
85
85
  Raw(PollWorkflowTaskQueueResponse),
86
86
  }
87
+
87
88
  #[derive(Eq, PartialEq, Hash)]
88
- pub enum HashableResponseType {
89
+ pub(crate) enum HashableResponseType {
89
90
  ToTaskNum(usize),
90
91
  OneTask(usize),
91
92
  UntilResolved(usize),
@@ -93,8 +94,9 @@ pub enum HashableResponseType {
93
94
  AllHistory,
94
95
  Raw(TaskToken),
95
96
  }
97
+
96
98
  impl ResponseType {
97
- pub fn hashable(&self) -> HashableResponseType {
99
+ fn hashable(&self) -> HashableResponseType {
98
100
  match self {
99
101
  ResponseType::ToTaskNum(x) => HashableResponseType::ToTaskNum(*x),
100
102
  ResponseType::OneTask(x) => HashableResponseType::OneTask(*x),
@@ -107,6 +109,7 @@ impl ResponseType {
107
109
  }
108
110
  }
109
111
  }
112
+
110
113
  impl From<&usize> for ResponseType {
111
114
  fn from(u: &usize) -> Self {
112
115
  Self::ToTaskNum(*u)
@@ -139,7 +142,10 @@ pub(crate) fn build_fake_worker(
139
142
 
140
143
  pub(crate) fn build_fake_sdk(mock_cfg: MockPollCfg) -> temporal_sdk::Worker {
141
144
  let mut mock = build_mock_pollers(mock_cfg);
142
- mock.worker_cfg(|c| c.max_cached_workflows = 1);
145
+ mock.worker_cfg(|c| {
146
+ c.max_cached_workflows = 1;
147
+ c.ignore_evicts_on_shutdown = false;
148
+ });
143
149
  let core = mock_worker(mock);
144
150
  let mut worker = temporal_sdk::Worker::new_from_core(Arc::new(core), "replay_q".to_string());
145
151
  worker.set_worker_interceptor(FailOnNondeterminismInterceptor {});
@@ -179,37 +185,39 @@ pub(crate) fn mock_sdk_cfg(
179
185
  TestWorker::new(Arc::new(core), TEST_Q.to_string())
180
186
  }
181
187
 
182
- pub struct FakeWfResponses {
183
- pub wf_id: String,
184
- pub hist: TestHistoryBuilder,
185
- pub response_batches: Vec<ResponseType>,
188
+ pub(crate) struct FakeWfResponses {
189
+ pub(crate) wf_id: String,
190
+ pub(crate) hist: TestHistoryBuilder,
191
+ pub(crate) response_batches: Vec<ResponseType>,
186
192
  }
187
193
 
188
194
  // TODO: Should be all-internal to this module
189
- pub struct MocksHolder {
195
+ pub(crate) struct MocksHolder {
190
196
  client: Arc<dyn WorkerClient>,
191
197
  inputs: MockWorkerInputs,
192
- pub outstanding_task_map: Option<OutstandingWFTMap>,
198
+ pub(crate) outstanding_task_map: Option<OutstandingWFTMap>,
193
199
  }
194
200
 
195
201
  impl MocksHolder {
196
- pub fn worker_cfg(&mut self, mutator: impl FnOnce(&mut WorkerConfig)) {
202
+ pub(crate) fn worker_cfg(&mut self, mutator: impl FnOnce(&mut WorkerConfig)) {
197
203
  mutator(&mut self.inputs.config);
198
204
  }
199
- pub fn set_act_poller(&mut self, poller: BoxedPoller<PollActivityTaskQueueResponse>) {
205
+
206
+ pub(crate) fn set_act_poller(&mut self, poller: BoxedPoller<PollActivityTaskQueueResponse>) {
200
207
  self.inputs.act_poller = Some(poller);
201
208
  }
209
+
202
210
  /// Can be used for tests that need to avoid auto-shutdown due to running out of mock responses
203
- pub fn make_wft_stream_interminable(&mut self) {
211
+ pub(crate) fn make_wft_stream_interminable(&mut self) {
204
212
  let old_stream = std::mem::replace(&mut self.inputs.wft_stream, stream::pending().boxed());
205
213
  self.inputs.wft_stream = old_stream.chain(stream::pending()).boxed();
206
214
  }
207
215
  }
208
216
 
209
- pub struct MockWorkerInputs {
210
- pub wft_stream: BoxStream<'static, Result<ValidPollWFTQResponse, tonic::Status>>,
211
- pub act_poller: Option<BoxedPoller<PollActivityTaskQueueResponse>>,
212
- pub config: WorkerConfig,
217
+ pub(crate) struct MockWorkerInputs {
218
+ pub(crate) wft_stream: BoxStream<'static, Result<ValidPollWFTQResponse, tonic::Status>>,
219
+ pub(crate) act_poller: Option<BoxedPoller<PollActivityTaskQueueResponse>>,
220
+ pub(crate) config: WorkerConfig,
213
221
  }
214
222
 
215
223
  impl Default for MockWorkerInputs {
@@ -219,7 +227,7 @@ impl Default for MockWorkerInputs {
219
227
  }
220
228
 
221
229
  impl MockWorkerInputs {
222
- pub fn new(
230
+ pub(crate) fn new(
223
231
  wft_stream: BoxStream<'static, Result<ValidPollWFTQResponse, tonic::Status>>,
224
232
  ) -> Self {
225
233
  Self {
@@ -313,7 +321,7 @@ where
313
321
  Box::new(mock_poller) as BoxedPoller<T>
314
322
  }
315
323
 
316
- pub fn mock_poller<T>() -> MockPoller<T>
324
+ pub(crate) fn mock_poller<T>() -> MockPoller<T>
317
325
  where
318
326
  T: Send + Sync + 'static,
319
327
  {
@@ -323,7 +331,7 @@ where
323
331
  mock_poller
324
332
  }
325
333
 
326
- pub fn mock_manual_poller<T>() -> MockManualPoller<T>
334
+ pub(crate) fn mock_manual_poller<T>() -> MockManualPoller<T>
327
335
  where
328
336
  T: Send + Sync + 'static,
329
337
  {
@@ -372,25 +380,25 @@ pub(crate) fn single_hist_mock_sg(
372
380
 
373
381
  #[allow(clippy::type_complexity)]
374
382
  pub(crate) struct MockPollCfg {
375
- pub hists: Vec<FakeWfResponses>,
376
- pub enforce_correct_number_of_polls: bool,
377
- pub num_expected_fails: usize,
378
- pub num_expected_legacy_query_resps: usize,
379
- pub mock_client: MockWorkerClient,
383
+ pub(crate) hists: Vec<FakeWfResponses>,
384
+ pub(crate) enforce_correct_number_of_polls: bool,
385
+ pub(crate) num_expected_fails: usize,
386
+ pub(crate) num_expected_legacy_query_resps: usize,
387
+ pub(crate) mock_client: MockWorkerClient,
380
388
  /// All calls to fail WFTs must match this predicate
381
- pub expect_fail_wft_matcher:
389
+ pub(crate) expect_fail_wft_matcher:
382
390
  Box<dyn Fn(&TaskToken, &WorkflowTaskFailedCause, &Option<Failure>) -> bool + Send>,
383
- pub completion_asserts: Option<Box<dyn FnMut(&WorkflowTaskCompletion) + Send>>,
384
- pub num_expected_completions: Option<TimesRange>,
391
+ pub(crate) completion_asserts: Option<Box<dyn FnMut(&WorkflowTaskCompletion) + Send>>,
392
+ pub(crate) num_expected_completions: Option<TimesRange>,
385
393
  /// If being used with the Rust SDK, this is set true. It ensures pollers will not error out
386
394
  /// early with no work, since we cannot know the exact number of times polling will happen.
387
395
  /// Instead, they will just block forever.
388
- pub using_rust_sdk: bool,
389
- pub make_poll_stream_interminable: bool,
396
+ pub(crate) using_rust_sdk: bool,
397
+ pub(crate) make_poll_stream_interminable: bool,
390
398
  }
391
399
 
392
400
  impl MockPollCfg {
393
- pub fn new(
401
+ pub(crate) fn new(
394
402
  hists: Vec<FakeWfResponses>,
395
403
  enforce_correct_number_of_polls: bool,
396
404
  num_expected_fails: usize,
@@ -410,20 +418,20 @@ impl MockPollCfg {
410
418
  }
411
419
 
412
420
  /// Builds a config which will hand out each WFT in the history builder one by one
413
- pub fn from_hist_builder(t: TestHistoryBuilder) -> Self {
421
+ pub(crate) fn from_hist_builder(t: TestHistoryBuilder) -> Self {
414
422
  let full_hist_info = t.get_full_history_info().unwrap();
415
423
  let tasks = 1..=full_hist_info.wf_task_count();
416
424
  Self::from_resp_batches("fake_wf_id", t, tasks, mock_workflow_client())
417
425
  }
418
426
 
419
- pub fn from_resps(
427
+ pub(crate) fn from_resps(
420
428
  t: TestHistoryBuilder,
421
429
  resps: impl IntoIterator<Item = impl Into<ResponseType>>,
422
430
  ) -> Self {
423
431
  Self::from_resp_batches("fake_wf_id", t, resps, mock_workflow_client())
424
432
  }
425
433
 
426
- pub fn from_resp_batches(
434
+ pub(crate) fn from_resp_batches(
427
435
  wf_id: &str,
428
436
  t: TestHistoryBuilder,
429
437
  resps: impl IntoIterator<Item = impl Into<ResponseType>>,
@@ -447,7 +455,7 @@ impl MockPollCfg {
447
455
  }
448
456
  }
449
457
 
450
- pub fn completion_asserts_from_expectations(
458
+ pub(crate) fn completion_asserts_from_expectations(
451
459
  &mut self,
452
460
  builder_fn: impl FnOnce(CompletionAssertsBuilder<'_>),
453
461
  ) {
@@ -464,8 +472,9 @@ pub(crate) struct CompletionAssertsBuilder<'a> {
464
472
  dest: &'a mut Option<Box<dyn FnMut(&WorkflowTaskCompletion) + Send>>,
465
473
  assertions: VecDeque<Box<dyn FnOnce(&WorkflowTaskCompletion) + Send>>,
466
474
  }
475
+
467
476
  impl CompletionAssertsBuilder<'_> {
468
- pub fn then(
477
+ pub(crate) fn then(
469
478
  &mut self,
470
479
  assert: impl FnOnce(&WorkflowTaskCompletion) + Send + 'static,
471
480
  ) -> &mut Self {
@@ -473,6 +482,7 @@ impl CompletionAssertsBuilder<'_> {
473
482
  self
474
483
  }
475
484
  }
485
+
476
486
  impl Drop for CompletionAssertsBuilder<'_> {
477
487
  fn drop(&mut self) {
478
488
  let mut asserts = std::mem::take(&mut self.assertions);
@@ -485,27 +495,32 @@ impl Drop for CompletionAssertsBuilder<'_> {
485
495
  }
486
496
 
487
497
  #[derive(Default, Clone)]
488
- pub struct OutstandingWFTMap {
498
+ pub(crate) struct OutstandingWFTMap {
489
499
  map: Arc<RwLock<BiMap<String, TaskToken>>>,
490
500
  waker: Arc<Notify>,
491
501
  all_work_delivered: Arc<AtomicBool>,
492
502
  }
503
+
493
504
  impl OutstandingWFTMap {
494
505
  fn has_run(&self, run_id: &str) -> bool {
495
506
  self.map.read().contains_left(run_id)
496
507
  }
508
+
497
509
  fn put_token(&self, run_id: String, token: TaskToken) {
498
510
  self.map.write().insert(run_id, token);
499
511
  }
512
+
500
513
  fn release_token(&self, token: &TaskToken) {
501
514
  self.map.write().remove_by_right(token);
502
515
  self.waker.notify_one();
503
516
  }
504
- pub fn release_run(&self, run_id: &str) {
517
+
518
+ pub(crate) fn release_run(&self, run_id: &str) {
505
519
  self.map.write().remove_by_left(run_id);
506
520
  self.waker.notify_waiters();
507
521
  }
508
- pub fn all_work_delivered(&self) -> bool {
522
+
523
+ pub(crate) fn all_work_delivered(&self) -> bool {
509
524
  self.all_work_delivered.load(Ordering::Acquire)
510
525
  }
511
526
  }
@@ -690,10 +705,11 @@ pub(crate) fn build_mock_pollers(mut cfg: MockPollCfg) -> MocksHolder {
690
705
  mh
691
706
  }
692
707
 
693
- pub struct QueueResponse<T> {
694
- pub resp: T,
695
- pub delay_until: Option<BoxFuture<'static, ()>>,
708
+ pub(crate) struct QueueResponse<T> {
709
+ pub(crate) resp: T,
710
+ pub(crate) delay_until: Option<BoxFuture<'static, ()>>,
696
711
  }
712
+
697
713
  impl<T> From<T> for QueueResponse<T> {
698
714
  fn from(resp: T) -> Self {
699
715
  QueueResponse {
@@ -732,7 +748,7 @@ where
732
748
  }
733
749
  }
734
750
 
735
- pub fn hist_to_poll_resp(
751
+ pub(crate) fn hist_to_poll_resp(
736
752
  t: &TestHistoryBuilder,
737
753
  wf_id: impl Into<String>,
738
754
  response_type: ResponseType,
@@ -828,18 +844,23 @@ pub(crate) async fn poll_and_reply_clears_outstanding_evicts<'a>(
828
844
  }
829
845
 
830
846
  let mut res = worker.poll_workflow_activation().await.unwrap();
831
- let contains_eviction = res.eviction_index();
847
+ if res.jobs.iter().any(|j| {
848
+ matches!(
849
+ j.variant,
850
+ Some(workflow_activation_job::Variant::RemoveFromCache(_))
851
+ )
852
+ }) && res.jobs.len() > 1
853
+ {
854
+ panic!("Saw an activation with an eviction & other work! {res:?}");
855
+ }
856
+ let is_eviction = res.is_only_eviction();
832
857
 
833
858
  let mut do_release = false;
834
- if let Some(eviction_job_ix) = contains_eviction {
835
- // If the job list has an eviction, make sure it was the last item in the list
836
- // then remove it, since in the tests we don't explicitly specify evict assertions
837
- assert_eq!(
838
- eviction_job_ix,
839
- res.jobs.len() - 1,
840
- "Eviction job was not last job in job list"
841
- );
842
- res.jobs.remove(eviction_job_ix);
859
+
860
+ if is_eviction {
861
+ // If the job is an eviction, clear it, since in the tests we don't explicitly
862
+ // specify evict assertions
863
+ res.jobs.clear();
843
864
  do_release = true;
844
865
  }
845
866
 
@@ -870,7 +891,7 @@ pub(crate) async fn poll_and_reply_clears_outstanding_evicts<'a>(
870
891
  }
871
892
  // Restart assertions from the beginning if it was an eviction (and workflow execution
872
893
  // isn't over)
873
- if contains_eviction.is_some() && !ends_execution {
894
+ if is_eviction && !ends_execution {
874
895
  continue 'outer;
875
896
  }
876
897
 
@@ -45,11 +45,11 @@ enum HeartbeatAction {
45
45
  }
46
46
 
47
47
  #[derive(Debug)]
48
- pub struct ValidActivityHeartbeat {
49
- pub task_token: TaskToken,
50
- pub details: Vec<Payload>,
51
- pub throttle_interval: Duration,
52
- pub timeout_resetter: Option<Arc<Notify>>,
48
+ struct ValidActivityHeartbeat {
49
+ task_token: TaskToken,
50
+ details: Vec<Payload>,
51
+ throttle_interval: Duration,
52
+ timeout_resetter: Option<Arc<Notify>>,
53
53
  }
54
54
 
55
55
  #[derive(Debug)]
@@ -65,7 +65,7 @@ enum HeartbeatExecutorAction {
65
65
 
66
66
  /// Errors thrown when heartbeating
67
67
  #[derive(thiserror::Error, Debug)]
68
- pub enum ActivityHeartbeatError {
68
+ pub(crate) enum ActivityHeartbeatError {
69
69
  /// Heartbeat referenced an activity that we don't think exists. It may have completed already.
70
70
  #[error("Heartbeat has been sent for activity that either completed or never started on this worker.")]
71
71
  UnknownActivity,
@@ -1,5 +1,5 @@
1
1
  use crate::{
2
- abstractions::{dbg_panic, MeteredSemaphore, OwnedMeteredSemPermit, UsedMeteredSemPermit},
2
+ abstractions::{dbg_panic, MeteredPermitDealer, OwnedMeteredSemPermit, UsedMeteredSemPermit},
3
3
  protosext::ValidScheduleLA,
4
4
  retry_logic::RetryPolicyExt,
5
5
  worker::workflow::HeartbeatTimeoutMsg,
@@ -12,9 +12,11 @@ use std::{
12
12
  collections::{hash_map::Entry, HashMap},
13
13
  fmt::{Debug, Formatter},
14
14
  pin::Pin,
15
+ sync::Arc,
15
16
  task::{Context, Poll},
16
17
  time::{Duration, Instant, SystemTime},
17
18
  };
19
+ use temporal_sdk_core_api::worker::{LocalActivitySlotInfo, LocalActivitySlotKind, SlotSupplier};
18
20
  use temporal_sdk_core_protos::{
19
21
  coresdk::{
20
22
  activity_result::{Cancellation, Failure as ActFail, Success},
@@ -47,18 +49,14 @@ pub(crate) enum NextPendingLAAction {
47
49
  }
48
50
 
49
51
  #[derive(Debug)]
50
- pub(crate) struct LocalInFlightActInfo {
51
- pub la_info: NewLocalAct,
52
- pub dispatch_time: Instant,
53
- pub attempt: u32,
54
- _permit: UsedMeteredSemPermit,
52
+ struct LocalInFlightActInfo {
53
+ la_info: NewLocalAct,
54
+ dispatch_time: Instant,
55
+ attempt: u32,
56
+ _permit: UsedMeteredSemPermit<LocalActivitySlotKind>,
55
57
  }
56
58
 
57
59
  #[derive(Debug, Clone)]
58
- #[cfg_attr(
59
- feature = "save_wf_inputs",
60
- derive(serde::Serialize, serde::Deserialize)
61
- )]
62
60
  pub(crate) enum LocalActivityExecutionResult {
63
61
  Completed(Success),
64
62
  Failed(ActFail),
@@ -97,33 +95,30 @@ impl LocalActivityExecutionResult {
97
95
  ..
98
96
  }),
99
97
  ..
100
- }) => TimeoutType::from_i32(*timeout_type),
98
+ }) => TimeoutType::try_from(*timeout_type).ok(),
101
99
  _ => None,
102
100
  }
103
101
  }
104
102
  }
105
103
 
106
104
  #[derive(Debug, Clone)]
107
- #[cfg_attr(
108
- feature = "save_wf_inputs",
109
- derive(serde::Serialize, serde::Deserialize)
110
- )]
111
105
  pub(crate) struct LocalActivityResolution {
112
- pub seq: u32,
113
- pub result: LocalActivityExecutionResult,
114
- pub runtime: Duration,
115
- pub attempt: u32,
116
- pub backoff: Option<prost_types::Duration>,
117
- pub original_schedule_time: Option<SystemTime>,
106
+ pub(crate) seq: u32,
107
+ pub(crate) result: LocalActivityExecutionResult,
108
+ pub(crate) runtime: Duration,
109
+ pub(crate) attempt: u32,
110
+ pub(crate) backoff: Option<prost_types::Duration>,
111
+ pub(crate) original_schedule_time: Option<SystemTime>,
118
112
  }
119
113
 
120
114
  #[derive(Clone)]
121
115
  pub(crate) struct NewLocalAct {
122
- pub schedule_cmd: ValidScheduleLA,
123
- pub workflow_type: String,
124
- pub workflow_exec_info: WorkflowExecution,
125
- pub schedule_time: SystemTime,
116
+ pub(crate) schedule_cmd: ValidScheduleLA,
117
+ pub(crate) workflow_type: String,
118
+ pub(crate) workflow_exec_info: WorkflowExecution,
119
+ pub(crate) schedule_time: SystemTime,
126
120
  }
121
+
127
122
  impl Debug for NewLocalAct {
128
123
  fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
129
124
  write!(
@@ -154,8 +149,8 @@ pub(crate) enum LocalActRequest {
154
149
 
155
150
  #[derive(Debug, Clone, Eq, PartialEq, Hash)]
156
151
  pub(crate) struct ExecutingLAId {
157
- pub run_id: String,
158
- pub seq_num: u32,
152
+ pub(crate) run_id: String,
153
+ pub(crate) seq_num: u32,
159
154
  }
160
155
 
161
156
  pub(crate) struct LocalActivityManager {
@@ -210,7 +205,7 @@ impl LAMData {
210
205
 
211
206
  impl LocalActivityManager {
212
207
  pub(crate) fn new(
213
- max_concurrent: usize,
208
+ slot_supplier: Arc<dyn SlotSupplier<SlotKind = LocalActivitySlotKind> + Send + Sync>,
214
209
  namespace: String,
215
210
  heartbeat_timeout_tx: UnboundedSender<HeartbeatTimeoutMsg>,
216
211
  metrics_context: MetricsContext,
@@ -218,11 +213,7 @@ impl LocalActivityManager {
218
213
  let (act_req_tx, act_req_rx) = unbounded_channel();
219
214
  let (cancels_req_tx, cancels_req_rx) = unbounded_channel();
220
215
  let shutdown_complete_tok = CancellationToken::new();
221
- let semaphore = MeteredSemaphore::new(
222
- max_concurrent,
223
- metrics_context,
224
- MetricsContext::available_task_slots,
225
- );
216
+ let semaphore = MeteredPermitDealer::new(slot_supplier, metrics_context, None);
226
217
  Self {
227
218
  namespace,
228
219
  rcvs: tokio::sync::Mutex::new(RcvChans::new(
@@ -247,13 +238,11 @@ impl LocalActivityManager {
247
238
 
248
239
  #[cfg(test)]
249
240
  fn test(max_concurrent: usize) -> Self {
241
+ use crate::worker::tuner::FixedSizeSlotSupplier;
242
+
243
+ let ss = Arc::new(FixedSizeSlotSupplier::new(max_concurrent));
250
244
  let (hb_tx, _hb_rx) = unbounded_channel();
251
- Self::new(
252
- max_concurrent,
253
- "fake_ns".to_string(),
254
- hb_tx,
255
- MetricsContext::no_op(),
256
- )
245
+ Self::new(ss, "fake_ns".to_string(), hb_tx, MetricsContext::no_op())
257
246
  }
258
247
 
259
248
  #[cfg(test)]
@@ -386,7 +375,19 @@ impl LocalActivityManager {
386
375
  let (new_or_retry, permit) = match self.rcvs.lock().await.next().await? {
387
376
  NewOrCancel::Cancel(c) => {
388
377
  return match c {
389
- CancelOrTimeout::Cancel(c) => Some(NextPendingLAAction::Dispatch(c)),
378
+ CancelOrTimeout::Cancel(c) => {
379
+ if self
380
+ .dat
381
+ .lock()
382
+ .outstanding_activity_tasks
383
+ .contains_key(c.task_token.as_slice())
384
+ {
385
+ Some(NextPendingLAAction::Dispatch(c))
386
+ } else {
387
+ // Don't dispatch cancels for things we've already stopped tracking
388
+ None
389
+ }
390
+ }
390
391
  CancelOrTimeout::Timeout { run_id, resolution } => {
391
392
  let tt = self
392
393
  .dat
@@ -471,7 +472,9 @@ impl LocalActivityManager {
471
472
  la_info: la_info_for_in_flight_map,
472
473
  dispatch_time: Instant::now(),
473
474
  attempt,
474
- _permit: permit.into_used(),
475
+ _permit: permit.into_used(LocalActivitySlotInfo {
476
+ activity_type: new_la.workflow_type.as_str(),
477
+ }),
475
478
  },
476
479
  );
477
480
 
@@ -787,7 +790,7 @@ enum CancelOrTimeout {
787
790
 
788
791
  #[allow(clippy::large_enum_variant)]
789
792
  enum NewOrCancel {
790
- New(NewOrRetry, OwnedMeteredSemPermit),
793
+ New(NewOrRetry, OwnedMeteredSemPermit<LocalActivitySlotKind>),
791
794
  Cancel(CancelOrTimeout),
792
795
  }
793
796
 
@@ -800,7 +803,7 @@ struct RcvChans {
800
803
  impl RcvChans {
801
804
  fn new(
802
805
  new_reqs: UnboundedReceiver<NewOrRetry>,
803
- new_sem: MeteredSemaphore,
806
+ new_sem: MeteredPermitDealer<LocalActivitySlotKind>,
804
807
  cancels: UnboundedReceiver<CancelOrTimeout>,
805
808
  shutdown_completed: CancellationToken,
806
809
  ) -> Self {