@temporalio/core-bridge 1.7.4 → 1.8.1

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 (90) hide show
  1. package/Cargo.lock +245 -247
  2. package/Cargo.toml +1 -1
  3. package/lib/errors.d.ts +9 -0
  4. package/lib/errors.js +13 -0
  5. package/lib/errors.js.map +1 -1
  6. package/lib/index.d.ts +19 -3
  7. package/lib/index.js.map +1 -1
  8. package/package.json +3 -3
  9. package/releases/aarch64-apple-darwin/index.node +0 -0
  10. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  11. package/releases/x86_64-apple-darwin/index.node +0 -0
  12. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  13. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  14. package/sdk-core/.github/workflows/heavy.yml +1 -1
  15. package/sdk-core/.github/workflows/semgrep.yml +25 -0
  16. package/sdk-core/README.md +2 -0
  17. package/sdk-core/cargo-tokio-console.sh +5 -0
  18. package/sdk-core/client/src/lib.rs +6 -41
  19. package/sdk-core/client/src/raw.rs +9 -0
  20. package/sdk-core/client/src/retry.rs +0 -16
  21. package/sdk-core/core/Cargo.toml +9 -5
  22. package/sdk-core/core/src/abstractions.rs +7 -75
  23. package/sdk-core/core/src/core_tests/activity_tasks.rs +16 -8
  24. package/sdk-core/core/src/core_tests/local_activities.rs +97 -5
  25. package/sdk-core/core/src/core_tests/mod.rs +1 -1
  26. package/sdk-core/core/src/core_tests/workers.rs +16 -16
  27. package/sdk-core/core/src/core_tests/workflow_tasks.rs +247 -28
  28. package/sdk-core/core/src/lib.rs +2 -3
  29. package/sdk-core/core/src/pollers/mod.rs +30 -3
  30. package/sdk-core/core/src/pollers/poll_buffer.rs +166 -77
  31. package/sdk-core/core/src/protosext/mod.rs +4 -8
  32. package/sdk-core/core/src/replay/mod.rs +1 -1
  33. package/sdk-core/core/src/telemetry/metrics.rs +9 -0
  34. package/sdk-core/core/src/telemetry/mod.rs +3 -0
  35. package/sdk-core/core/src/test_help/mod.rs +9 -16
  36. package/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +6 -31
  37. package/sdk-core/core/src/worker/activities/local_activities.rs +214 -110
  38. package/sdk-core/core/src/worker/activities.rs +72 -47
  39. package/sdk-core/core/src/worker/client/mocks.rs +1 -1
  40. package/sdk-core/core/src/worker/client.rs +45 -32
  41. package/sdk-core/core/src/worker/mod.rs +170 -122
  42. package/sdk-core/core/src/worker/workflow/driven_workflow.rs +0 -4
  43. package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +9 -2
  44. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +9 -2
  45. package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +6 -3
  46. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +74 -22
  47. package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +3 -2
  48. package/sdk-core/core/src/worker/workflow/managed_run.rs +16 -3
  49. package/sdk-core/core/src/worker/workflow/mod.rs +13 -22
  50. package/sdk-core/core/src/worker/workflow/run_cache.rs +5 -0
  51. package/sdk-core/core/src/worker/workflow/wft_extraction.rs +4 -7
  52. package/sdk-core/core/src/worker/workflow/wft_poller.rs +38 -8
  53. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +1 -0
  54. package/sdk-core/core-api/src/worker.rs +43 -2
  55. package/sdk-core/protos/api_upstream/Makefile +1 -1
  56. package/sdk-core/protos/api_upstream/buf.yaml +1 -6
  57. package/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +12 -0
  58. package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +11 -0
  59. package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +13 -2
  60. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +1 -0
  61. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +2 -0
  62. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +9 -0
  63. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +19 -0
  64. package/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +5 -0
  65. package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +36 -4
  66. package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +24 -7
  67. package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +4 -0
  68. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +76 -44
  69. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +23 -1
  70. package/sdk-core/protos/google/rpc/status.proto +52 -0
  71. package/sdk-core/protos/local/temporal/sdk/core/common/common.proto +16 -0
  72. package/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +4 -0
  73. package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +6 -0
  74. package/sdk-core/sdk/src/lib.rs +31 -10
  75. package/sdk-core/sdk/src/workflow_future.rs +7 -5
  76. package/sdk-core/sdk-core-protos/src/history_builder.rs +2 -0
  77. package/sdk-core/sdk-core-protos/src/history_info.rs +1 -0
  78. package/sdk-core/sdk-core-protos/src/lib.rs +82 -73
  79. package/sdk-core/test-utils/Cargo.toml +1 -1
  80. package/sdk-core/test-utils/src/lib.rs +50 -37
  81. package/sdk-core/tests/integ_tests/metrics_tests.rs +143 -10
  82. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +26 -15
  83. package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +1 -1
  84. package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +2 -2
  85. package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +5 -1
  86. package/sdk-core/tests/integ_tests/workflow_tests.rs +1 -0
  87. package/src/conversions.rs +9 -2
  88. package/src/runtime.rs +5 -7
  89. package/ts/errors.ts +15 -0
  90. package/ts/index.ts +22 -4
