@temporalio/core-bridge 1.5.2 → 1.6.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 (153) hide show
  1. package/Cargo.lock +255 -48
  2. package/package.json +4 -4
  3. package/releases/aarch64-apple-darwin/index.node +0 -0
  4. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  5. package/releases/x86_64-apple-darwin/index.node +0 -0
  6. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  7. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  8. package/sdk-core/.buildkite/pipeline.yml +1 -3
  9. package/sdk-core/.cargo/config.toml +5 -2
  10. package/sdk-core/.github/workflows/heavy.yml +28 -0
  11. package/sdk-core/Cargo.toml +1 -1
  12. package/sdk-core/README.md +9 -5
  13. package/sdk-core/client/src/lib.rs +211 -36
  14. package/sdk-core/client/src/raw.rs +1 -1
  15. package/sdk-core/client/src/retry.rs +32 -20
  16. package/sdk-core/core/Cargo.toml +23 -9
  17. package/sdk-core/core/src/abstractions.rs +11 -0
  18. package/sdk-core/core/src/core_tests/activity_tasks.rs +6 -5
  19. package/sdk-core/core/src/core_tests/local_activities.rs +263 -22
  20. package/sdk-core/core/src/core_tests/queries.rs +2 -2
  21. package/sdk-core/core/src/core_tests/workflow_tasks.rs +249 -5
  22. package/sdk-core/core/src/ephemeral_server/mod.rs +5 -6
  23. package/sdk-core/core/src/lib.rs +2 -0
  24. package/sdk-core/core/src/protosext/mod.rs +1 -1
  25. package/sdk-core/core/src/telemetry/log_export.rs +1 -1
  26. package/sdk-core/core/src/telemetry/mod.rs +23 -8
  27. package/sdk-core/core/src/test_help/mod.rs +8 -1
  28. package/sdk-core/core/src/worker/activities/local_activities.rs +259 -125
  29. package/sdk-core/core/src/worker/activities.rs +3 -2
  30. package/sdk-core/core/src/worker/mod.rs +53 -26
  31. package/sdk-core/core/src/worker/workflow/bridge.rs +1 -3
  32. package/sdk-core/core/src/worker/workflow/driven_workflow.rs +3 -5
  33. package/sdk-core/core/src/worker/workflow/history_update.rs +835 -277
  34. package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +9 -17
  35. package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +3 -5
  36. package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +1 -2
  37. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +3 -5
  38. package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +1 -2
  39. package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +1 -2
  40. package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +1 -2
  41. package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +73 -51
  42. package/sdk-core/core/src/worker/workflow/machines/mod.rs +3 -3
  43. package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +4 -4
  44. package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +1 -2
  45. package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +3 -5
  46. package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +6 -7
  47. package/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +2 -2
  48. package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +4 -4
  49. package/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +6 -17
  50. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +89 -58
  51. package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +4 -7
  52. package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +21 -9
  53. package/sdk-core/core/src/worker/workflow/managed_run.rs +1021 -360
  54. package/sdk-core/core/src/worker/workflow/mod.rs +306 -346
  55. package/sdk-core/core/src/worker/workflow/run_cache.rs +29 -53
  56. package/sdk-core/core/src/worker/workflow/wft_extraction.rs +125 -0
  57. package/sdk-core/core/src/worker/workflow/wft_poller.rs +1 -4
  58. package/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +115 -0
  59. package/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +24 -0
  60. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +444 -714
  61. package/sdk-core/core-api/Cargo.toml +2 -0
  62. package/sdk-core/core-api/src/errors.rs +1 -34
  63. package/sdk-core/core-api/src/lib.rs +6 -2
  64. package/sdk-core/core-api/src/worker.rs +14 -1
  65. package/sdk-core/etc/deps.svg +115 -140
  66. package/sdk-core/etc/regen-depgraph.sh +5 -0
  67. package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +6 -6
  68. package/sdk-core/fsm/rustfsm_trait/src/lib.rs +7 -3
  69. package/sdk-core/histories/evict_while_la_running_no_interference-16_history.bin +0 -0
  70. package/sdk-core/protos/api_upstream/Makefile +5 -5
  71. package/sdk-core/protos/api_upstream/build/go.mod +7 -0
  72. package/sdk-core/protos/api_upstream/build/go.sum +5 -0
  73. package/sdk-core/protos/api_upstream/build/tools.go +29 -0
  74. package/sdk-core/protos/api_upstream/go.mod +6 -0
  75. package/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +9 -2
  76. package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +12 -19
  77. package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +2 -2
  78. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +3 -2
  79. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +3 -2
  80. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +3 -2
  81. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +3 -3
  82. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +20 -2
  83. package/sdk-core/protos/api_upstream/temporal/api/{update/v1/message.proto → enums/v1/interaction_type.proto} +11 -18
  84. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +2 -2
  85. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/query.proto +2 -2
  86. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +2 -2
  87. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +2 -2
  88. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +2 -2
  89. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +2 -13
  90. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +2 -2
  91. package/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +2 -2
  92. package/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +2 -2
  93. package/sdk-core/protos/api_upstream/temporal/api/filter/v1/message.proto +2 -2
  94. package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +13 -19
  95. package/sdk-core/protos/api_upstream/temporal/api/interaction/v1/message.proto +87 -0
  96. package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +2 -2
  97. package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +2 -2
  98. package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +2 -2
  99. package/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +2 -2
  100. package/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +2 -2
  101. package/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +2 -2
  102. package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +2 -2
  103. package/sdk-core/protos/api_upstream/temporal/api/version/v1/message.proto +2 -2
  104. package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +2 -2
  105. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +13 -8
  106. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +2 -2
  107. package/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +2 -0
  108. package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +2 -2
  109. package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +2 -2
  110. package/sdk-core/sdk/Cargo.toml +4 -3
  111. package/sdk-core/sdk/src/lib.rs +87 -21
  112. package/sdk-core/sdk/src/workflow_future.rs +7 -12
  113. package/sdk-core/sdk-core-protos/Cargo.toml +5 -2
  114. package/sdk-core/sdk-core-protos/build.rs +36 -2
  115. package/sdk-core/sdk-core-protos/src/history_builder.rs +26 -19
  116. package/sdk-core/sdk-core-protos/src/history_info.rs +4 -0
  117. package/sdk-core/sdk-core-protos/src/lib.rs +78 -34
  118. package/sdk-core/sdk-core-protos/src/task_token.rs +12 -2
  119. package/sdk-core/test-utils/Cargo.toml +3 -1
  120. package/sdk-core/test-utils/src/histfetch.rs +1 -1
  121. package/sdk-core/test-utils/src/lib.rs +50 -18
  122. package/sdk-core/test-utils/src/wf_input_saver.rs +50 -0
  123. package/sdk-core/test-utils/src/workflows.rs +29 -0
  124. package/sdk-core/tests/fuzzy_workflow.rs +130 -0
  125. package/sdk-core/tests/{load_tests.rs → heavy_tests.rs} +114 -7
  126. package/sdk-core/tests/integ_tests/heartbeat_tests.rs +5 -2
  127. package/sdk-core/tests/integ_tests/metrics_tests.rs +1 -1
  128. package/sdk-core/tests/integ_tests/polling_tests.rs +1 -39
  129. package/sdk-core/tests/integ_tests/queries_tests.rs +2 -127
  130. package/sdk-core/tests/integ_tests/visibility_tests.rs +52 -5
  131. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +74 -1
  132. package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +5 -13
  133. package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +1 -1
  134. package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +2 -10
  135. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +69 -197
  136. package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +4 -28
  137. package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +12 -7
  138. package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +14 -14
  139. package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +3 -19
  140. package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +3 -19
  141. package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +1 -1
  142. package/sdk-core/tests/integ_tests/workflow_tests.rs +5 -6
  143. package/sdk-core/tests/main.rs +2 -12
  144. package/sdk-core/tests/runner.rs +71 -34
  145. package/sdk-core/tests/wf_input_replay.rs +32 -0
  146. package/sdk-core/bridge-ffi/Cargo.toml +0 -24
  147. package/sdk-core/bridge-ffi/LICENSE.txt +0 -23
  148. package/sdk-core/bridge-ffi/build.rs +0 -25
  149. package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +0 -224
  150. package/sdk-core/bridge-ffi/src/lib.rs +0 -746
  151. package/sdk-core/bridge-ffi/src/wrappers.rs +0 -221
  152. package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +0 -210
  153. package/sdk-core/sdk/src/conversions.rs +0 -8
