@temporalio/core-bridge 0.14.0 → 0.16.4

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 (75) hide show
  1. package/Cargo.lock +162 -38
  2. package/Cargo.toml +3 -3
  3. package/index.d.ts +14 -1
  4. package/index.node +0 -0
  5. package/package.json +8 -5
  6. package/releases/aarch64-apple-darwin/index.node +0 -0
  7. package/releases/{x86_64-pc-windows-gnu → 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 +77 -34
  12. package/sdk-core/.buildkite/docker/Dockerfile +1 -1
  13. package/sdk-core/Cargo.toml +6 -5
  14. package/sdk-core/fsm/Cargo.toml +1 -1
  15. package/sdk-core/fsm/rustfsm_procmacro/Cargo.toml +2 -2
  16. package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +8 -9
  17. package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +13 -7
  18. package/sdk-core/fsm/rustfsm_trait/Cargo.toml +2 -2
  19. package/sdk-core/fsm/rustfsm_trait/src/lib.rs +1 -1
  20. package/sdk-core/protos/local/workflow_activation.proto +6 -3
  21. package/sdk-core/sdk-core-protos/Cargo.toml +4 -4
  22. package/sdk-core/sdk-core-protos/src/lib.rs +38 -50
  23. package/sdk-core/src/core_tests/activity_tasks.rs +5 -5
  24. package/sdk-core/src/core_tests/child_workflows.rs +55 -29
  25. package/sdk-core/src/core_tests/determinism.rs +19 -9
  26. package/sdk-core/src/core_tests/mod.rs +3 -3
  27. package/sdk-core/src/core_tests/retry.rs +14 -8
  28. package/sdk-core/src/core_tests/workers.rs +1 -1
  29. package/sdk-core/src/core_tests/workflow_tasks.rs +347 -4
  30. package/sdk-core/src/errors.rs +27 -44
  31. package/sdk-core/src/lib.rs +13 -3
  32. package/sdk-core/src/machines/activity_state_machine.rs +44 -5
  33. package/sdk-core/src/machines/child_workflow_state_machine.rs +31 -11
  34. package/sdk-core/src/machines/complete_workflow_state_machine.rs +1 -1
  35. package/sdk-core/src/machines/continue_as_new_workflow_state_machine.rs +1 -1
  36. package/sdk-core/src/machines/mod.rs +18 -23
  37. package/sdk-core/src/machines/patch_state_machine.rs +8 -8
  38. package/sdk-core/src/machines/signal_external_state_machine.rs +22 -1
  39. package/sdk-core/src/machines/timer_state_machine.rs +21 -3
  40. package/sdk-core/src/machines/transition_coverage.rs +3 -3
  41. package/sdk-core/src/machines/workflow_machines.rs +11 -11
  42. package/sdk-core/src/pending_activations.rs +27 -22
  43. package/sdk-core/src/pollers/gateway.rs +15 -7
  44. package/sdk-core/src/pollers/poll_buffer.rs +6 -5
  45. package/sdk-core/src/pollers/retry.rs +153 -120
  46. package/sdk-core/src/prototype_rust_sdk/workflow_context.rs +61 -46
  47. package/sdk-core/src/prototype_rust_sdk/workflow_future.rs +13 -12
  48. package/sdk-core/src/prototype_rust_sdk.rs +17 -23
  49. package/sdk-core/src/telemetry/metrics.rs +2 -4
  50. package/sdk-core/src/telemetry/mod.rs +6 -7
  51. package/sdk-core/src/test_help/canned_histories.rs +17 -93
  52. package/sdk-core/src/test_help/history_builder.rs +61 -2
  53. package/sdk-core/src/test_help/history_info.rs +21 -2
  54. package/sdk-core/src/test_help/mod.rs +26 -34
  55. package/sdk-core/src/worker/activities/activity_heartbeat_manager.rs +246 -138
  56. package/sdk-core/src/worker/activities.rs +46 -45
  57. package/sdk-core/src/worker/config.rs +11 -0
  58. package/sdk-core/src/worker/dispatcher.rs +5 -5
  59. package/sdk-core/src/worker/mod.rs +86 -56
  60. package/sdk-core/src/workflow/driven_workflow.rs +3 -3
  61. package/sdk-core/src/workflow/history_update.rs +1 -1
  62. package/sdk-core/src/workflow/mod.rs +2 -1
  63. package/sdk-core/src/workflow/workflow_tasks/cache_manager.rs +13 -17
  64. package/sdk-core/src/workflow/workflow_tasks/concurrency_manager.rs +10 -18
  65. package/sdk-core/src/workflow/workflow_tasks/mod.rs +72 -57
  66. package/sdk-core/test_utils/Cargo.toml +1 -1
  67. package/sdk-core/test_utils/src/lib.rs +2 -2
  68. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +61 -1
  69. package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +2 -2
  70. package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +49 -0
  71. package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +2 -2
  72. package/sdk-core/tests/integ_tests/workflow_tests.rs +1 -0
  73. package/src/conversions.rs +17 -0
  74. package/src/errors.rs +0 -7
  75. package/src/lib.rs +0 -20
@@ -9,7 +9,10 @@ use crate::{
9
9
  use anyhow::bail;
10
10
  use std::time::SystemTime;
11
11
  use temporal_sdk_core_protos::{
12
- coresdk::common::{build_has_change_marker_details, NamespacedWorkflowExecution},
12
+ coresdk::common::{
13
+ build_has_change_marker_details, NamespacedWorkflowExecution, Payload as CorePayload,
14
+ },
15
+ coresdk::IntoPayloadsExt,
13
16
  temporal::api::{
14
17
  common::v1::{Payload, Payloads, WorkflowExecution, WorkflowType},
15
18
  enums::v1::{EventType, WorkflowTaskFailedCause},
@@ -136,6 +139,52 @@ impl TestHistoryBuilder {
136
139
  self.build_and_push_event(EventType::WorkflowExecutionCanceled, attrs.into());
137
140
  }
138
141
 
142
+ pub fn add_activity_task_scheduled(&mut self, activity_id: impl Into<String>) -> i64 {
143
+ self.add_get_event_id(
144
+ EventType::ActivityTaskScheduled,
145
+ Some(
146
+ history_event::Attributes::ActivityTaskScheduledEventAttributes(
147
+ ActivityTaskScheduledEventAttributes {
148
+ activity_id: activity_id.into(),
149
+ ..Default::default()
150
+ },
151
+ ),
152
+ ),
153
+ )
154
+ }
155
+ pub fn add_activity_task_started(&mut self, scheduled_event_id: i64) -> i64 {
156
+ self.add_get_event_id(
157
+ EventType::ActivityTaskStarted,
158
+ Some(
159
+ history_event::Attributes::ActivityTaskStartedEventAttributes(
160
+ ActivityTaskStartedEventAttributes {
161
+ scheduled_event_id,
162
+ ..Default::default()
163
+ },
164
+ ),
165
+ ),
166
+ )
167
+ }
168
+
169
+ pub fn add_activity_task_completed(
170
+ &mut self,
171
+ scheduled_event_id: i64,
172
+ started_event_id: i64,
173
+ payload: CorePayload,
174
+ ) {
175
+ self.add(
176
+ EventType::ActivityTaskCompleted,
177
+ history_event::Attributes::ActivityTaskCompletedEventAttributes(
178
+ ActivityTaskCompletedEventAttributes {
179
+ scheduled_event_id,
180
+ started_event_id,
181
+ result: vec![payload].into_payloads(),
182
+ ..Default::default()
183
+ },
184
+ ),
185
+ );
186
+ }
187
+
139
188
  pub fn add_activity_task_cancel_requested(&mut self, scheduled_event_id: i64) {
140
189
  let attrs = ActivityTaskCancelRequestedEventAttributes {
141
190
  scheduled_event_id,
@@ -293,6 +342,16 @@ impl TestHistoryBuilder {
293
342
  HistoryInfo::new_from_history(&self.events.clone().into(), None)
294
343
  }
295
344
 
345
+ pub(crate) fn get_one_wft(
346
+ &self,
347
+ from_wft_number: usize,
348
+ ) -> Result<HistoryInfo, HistoryInfoError> {
349
+ let mut histinfo =
350
+ HistoryInfo::new_from_history(&self.events.clone().into(), Some(from_wft_number))?;
351
+ histinfo.make_incremental();
352
+ Ok(histinfo)
353
+ }
354
+
296
355
  fn build_and_push_event(&mut self, event_type: EventType, attribs: Attributes) {
297
356
  self.current_event_id += 1;
298
357
  let evt = HistoryEvent {
@@ -309,7 +368,7 @@ impl TestHistoryBuilder {
309
368
  },
310
369
  )) = &evt.attributes
311
370
  {
312
- self.original_run_id = original_execution_run_id.to_owned();
371
+ self.original_run_id = original_execution_run_id.clone();
313
372
  };
314
373
  self.events.push(evt);
315
374
  }
@@ -100,19 +100,31 @@ impl HistoryInfo {
100
100
  unreachable!()
101
101
  }
102
102
 
103
+ /// Remove events from the beginning of this history such that it looks like what would've been
104
+ /// delivered on a sticky queue where the previously started task was the one before the last
105
+ /// task in this history.
106
+ pub(crate) fn make_incremental(&mut self) {
107
+ let last_complete_ix = self
108
+ .events
109
+ .iter()
110
+ .rposition(|he| he.event_type() == EventType::WorkflowTaskCompleted)
111
+ .expect("Must be a WFT completed event in history");
112
+ self.events.drain(0..=last_complete_ix);
113
+ }
114
+
103
115
  pub(crate) fn events(&self) -> &[HistoryEvent] {
104
116
  &self.events
105
117
  }
106
118
 
107
119
  /// Non-test code should *not* rely on just counting workflow tasks b/c of pagination
108
- pub(crate) fn wf_task_count(&self) -> usize {
120
+ pub(crate) const fn wf_task_count(&self) -> usize {
109
121
  self.wf_task_count
110
122
  }
111
123
  }
112
124
 
113
125
  impl From<HistoryInfo> for HistoryUpdate {
114
126
  fn from(v: HistoryInfo) -> Self {
115
- HistoryUpdate::new_from_events(v.events, v.previous_started_event_id)
127
+ Self::new_from_events(v.events, v.previous_started_event_id)
116
128
  }
117
129
  }
118
130
 
@@ -135,4 +147,11 @@ mod tests {
135
147
  let history_info = t.get_history_info(2).unwrap();
136
148
  assert_eq!(8, history_info.events.len());
137
149
  }
150
+
151
+ #[test]
152
+ fn incremental_works() {
153
+ let t = canned_histories::single_timer("timer1");
154
+ let hi = t.get_one_wft(2).unwrap();
155
+ dbg!(hi.events);
156
+ }
138
157
  }
@@ -47,22 +47,27 @@ use temporal_sdk_core_protos::{
47
47
 
48
48
  pub type Result<T, E = anyhow::Error> = std::result::Result<T, E>;
49
49
  pub const TEST_Q: &str = "q";
50
+ pub static NO_MORE_WORK_ERROR_MSG: &str = "No more work to do";
50
51
 
51
52
  /// When constructing responses for mocks, indicates how a given response should be built
52
53
  #[derive(derive_more::From, Debug, Clone, Copy, Eq, PartialEq, Hash)]
53
54
  pub enum ResponseType {
54
55
  ToTaskNum(usize),
56
+ /// Returns just the history after the WFT completed of the provided task number - 1, through to
57
+ /// the next WFT started. Simulating the incremental history for just the provided task number
58
+ #[from(ignore)]
59
+ OneTask(usize),
55
60
  AllHistory,
56
61
  }
57
62
 
58
63
  impl From<&usize> for ResponseType {
59
64
  fn from(u: &usize) -> Self {
60
- ResponseType::ToTaskNum(*u)
65
+ Self::ToTaskNum(*u)
61
66
  }
62
67
  }
63
68
  // :shrug:
64
- impl From<&ResponseType> for ResponseType {
65
- fn from(r: &ResponseType) -> Self {
69
+ impl From<&Self> for ResponseType {
70
+ fn from(r: &Self) -> Self {
66
71
  *r
67
72
  }
68
73
  }
@@ -164,7 +169,7 @@ pub struct MockWorker {
164
169
 
165
170
  impl Default for MockWorker {
166
171
  fn default() -> Self {
167
- MockWorker {
172
+ Self {
168
173
  wf_poller: Box::from(mock_poller()),
169
174
  act_poller: None,
170
175
  config: WorkerConfig::default_test_q(),
@@ -174,14 +179,14 @@ impl Default for MockWorker {
174
179
 
175
180
  impl MockWorker {
176
181
  pub fn new(q: &str, wf_poller: BoxedWFPoller) -> Self {
177
- MockWorker {
182
+ Self {
178
183
  wf_poller,
179
184
  act_poller: None,
180
185
  config: WorkerConfig::default(q),
181
186
  }
182
187
  }
183
188
  pub fn for_queue(q: &str) -> Self {
184
- MockWorker {
189
+ Self {
185
190
  wf_poller: Box::from(mock_poller()),
186
191
  act_poller: None,
187
192
  config: WorkerConfig::default(q),
@@ -193,15 +198,12 @@ impl<SG> MocksHolder<SG>
193
198
  where
194
199
  SG: ServerGatewayApis + Send + Sync + 'static,
195
200
  {
196
- pub fn from_mock_workers(
197
- sg: SG,
198
- mock_workers: impl IntoIterator<Item = MockWorker>,
199
- ) -> MocksHolder<SG> {
201
+ pub fn from_mock_workers(sg: SG, mock_workers: impl IntoIterator<Item = MockWorker>) -> Self {
200
202
  let mock_pollers = mock_workers
201
203
  .into_iter()
202
204
  .map(|w| (w.config.task_queue.clone(), w))
203
205
  .collect();
204
- MocksHolder {
206
+ Self {
205
207
  sg,
206
208
  mock_pollers,
207
209
  outstanding_task_map: None,
@@ -209,16 +211,12 @@ where
209
211
  }
210
212
 
211
213
  /// Uses the provided list of tasks to create a mock poller for the `TEST_Q`
212
- pub fn from_gateway_with_responses<WFT, ACT>(
213
- sg: SG,
214
- wf_tasks: WFT,
215
- act_tasks: ACT,
216
- ) -> MocksHolder<SG>
214
+ pub fn from_gateway_with_responses<WFT, ACT>(sg: SG, wf_tasks: WFT, act_tasks: ACT) -> Self
217
215
  where
218
216
  WFT: IntoIterator<Item = PollWorkflowTaskQueueResponse>,
219
217
  ACT: IntoIterator<Item = PollActivityTaskQueueResponse>,
220
- <WFT as IntoIterator>::IntoIter: std::marker::Send + 'static,
221
- <ACT as IntoIterator>::IntoIter: std::marker::Send + 'static,
218
+ <WFT as IntoIterator>::IntoIter: Send + 'static,
219
+ <ACT as IntoIterator>::IntoIter: Send + 'static,
222
220
  {
223
221
  let mut mock_pollers = HashMap::new();
224
222
  let mock_poller = mock_poller_from_resps(wf_tasks);
@@ -234,7 +232,7 @@ where
234
232
  .unwrap(),
235
233
  },
236
234
  );
237
- MocksHolder {
235
+ Self {
238
236
  sg,
239
237
  mock_pollers,
240
238
  outstanding_task_map: None,
@@ -246,7 +244,7 @@ pub fn mock_poller_from_resps<T, I>(tasks: I) -> BoxedPoller<T>
246
244
  where
247
245
  T: Send + Sync + 'static,
248
246
  I: IntoIterator<Item = T>,
249
- <I as IntoIterator>::IntoIter: std::marker::Send + 'static,
247
+ <I as IntoIterator>::IntoIter: Send + 'static,
250
248
  {
251
249
  let mut mock_poller = mock_poller();
252
250
  let mut tasks = tasks.into_iter();
@@ -254,9 +252,7 @@ where
254
252
  if let Some(t) = tasks.next() {
255
253
  Some(Ok(t))
256
254
  } else {
257
- Some(Err(tonic::Status::out_of_range(
258
- "Ran out of mock responses!",
259
- )))
255
+ Some(Err(tonic::Status::cancelled(NO_MORE_WORK_ERROR_MSG)))
260
256
  }
261
257
  });
262
258
  Box::new(mock_poller) as BoxedPoller<T>
@@ -412,7 +408,7 @@ pub fn build_mock_pollers(mut cfg: MockPollCfg) -> MocksHolder<MockServerGateway
412
408
  let cur_attempt = attempts_at_task_num.entry(to_task_num).or_insert(1);
413
409
  let mut r = hist_to_poll_resp(
414
410
  &hist.hist,
415
- hist.wf_id.to_owned(),
411
+ hist.wf_id.clone(),
416
412
  *to_task_num,
417
413
  hist.task_q.clone(),
418
414
  );
@@ -430,7 +426,7 @@ pub fn build_mock_pollers(mut cfg: MockPollCfg) -> MocksHolder<MockServerGateway
430
426
  }
431
427
 
432
428
  let mut mock_pollers = HashMap::new();
433
- for (task_q, mut queue_tasks) in task_queues_to_resps.into_iter() {
429
+ for (task_q, mut queue_tasks) in task_queues_to_resps {
434
430
  let mut mock_poller = mock_poller();
435
431
 
436
432
  // The poller will return history from any workflow runs that do not have currently
@@ -438,11 +434,7 @@ pub fn build_mock_pollers(mut cfg: MockPollCfg) -> MocksHolder<MockServerGateway
438
434
  let outstanding = outstanding_wf_task_tokens.clone();
439
435
  mock_poller
440
436
  .expect_poll()
441
- .times(
442
- correct_num_polls
443
- .map::<TimesRange, _>(Into::into)
444
- .unwrap_or_else(|| RangeFull.into()),
445
- )
437
+ .times(correct_num_polls.map_or_else(|| RangeFull.into(), Into::<TimesRange>::into))
446
438
  .returning(move || {
447
439
  for (_, tasks) in queue_tasks.iter_mut() {
448
440
  // Must extract run id from a workflow task associated with this workflow
@@ -458,7 +450,7 @@ pub fn build_mock_pollers(mut cfg: MockPollCfg) -> MocksHolder<MockServerGateway
458
450
  }
459
451
  }
460
452
  }
461
- Some(Err(tonic::Status::cancelled("No more work to do")))
453
+ Some(Err(tonic::Status::cancelled(NO_MORE_WORK_ERROR_MSG)))
462
454
  });
463
455
  let mw = MockWorker::new(&task_q, Box::from(mock_poller));
464
456
  mock_pollers.insert(task_q, mw);
@@ -477,8 +469,7 @@ pub fn build_mock_pollers(mut cfg: MockPollCfg) -> MocksHolder<MockServerGateway
477
469
  .withf(cfg.expect_fail_wft_matcher)
478
470
  .times(
479
471
  cfg.num_expected_fails
480
- .map::<TimesRange, _>(Into::into)
481
- .unwrap_or_else(|| RangeFull.into()),
472
+ .map_or_else(|| RangeFull.into(), Into::<TimesRange>::into),
482
473
  )
483
474
  .returning(move |tt, _, _| {
484
475
  outstanding.write().remove_by_right(&tt);
@@ -508,6 +499,7 @@ pub fn hist_to_poll_resp(
508
499
  };
509
500
  let hist_info = match response_type {
510
501
  ResponseType::ToTaskNum(tn) => t.get_history_info(tn).unwrap(),
502
+ ResponseType::OneTask(tn) => t.get_one_wft(tn).unwrap(),
511
503
  ResponseType::AllHistory => t.get_full_history_info().unwrap(),
512
504
  };
513
505
  let batch = hist_info.events().to_vec();
@@ -557,7 +549,7 @@ pub(crate) async fn poll_and_reply<'a>(
557
549
  eviction_mode: WorkflowCachingPolicy,
558
550
  expect_and_reply: &'a [AsserterWithReply<'a>],
559
551
  ) {
560
- poll_and_reply_clears_outstanding_evicts(core, None, eviction_mode, expect_and_reply).await
552
+ poll_and_reply_clears_outstanding_evicts(core, None, eviction_mode, expect_and_reply).await;
561
553
  }
562
554
 
563
555
  pub(crate) async fn poll_and_reply_clears_outstanding_evicts<'a>(