@@ -3,9 +3,8 @@ mod activity_task_poller_stream;
3
3
  mod local_activities;
4
4
 
5
5
  pub(crate) use local_activities::{
6
- DispatchOrTimeoutLA, ExecutingLAId, LACompleteAction, LocalActRequest,
7
- LocalActivityExecutionResult, LocalActivityManager, LocalActivityResolution,
8
- LocalInFlightActInfo, NewLocalAct,
6
+ ExecutingLAId, LACompleteAction, LocalActRequest, LocalActivityExecutionResult,
7
+ LocalActivityManager, LocalActivityResolution, NewLocalAct, NextPendingLAAction,
9
8
  };
10
9
 
11
10
  use crate::{
@@ -14,9 +13,7 @@ use crate::{
14
13
  TrackedOwnedMeteredSemPermit, UsedMeteredSemPermit,
15
14
  },
16
15
  pollers::BoxedActPoller,
17
- telemetry::metrics::{
18
- activity_type, activity_worker_type, eager, workflow_type, MetricsContext,
19
- },
16
+ telemetry::metrics::{activity_type, eager, workflow_type, MetricsContext},
20
17
  worker::{
21
18
  activities::{
22
19
  activity_heartbeat_manager::ActivityHeartbeatError,
@@ -33,7 +30,6 @@ use futures::{
33
30
  stream::{BoxStream, PollNext},
34
31
  Stream, StreamExt,
35
32
  };
36
- use governor::{Quota, RateLimiter};
37
33
  use std::{
38
34
  convert::TryInto,
39
35
  future,
@@ -158,8 +154,7 @@ enum ActivityTaskSource {
158
154
  impl WorkerActivityTasks {
159
155
  #[allow(clippy::too_many_arguments)]
160
156
  pub(crate) fn new(
161
- max_activity_tasks: usize,
162
- max_worker_act_per_sec: Option<f64>,
157
+ semaphore: Arc<MeteredSemaphore>,
163
158
  poller: BoxedActPoller,
164
159
  client: Arc<dyn WorkerClient>,
165
160
  metrics: MetricsContext,
@@ -167,23 +162,10 @@ impl WorkerActivityTasks {
167
162
  default_heartbeat_throttle_interval: Duration,
168
163
  graceful_shutdown: Option<Duration>,
169
164
  ) -> Self {
170
- let semaphore = Arc::new(MeteredSemaphore::new(
171
- max_activity_tasks,
172
- metrics.with_new_attrs([activity_worker_type()]),
173
- MetricsContext::available_task_slots,
174
- ));
175
165
  let shutdown_initiated_token = CancellationToken::new();
176
- let rate_limiter = max_worker_act_per_sec.and_then(|ps| {
177
- Quota::with_period(Duration::from_secs_f64(ps.recip())).map(RateLimiter::direct)
178
- });
179
166
  let outstanding_activity_tasks = Arc::new(DashMap::new());
180
- let server_poller_stream = new_activity_task_poller(
181
- poller,
182
- semaphore.clone(),
183
- rate_limiter,
184
- metrics.clone(),
185
- shutdown_initiated_token.clone(),
186
- );
167
+ let server_poller_stream =
168
+ new_activity_task_poller(poller, metrics.clone(), shutdown_initiated_token.clone());
187
169
  let (eager_activities_tx, eager_activities_rx) = unbounded_channel();
188
170
  let eager_activities_semaphore = ClosableMeteredSemaphore::new_arc(semaphore);
189
171
 
@@ -430,7 +412,7 @@ impl WorkerActivityTasks {
430
412
 
431
413
  #[cfg(test)]
432
414
  pub(crate) fn remaining_activity_capacity(&self) -> usize {
433
- self.eager_activities_semaphore.available_permits()
415
+ self.eager_activities_semaphore.unused_permits()
434
416
  }
435
417
  }
436
418
 
@@ -625,42 +607,85 @@ fn worker_shutdown_failure() -> Failure {
625
607
  #[cfg(test)]
626
608
  mod tests {
627
609
  use super::*;
628
- use crate::{
629
- test_help::mock_poller_from_resps, worker::client::mocks::mock_manual_workflow_client,
630
- };
610
+ use crate::{pollers::new_activity_task_buffer, worker::client::mocks::mock_workflow_client};
611
+ use temporal_sdk_core_protos::coresdk::activity_result::ActivityExecutionResult;
631
612
 
632
613
  #[tokio::test]
633
614
  async fn per_worker_ratelimit() {
634
- let poller = mock_poller_from_resps([
635
- PollActivityTaskQueueResponse {
636
- task_token: vec![1],
637
- activity_id: "act1".to_string(),
638
- ..Default::default()
639
- }
640
- .into(),
641
- PollActivityTaskQueueResponse {
642
- task_token: vec![2],
643
- activity_id: "act2".to_string(),
644
- ..Default::default()
645
- }
646
- .into(),
647
- ]);
648
- let atm = WorkerActivityTasks::new(
615
+ let mut mock_client = mock_workflow_client();
616
+ mock_client
617
+ .expect_poll_activity_task()
618
+ .times(1)
619
+ .returning(move |_, _| {
620
+ Ok(PollActivityTaskQueueResponse {
621
+ task_token: vec![1],
622
+ activity_id: "act1".to_string(),
623
+ ..Default::default()
624
+ })
625
+ });
626
+ mock_client
627
+ .expect_poll_activity_task()
628
+ .times(1)
629
+ .returning(move |_, _| {
630
+ Ok(PollActivityTaskQueueResponse {
631
+ task_token: vec![2],
632
+ activity_id: "act2".to_string(),
633
+ ..Default::default()
634
+ })
635
+ });
636
+ mock_client
637
+ .expect_complete_activity_task()
638
+ .times(2)
639
+ .returning(|_, _| Ok(Default::default()));
640
+ let mock_client = Arc::new(mock_client);
641
+ let sem = Arc::new(MeteredSemaphore::new(
649
642
  10,
643
+ MetricsContext::no_op(),
644
+ MetricsContext::available_task_slots,
645
+ ));
646
+ let shutdown_token = CancellationToken::new();
647
+ let ap = new_activity_task_buffer(
648
+ mock_client.clone(),
649
+ "tq".to_string(),
650
+ 5, // Lots of concurrent pollers, to ensure we don't poll to much when that's the case
651
+ sem.clone(),
652
+ None,
653
+ shutdown_token.clone(),
654
+ None::<fn(usize)>,
650
655
  Some(2.0),
651
- poller,
652
- Arc::new(mock_manual_workflow_client()),
656
+ );
657
+ let atm = WorkerActivityTasks::new(
658
+ sem.clone(),
659
+ Box::new(ap),
660
+ mock_client.clone(),
653
661
  MetricsContext::no_op(),
654
662
  Duration::from_secs(1),
655
663
  Duration::from_secs(1),
656
664
  None,
657
665
  );
658
666
  let start = Instant::now();
659
- atm.poll().await.unwrap();
660
- atm.poll().await.unwrap();
667
+ let t1 = atm.poll().await.unwrap();
668
+ let t2 = atm.poll().await.unwrap();
661
669
  // At least half a second will have elapsed since we only allow 2 tasks per second.
662
670
  // With no ratelimit, even on a slow CI server with lots of load, this would typically take
663
671
  // low single digit ms or less.
664
672
  assert!(start.elapsed() > Duration::from_secs_f64(0.5));
673
+ shutdown_token.cancel();
674
+ // Need to complete the tasks so shutdown will resolve
675
+ atm.complete(
676
+ TaskToken(t1.task_token),
677
+ ActivityExecutionResult::ok(vec![1].into()).status.unwrap(),
678
+ mock_client.as_ref(),
679
+ )
680
+ .await;
681
+ atm.complete(
682
+ TaskToken(t2.task_token),
683
+ ActivityExecutionResult::ok(vec![1].into()).status.unwrap(),
684
+ mock_client.as_ref(),
685
+ )
686
+ .await;
687
+ atm.initiate_shutdown();
688
+ assert_matches!(atm.poll().await.unwrap_err(), PollActivityError::ShutDown);
689
+ atm.shutdown().await;
665
690
  }
666
691
  }
@@ -37,7 +37,7 @@ mockall::mock! {
37
37
  pub(crate) ManualWorkerClient {}
38
38
  #[allow(unused)]
39
39
  impl WorkerClient for ManualWorkerClient {
40
- fn poll_workflow_task<'a, 'b>(&'a self, task_queue: String, is_sticky: bool)
40
+ fn poll_workflow_task<'a, 'b>(&'a self, task_queue: TaskQueue)
41
41
  -> impl Future<Output = Result<PollWorkflowTaskQueueResponse>> + Send + 'b
42
42
  where 'a: 'b, Self: 'b;
43
43
 
@@ -48,11 +48,39 @@ impl WorkerClientBag {
48
48
  use_versioning,
49
49
  }
50
50
  }
51
- fn versioning_build_id(&self) -> String {
52
- if self.use_versioning {
51
+
52
+ fn default_capabilities(&self) -> Capabilities {
53
+ self.capabilities().cloned().unwrap_or_default()
54
+ }
55
+
56
+ fn binary_checksum(&self) -> String {
57
+ if self.default_capabilities().build_id_based_versioning {
58
+ "".to_string()
59
+ } else {
53
60
  self.worker_build_id.clone()
61
+ }
62
+ }
63
+
64
+ fn worker_version_capabilities(&self) -> Option<WorkerVersionCapabilities> {
65
+ if self.default_capabilities().build_id_based_versioning {
66
+ Some(WorkerVersionCapabilities {
67
+ build_id: self.worker_build_id.clone(),
68
+ use_versioning: self.use_versioning,
69
+ })
54
70
  } else {
55
- "".to_string()
71
+ None
72
+ }
73
+ }
74
+
75
+ fn worker_version_stamp(&self) -> Option<WorkerVersionStamp> {
76
+ if self.default_capabilities().build_id_based_versioning {
77
+ Some(WorkerVersionStamp {
78
+ build_id: self.worker_build_id.clone(),
79
+ bundle_id: "".to_string(),
80
+ use_versioning: self.use_versioning,
81
+ })
82
+ } else {
83
+ None
56
84
  }
57
85
  }
58
86
  }
@@ -64,8 +92,7 @@ impl WorkerClientBag {
64
92
  pub(crate) trait WorkerClient: Sync + Send {
65
93
  async fn poll_workflow_task(
66
94
  &self,
67
- task_queue: String,
68
- is_sticky: bool,
95
+ task_queue: TaskQueue,
69
96
  ) -> Result<PollWorkflowTaskQueueResponse>;
70
97
  async fn poll_activity_task(
71
98
  &self,
@@ -122,28 +149,14 @@ pub(crate) trait WorkerClient: Sync + Send {
122
149
  impl WorkerClient for WorkerClientBag {
123
150
  async fn poll_workflow_task(
124
151
  &self,
125
- task_queue: String,
126
- is_sticky: bool,
152
+ task_queue: TaskQueue,
127
153
  ) -> Result<PollWorkflowTaskQueueResponse> {
128
154
  let request = PollWorkflowTaskQueueRequest {
129
155
  namespace: self.namespace.clone(),
130
- task_queue: Some(TaskQueue {
131
- name: task_queue,
132
- kind: if is_sticky {
133
- TaskQueueKind::Sticky
134
- } else {
135
- TaskQueueKind::Normal
136
- } as i32,
137
- }),
156
+ task_queue: Some(task_queue),
138
157
  identity: self.identity.clone(),
139
- binary_checksum: if self.use_versioning {
140
- "".to_string()
141
- } else {
142
- self.worker_build_id.clone()
143
- },
144
- worker_version_capabilities: Some(WorkerVersionCapabilities {
145
- build_id: self.versioning_build_id(),
146
- }),
158
+ binary_checksum: self.binary_checksum(),
159
+ worker_version_capabilities: self.worker_version_capabilities(),
147
160
  };
148
161
 
149
162
  Ok(self
@@ -164,14 +177,13 @@ impl WorkerClient for WorkerClientBag {
164
177
  task_queue: Some(TaskQueue {
165
178
  name: task_queue,
166
179
  kind: TaskQueueKind::Normal as i32,
180
+ normal_name: "".to_string(),
167
181
  }),
168
182
  identity: self.identity.clone(),
169
183
  task_queue_metadata: max_tasks_per_sec.map(|tps| TaskQueueMetadata {
170
184
  max_tasks_per_second: Some(tps),
171
185
  }),
172
- worker_version_capabilities: Some(WorkerVersionCapabilities {
173
- build_id: self.versioning_build_id(),
174
- }),
186
+ worker_version_capabilities: self.worker_version_capabilities(),
175
187
  };
176
188
 
177
189
  Ok(self
@@ -193,12 +205,9 @@ impl WorkerClient for WorkerClientBag {
193
205
  sticky_attributes: request.sticky_attributes,
194
206
  return_new_workflow_task: request.return_new_workflow_task,
195
207
  force_create_new_workflow_task: request.force_create_new_workflow_task,
196
- worker_version_stamp: Some(WorkerVersionStamp {
197
- build_id: self.versioning_build_id(),
198
- bundle_id: "".to_string(),
199
- }),
208
+ worker_version_stamp: self.worker_version_stamp(),
200
209
  messages: vec![],
201
- binary_checksum: self.worker_build_id.clone(),
210
+ binary_checksum: self.binary_checksum(),
202
211
  query_results: request
203
212
  .query_responses
204
213
  .into_iter()
@@ -239,6 +248,7 @@ impl WorkerClient for WorkerClientBag {
239
248
  result,
240
249
  identity: self.identity.clone(),
241
250
  namespace: self.namespace.clone(),
251
+ worker_version: self.worker_version_stamp(),
242
252
  })
243
253
  .await?
244
254
  .into_inner())
@@ -275,6 +285,7 @@ impl WorkerClient for WorkerClientBag {
275
285
  details,
276
286
  identity: self.identity.clone(),
277
287
  namespace: self.namespace.clone(),
288
+ worker_version: self.worker_version_stamp(),
278
289
  })
279
290
  .await?
280
291
  .into_inner())
@@ -295,6 +306,7 @@ impl WorkerClient for WorkerClientBag {
295
306
  namespace: self.namespace.clone(),
296
307
  // TODO: Implement - https://github.com/temporalio/sdk-core/issues/293
297
308
  last_heartbeat_details: None,
309
+ worker_version: self.worker_version_stamp(),
298
310
  })
299
311
  .await?
300
312
  .into_inner())
@@ -311,9 +323,10 @@ impl WorkerClient for WorkerClientBag {
311
323
  cause: cause as i32,
312
324
  failure,
313
325
  identity: self.identity.clone(),
314
- binary_checksum: self.worker_build_id.clone(),
326
+ binary_checksum: self.binary_checksum(),
315
327
  namespace: self.namespace.clone(),
316
328
  messages: vec![],
329
+ worker_version: self.worker_version_stamp(),
317
330
  };
318
331
  Ok(self
319
332
  .client