@@ -3,6 +3,8 @@ pub(crate) mod client;
3
3
  mod workflow;
4
4
 
5
5
  pub use temporal_sdk_core_api::worker::{WorkerConfig, WorkerConfigBuilder};
6
+ #[cfg(feature = "save_wf_inputs")]
7
+ pub use workflow::replay_wf_state_inputs;
6
8
 
7
9
  pub(crate) use activities::{
8
10
  ExecutingLAId, LocalActRequest, LocalActivityExecutionResult, LocalActivityResolution,
@@ -26,13 +28,13 @@ use crate::{
26
28
  worker::{
27
29
  activities::{DispatchOrTimeoutLA, LACompleteAction, LocalActivityManager},
28
30
  client::WorkerClient,
29
- workflow::{LocalResolution, WorkflowBasics, Workflows},
31
+ workflow::{LAReqSink, LocalResolution, WorkflowBasics, Workflows},
30
32
  },
31
33
  ActivityHeartbeat, CompleteActivityError, PollActivityError, PollWfError, WorkerTrait,
32
34
  };
33
35
  use activities::{LocalInFlightActInfo, WorkerActivityTasks};
34
36
  use futures::Stream;
35
- use std::{convert::TryInto, sync::Arc};
37
+ use std::{convert::TryInto, future, sync::Arc};
36
38
  use temporal_sdk_core_protos::{
37
39
  coresdk::{
38
40
  activity_result::activity_execution_result,
@@ -48,6 +50,7 @@ use temporal_sdk_core_protos::{
48
50
  },
49
51
  TaskToken,
50
52
  };
53
+ use tokio::sync::mpsc::unbounded_channel;
51
54
  use tokio_util::sync::CancellationToken;
52
55
 
53
56
  /// A worker polls on a certain task queue
@@ -233,7 +236,7 @@ impl Worker {
233
236
  }
234
237
 
235
238
  pub(crate) fn new_with_pollers(
236
- config: WorkerConfig,
239
+ mut config: WorkerConfig,
237
240
  sticky_queue_name: Option<String>,
238
241
  client: Arc<dyn WorkerClient>,
239
242
  wft_stream: impl Stream<Item = Result<ValidPollWFTQResponse, tonic::Status>> + Send + 'static,
@@ -241,13 +244,14 @@ impl Worker {
241
244
  metrics: MetricsContext,
242
245
  shutdown_token: CancellationToken,
243
246
  ) -> Self {
247
+ let (hb_tx, hb_rx) = unbounded_channel();
244
248
  let local_act_mgr = Arc::new(LocalActivityManager::new(
245
249
  config.max_outstanding_local_activities,
246
250
  config.namespace.clone(),
251
+ hb_tx,
247
252
  metrics.with_new_attrs([local_activity_worker_type()]),
248
253
  ));
249
254
  let lam_clone = local_act_mgr.clone();
250
- let local_act_req_sink = move |requests| lam_clone.enqueue(requests);
251
255
  let at_task_mgr = act_poller.map(|ap| {
252
256
  WorkerActivityTasks::new(
253
257
  config.max_outstanding_activities,
@@ -259,18 +263,14 @@ impl Worker {
259
263
  config.default_heartbeat_throttle_interval,
260
264
  )
261
265
  });
266
+ if at_task_mgr.is_none() {
267
+ info!("Activity polling is disabled for this worker");
268
+ }
269
+ let la_sink = LAReqSink::new(lam_clone, config.wf_state_inputs.clone());
262
270
  Self {
263
271
  wf_client: client.clone(),
264
272
  workflows: Workflows::new(
265
- WorkflowBasics {
266
- max_cached_workflows: config.max_cached_workflows,
267
- max_outstanding_wfts: config.max_outstanding_workflow_tasks,
268
- shutdown_token: shutdown_token.child_token(),
269
- metrics,
270
- namespace: config.namespace.clone(),
271
- task_queue: config.task_queue.clone(),
272
- ignore_evicts_on_shutdown: config.ignore_evicts_on_shutdown,
273
- },
273
+ build_wf_basics(&mut config, metrics, shutdown_token.child_token()),
274
274
  sticky_queue_name.map(|sq| StickyExecutionAttributes {
275
275
  worker_task_queue: Some(TaskQueue {
276
276
  name: sq,
@@ -285,7 +285,8 @@ impl Worker {
285
285
  }),
286
286
  client,
287
287
  wft_stream,
288
- local_act_req_sink,
288
+ la_sink,
289
+ hb_rx,
289
290
  at_task_mgr
290
291
  .as_ref()
291
292
  .map(|mgr| mgr.get_handle_for_workflows()),
@@ -304,7 +305,9 @@ impl Worker {
304
305
  self.initiate_shutdown();
305
306
  // Next we need to wait for all local activities to finish so no more workflow task
306
307
  // heartbeats will be generated
307
- self.local_act_mgr.shutdown_and_wait_all_finished().await;
308
+ self.local_act_mgr
309
+ .wait_all_outstanding_tasks_finished()
310
+ .await;
308
311
  // Wait for workflows to finish
309
312
  self.workflows
310
313
  .shutdown()
@@ -346,13 +349,9 @@ impl Worker {
346
349
  .unwrap_or_default()
347
350
  }
348
351
 
349
- #[cfg(test)]
352
+ #[allow(unused)]
350
353
  pub(crate) async fn available_wft_permits(&self) -> usize {
351
- self.workflows
352
- .get_state_info()
353
- .await
354
- .expect("You can only check for available permits before shutdown")
355
- .available_wft_permits
354
+ self.workflows.available_wft_permits()
356
355
  }
357
356
 
358
357
  /// Get new activity tasks (may be local or nonlocal). Local activities are returned first
@@ -365,9 +364,10 @@ impl Worker {
365
364
  if let Some(ref act_mgr) = self.at_task_mgr {
366
365
  act_mgr.poll().await
367
366
  } else {
368
- info!("Activity polling is disabled for this worker");
369
- self.shutdown_token.cancelled().await;
370
- Err(PollActivityError::ShutDown)
367
+ // We expect the local activity branch below to produce shutdown when appropriate if
368
+ // there are no activity pollers.
369
+ future::pending::<()>().await;
370
+ unreachable!()
371
371
  }
372
372
  };
373
373
 
@@ -448,7 +448,15 @@ impl Worker {
448
448
 
449
449
  #[instrument(skip(self), fields(run_id, workflow_id, task_queue=%self.config.task_queue))]
450
450
  pub(crate) async fn next_workflow_activation(&self) -> Result<WorkflowActivation, PollWfError> {
451
- self.workflows.next_workflow_activation().await
451
+ let r = self.workflows.next_workflow_activation().await;
452
+ // In the event workflows are shutdown, begin shutdown of everything else, since that's
453
+ // about to happen anyway. Tell the local activity manager that, so that it can know to
454
+ // cancel any remaining outstanding LAs and shutdown.
455
+ if matches!(r, Err(PollWfError::ShutDown)) {
456
+ self.initiate_shutdown();
457
+ self.local_act_mgr.workflows_have_shutdown();
458
+ }
459
+ r
452
460
  }
453
461
 
454
462
  #[instrument(skip(self, completion),
@@ -498,7 +506,7 @@ impl Worker {
498
506
  runtime: info.dispatch_time.elapsed(),
499
507
  attempt: info.attempt,
500
508
  backoff,
501
- original_schedule_time: Some(info.la_info.schedule_time),
509
+ original_schedule_time: info.la_info.schedule_cmd.original_schedule_time,
502
510
  }),
503
511
  )
504
512
  }
@@ -508,6 +516,25 @@ impl Worker {
508
516
  }
509
517
  }
510
518
 
519
+ fn build_wf_basics(
520
+ config: &mut WorkerConfig,
521
+ metrics: MetricsContext,
522
+ shutdown_token: CancellationToken,
523
+ ) -> WorkflowBasics {
524
+ WorkflowBasics {
525
+ max_cached_workflows: config.max_cached_workflows,
526
+ max_outstanding_wfts: config.max_outstanding_workflow_tasks,
527
+ shutdown_token,
528
+ metrics,
529
+ namespace: config.namespace.clone(),
530
+ task_queue: config.task_queue.clone(),
531
+ ignore_evicts_on_shutdown: config.ignore_evicts_on_shutdown,
532
+ fetching_concurrency: config.fetching_concurrency,
533
+ #[cfg(feature = "save_wf_inputs")]
534
+ wf_state_inputs: config.wf_state_inputs.take(),
535
+ }
536
+ }
537
+
511
538
  #[cfg(test)]
512
539
  mod tests {
513
540
  use super::*;
@@ -25,11 +25,9 @@ impl WorkflowBridge {
25
25
  }
26
26
  }
27
27
 
28
- #[async_trait::async_trait]
29
28
  impl WorkflowFetcher for WorkflowBridge {
30
- async fn fetch_workflow_iteration_output(&mut self) -> Vec<WFCommand> {
29
+ fn fetch_workflow_iteration_output(&mut self) -> Vec<WFCommand> {
31
30
  let in_cmds = self.incoming_commands.try_recv();
32
-
33
31
  let in_cmds = in_cmds.unwrap_or_else(|_| vec![WFCommand::NoCommandsFromLang]);
34
32
  debug!(in_cmds = %in_cmds.display(), "wf bridge iteration fetch");
35
33
  in_cmds
@@ -78,16 +78,14 @@ impl DrivenWorkflow {
78
78
  }
79
79
  }
80
80
 
81
- #[async_trait::async_trait]
82
81
  impl WorkflowFetcher for DrivenWorkflow {
83
- async fn fetch_workflow_iteration_output(&mut self) -> Vec<WFCommand> {
84
- self.fetcher.fetch_workflow_iteration_output().await
82
+ fn fetch_workflow_iteration_output(&mut self) -> Vec<WFCommand> {
83
+ self.fetcher.fetch_workflow_iteration_output()
85
84
  }
86
85
  }
87
86
 
88
87
  /// Implementors of this trait represent a way to fetch output from executing/iterating some
89
88
  /// workflow code (or a mocked workflow).
90
- #[async_trait::async_trait]
91
89
  pub trait WorkflowFetcher: Send {
92
90
  /// Obtain any output from the workflow's recent execution(s). Because the lang sdk is
93
91
  /// responsible for calling workflow code as a result of receiving tasks from
@@ -97,5 +95,5 @@ pub trait WorkflowFetcher: Send {
97
95
  ///
98
96
  /// In the case of the real [WorkflowBridge] implementation, commands are simply pulled from
99
97
  /// a buffer that the language side sinks into when it calls [crate::Core::complete_task]
100
- async fn fetch_workflow_iteration_output(&mut self) -> Vec<WFCommand>;
98
+ fn fetch_workflow_iteration_output(&mut self) -> Vec<WFCommand>;
101
99
  }