@temporalio/core-bridge 0.23.0 → 1.0.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 (135) hide show
  1. package/Cargo.lock +118 -15
  2. package/Cargo.toml +2 -1
  3. package/LICENSE.md +1 -1
  4. package/README.md +1 -1
  5. package/index.d.ts +47 -18
  6. package/package.json +7 -7
  7. package/releases/aarch64-apple-darwin/index.node +0 -0
  8. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  9. package/releases/x86_64-apple-darwin/index.node +0 -0
  10. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  11. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  12. package/sdk-core/.buildkite/docker/docker-compose.yaml +4 -2
  13. package/sdk-core/ARCHITECTURE.md +9 -7
  14. package/sdk-core/README.md +5 -1
  15. package/sdk-core/arch_docs/diagrams/workflow_internals.svg +1 -0
  16. package/sdk-core/bridge-ffi/src/wrappers.rs +0 -3
  17. package/sdk-core/client/src/lib.rs +26 -8
  18. package/sdk-core/client/src/raw.rs +166 -54
  19. package/sdk-core/client/src/retry.rs +9 -4
  20. package/sdk-core/client/src/workflow_handle/mod.rs +4 -2
  21. package/sdk-core/core/Cargo.toml +2 -0
  22. package/sdk-core/core/src/abstractions.rs +137 -16
  23. package/sdk-core/core/src/core_tests/activity_tasks.rs +258 -63
  24. package/sdk-core/core/src/core_tests/child_workflows.rs +1 -2
  25. package/sdk-core/core/src/core_tests/determinism.rs +2 -2
  26. package/sdk-core/core/src/core_tests/local_activities.rs +8 -7
  27. package/sdk-core/core/src/core_tests/queries.rs +146 -60
  28. package/sdk-core/core/src/core_tests/replay_flag.rs +1 -1
  29. package/sdk-core/core/src/core_tests/workers.rs +39 -23
  30. package/sdk-core/core/src/core_tests/workflow_cancels.rs +1 -1
  31. package/sdk-core/core/src/core_tests/workflow_tasks.rs +387 -280
  32. package/sdk-core/core/src/lib.rs +6 -4
  33. package/sdk-core/core/src/pollers/poll_buffer.rs +16 -10
  34. package/sdk-core/core/src/protosext/mod.rs +6 -6
  35. package/sdk-core/core/src/retry_logic.rs +1 -1
  36. package/sdk-core/core/src/telemetry/metrics.rs +21 -7
  37. package/sdk-core/core/src/telemetry/mod.rs +18 -4
  38. package/sdk-core/core/src/test_help/mod.rs +341 -109
  39. package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +18 -9
  40. package/sdk-core/core/src/worker/activities/local_activities.rs +19 -16
  41. package/sdk-core/core/src/worker/activities.rs +156 -29
  42. package/sdk-core/core/src/worker/client.rs +1 -0
  43. package/sdk-core/core/src/worker/mod.rs +132 -659
  44. package/sdk-core/core/src/{workflow → worker/workflow}/bridge.rs +1 -1
  45. package/sdk-core/core/src/{workflow → worker/workflow}/driven_workflow.rs +1 -1
  46. package/sdk-core/core/src/{workflow → worker/workflow}/history_update.rs +16 -2
  47. package/sdk-core/core/src/{workflow → worker/workflow}/machines/activity_state_machine.rs +39 -4
  48. package/sdk-core/core/src/{workflow → worker/workflow}/machines/cancel_external_state_machine.rs +5 -2
  49. package/sdk-core/core/src/{workflow → worker/workflow}/machines/cancel_workflow_state_machine.rs +1 -1
  50. package/sdk-core/core/src/{workflow → worker/workflow}/machines/child_workflow_state_machine.rs +2 -4
  51. package/sdk-core/core/src/{workflow → worker/workflow}/machines/complete_workflow_state_machine.rs +0 -0
  52. package/sdk-core/core/src/{workflow → worker/workflow}/machines/continue_as_new_workflow_state_machine.rs +1 -1
  53. package/sdk-core/core/src/{workflow → worker/workflow}/machines/fail_workflow_state_machine.rs +0 -0
  54. package/sdk-core/core/src/{workflow → worker/workflow}/machines/local_activity_state_machine.rs +2 -5
  55. package/sdk-core/core/src/{workflow → worker/workflow}/machines/mod.rs +1 -1
  56. package/sdk-core/core/src/{workflow → worker/workflow}/machines/mutable_side_effect_state_machine.rs +0 -0
  57. package/sdk-core/core/src/{workflow → worker/workflow}/machines/patch_state_machine.rs +1 -1
  58. package/sdk-core/core/src/{workflow → worker/workflow}/machines/side_effect_state_machine.rs +0 -0
  59. package/sdk-core/core/src/{workflow → worker/workflow}/machines/signal_external_state_machine.rs +4 -2
  60. package/sdk-core/core/src/{workflow → worker/workflow}/machines/timer_state_machine.rs +1 -2
  61. package/sdk-core/core/src/{workflow → worker/workflow}/machines/transition_coverage.rs +1 -1
  62. package/sdk-core/core/src/{workflow → worker/workflow}/machines/upsert_search_attributes_state_machine.rs +5 -7
  63. package/sdk-core/core/src/{workflow → worker/workflow}/machines/workflow_machines/local_acts.rs +2 -2
  64. package/sdk-core/core/src/{workflow → worker/workflow}/machines/workflow_machines.rs +40 -16
  65. package/sdk-core/core/src/{workflow → worker/workflow}/machines/workflow_task_state_machine.rs +0 -0
  66. package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +198 -0
  67. package/sdk-core/core/src/worker/workflow/managed_run.rs +627 -0
  68. package/sdk-core/core/src/worker/workflow/mod.rs +1115 -0
  69. package/sdk-core/core/src/worker/workflow/run_cache.rs +143 -0
  70. package/sdk-core/core/src/worker/workflow/wft_poller.rs +88 -0
  71. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +936 -0
  72. package/sdk-core/core-api/src/errors.rs +3 -10
  73. package/sdk-core/core-api/src/lib.rs +2 -1
  74. package/sdk-core/core-api/src/worker.rs +26 -2
  75. package/sdk-core/etc/dynamic-config.yaml +2 -0
  76. package/sdk-core/integ-with-otel.sh +1 -1
  77. package/sdk-core/protos/api_upstream/Makefile +4 -4
  78. package/sdk-core/protos/api_upstream/api-linter.yaml +2 -0
  79. package/sdk-core/protos/api_upstream/buf.yaml +8 -9
  80. package/sdk-core/protos/api_upstream/temporal/api/cluster/v1/message.proto +83 -0
  81. package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +7 -1
  82. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/cluster.proto +40 -0
  83. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +3 -0
  84. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +3 -1
  85. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +60 -0
  86. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +3 -0
  87. package/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +32 -4
  88. package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +69 -19
  89. package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +13 -0
  90. package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +163 -0
  91. package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +97 -0
  92. package/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +300 -0
  93. package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +25 -0
  94. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +180 -3
  95. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +53 -3
  96. package/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +2 -2
  97. package/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +6 -5
  98. package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +0 -1
  99. package/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +2 -1
  100. package/sdk-core/protos/local/temporal/sdk/core/common/common.proto +0 -64
  101. package/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +2 -1
  102. package/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +11 -8
  103. package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +30 -25
  104. package/sdk-core/sdk/src/activity_context.rs +12 -5
  105. package/sdk-core/sdk/src/app_data.rs +37 -0
  106. package/sdk-core/sdk/src/lib.rs +76 -43
  107. package/sdk-core/sdk/src/workflow_context/options.rs +8 -6
  108. package/sdk-core/sdk/src/workflow_context.rs +14 -19
  109. package/sdk-core/sdk/src/workflow_future.rs +11 -6
  110. package/sdk-core/sdk-core-protos/src/history_builder.rs +19 -5
  111. package/sdk-core/sdk-core-protos/src/history_info.rs +11 -6
  112. package/sdk-core/sdk-core-protos/src/lib.rs +74 -176
  113. package/sdk-core/test-utils/src/lib.rs +85 -72
  114. package/sdk-core/tests/integ_tests/heartbeat_tests.rs +11 -9
  115. package/sdk-core/tests/integ_tests/polling_tests.rs +12 -0
  116. package/sdk-core/tests/integ_tests/queries_tests.rs +39 -22
  117. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +49 -4
  118. package/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +61 -0
  119. package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -1
  120. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +74 -13
  121. package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +19 -0
  122. package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -1
  123. package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +6 -3
  124. package/sdk-core/tests/integ_tests/workflow_tests.rs +10 -23
  125. package/sdk-core/tests/load_tests.rs +8 -3
  126. package/sdk-core/tests/main.rs +2 -1
  127. package/src/conversions.rs +47 -39
  128. package/src/errors.rs +10 -21
  129. package/src/lib.rs +342 -325
  130. package/sdk-core/core/src/pending_activations.rs +0 -173
  131. package/sdk-core/core/src/worker/wft_delivery.rs +0 -81
  132. package/sdk-core/core/src/workflow/mod.rs +0 -478
  133. package/sdk-core/core/src/workflow/workflow_tasks/cache_manager.rs +0 -194
  134. package/sdk-core/core/src/workflow/workflow_tasks/concurrency_manager.rs +0 -418
  135. package/sdk-core/core/src/workflow/workflow_tasks/mod.rs +0 -989
@@ -0,0 +1,143 @@
1
+ use crate::{
2
+ telemetry::metrics::workflow_type,
3
+ worker::workflow::{
4
+ managed_run::WorkflowManager, HistoryUpdate, LocalActivityRequestSink, ManagedRunHandle,
5
+ NewIncomingWFT, RunUpdateResponse,
6
+ },
7
+ MetricsContext,
8
+ };
9
+ use lru::LruCache;
10
+ use std::time::Instant;
11
+ use tokio::sync::mpsc::UnboundedSender;
12
+
13
+ pub(super) struct RunCache {
14
+ max: usize,
15
+ namespace: String,
16
+ run_update_tx: UnboundedSender<RunUpdateResponse>,
17
+ /// Run id -> Data
18
+ runs: LruCache<String, ManagedRunHandle>,
19
+ local_activity_request_sink: LocalActivityRequestSink,
20
+
21
+ metrics: MetricsContext,
22
+ }
23
+
24
+ impl RunCache {
25
+ pub fn new(
26
+ max_cache_size: usize,
27
+ namespace: String,
28
+ run_update_tx: UnboundedSender<RunUpdateResponse>,
29
+ local_activity_request_sink: LocalActivityRequestSink,
30
+ metrics: MetricsContext,
31
+ ) -> Self {
32
+ // The cache needs room for at least one run, otherwise we couldn't do anything. In
33
+ // "0" size mode, the run is evicted once the workflow task is complete.
34
+ let lru_size = if max_cache_size > 0 {
35
+ max_cache_size
36
+ } else {
37
+ 1
38
+ };
39
+ Self {
40
+ max: max_cache_size,
41
+ namespace,
42
+ run_update_tx,
43
+ runs: LruCache::new(lru_size),
44
+ local_activity_request_sink,
45
+ metrics,
46
+ }
47
+ }
48
+
49
+ pub fn instantiate_or_update(
50
+ &mut self,
51
+ run_id: &str,
52
+ workflow_id: &str,
53
+ wf_type: &str,
54
+ history_update: HistoryUpdate,
55
+ start_time: Instant,
56
+ ) -> &mut ManagedRunHandle {
57
+ let cur_num_cached_runs = self.runs.len();
58
+
59
+ if self.runs.contains(run_id) {
60
+ // For some weird reason, maybe a NLL bug, there are double-mutable-borrow errors if I
61
+ // use get_mut above instead of in here (even though we always return from this branch).
62
+ // So, forced to do this.
63
+ let run_handle = self.runs.get_mut(run_id).unwrap();
64
+
65
+ run_handle.metrics.sticky_cache_hit();
66
+ run_handle.incoming_wft(NewIncomingWFT {
67
+ history_update: Some(history_update),
68
+ start_time,
69
+ });
70
+ self.metrics.cache_size(cur_num_cached_runs as u64);
71
+ return run_handle;
72
+ }
73
+
74
+ // Create a new workflow machines instance for this workflow, initialize it, and
75
+ // track it.
76
+ let metrics = self
77
+ .metrics
78
+ .with_new_attrs([workflow_type(wf_type.to_string())]);
79
+ let wfm = WorkflowManager::new(
80
+ history_update,
81
+ self.namespace.clone(),
82
+ workflow_id.to_string(),
83
+ wf_type.to_string(),
84
+ run_id.to_string(),
85
+ metrics.clone(),
86
+ );
87
+ let mut mrh = ManagedRunHandle::new(
88
+ wfm,
89
+ self.run_update_tx.clone(),
90
+ self.local_activity_request_sink.clone(),
91
+ metrics,
92
+ );
93
+ mrh.incoming_wft(NewIncomingWFT {
94
+ history_update: None,
95
+ start_time,
96
+ });
97
+ if self.runs.push(run_id.to_string(), mrh).is_some() {
98
+ panic!("Overflowed run cache! Cache owner is expected to avoid this!");
99
+ }
100
+ self.metrics.cache_size(cur_num_cached_runs as u64 + 1);
101
+ // This is safe, we just inserted.
102
+ self.runs.get_mut(run_id).unwrap()
103
+ }
104
+ pub fn remove(&mut self, k: &str) -> Option<ManagedRunHandle> {
105
+ let r = self.runs.pop(k);
106
+ self.metrics.cache_size(self.len() as u64);
107
+ r
108
+ }
109
+
110
+ pub fn get_mut(&mut self, k: &str) -> Option<&mut ManagedRunHandle> {
111
+ self.runs.get_mut(k)
112
+ }
113
+ pub fn get(&mut self, k: &str) -> Option<&ManagedRunHandle> {
114
+ self.runs.get(k)
115
+ }
116
+
117
+ /// Returns the current least-recently-used run. Returns `None` when cache empty.
118
+ pub fn current_lru_run(&self) -> Option<&str> {
119
+ self.runs.peek_lru().map(|(run_id, _)| run_id.as_str())
120
+ }
121
+ /// Returns an iterator yielding cached runs in LRU order
122
+ pub fn runs_lru_order(&self) -> impl Iterator<Item = (&str, &ManagedRunHandle)> {
123
+ self.runs.iter().rev().map(|(k, v)| (k.as_str(), v))
124
+ }
125
+ pub fn peek(&self, k: &str) -> Option<&ManagedRunHandle> {
126
+ self.runs.peek(k)
127
+ }
128
+ pub fn has_run(&self, k: &str) -> bool {
129
+ self.runs.contains(k)
130
+ }
131
+ pub fn handles(&self) -> impl Iterator<Item = &ManagedRunHandle> {
132
+ self.runs.iter().map(|(_, v)| v)
133
+ }
134
+ pub fn is_full(&self) -> bool {
135
+ self.runs.cap() == self.runs.len()
136
+ }
137
+ pub fn len(&self) -> usize {
138
+ self.runs.len()
139
+ }
140
+ pub fn cache_capacity(&self) -> usize {
141
+ self.max
142
+ }
143
+ }
@@ -0,0 +1,88 @@
1
+ use crate::{pollers::BoxedWFPoller, protosext::ValidPollWFTQResponse, MetricsContext};
2
+ use futures::{stream, Stream};
3
+ use temporal_sdk_core_protos::temporal::api::workflowservice::v1::PollWorkflowTaskQueueResponse;
4
+
5
+ pub(crate) fn new_wft_poller(
6
+ poller: BoxedWFPoller,
7
+ metrics: MetricsContext,
8
+ ) -> impl Stream<Item = Result<ValidPollWFTQResponse, tonic::Status>> {
9
+ stream::unfold((poller, metrics), |(poller, metrics)| async move {
10
+ loop {
11
+ return match poller.poll().await {
12
+ Some(Ok(wft)) => {
13
+ if wft == PollWorkflowTaskQueueResponse::default() {
14
+ // We get the default proto in the event that the long poll times out.
15
+ debug!("Poll wft timeout");
16
+ metrics.wf_tq_poll_empty();
17
+ continue;
18
+ }
19
+ if let Some(dur) = wft.sched_to_start() {
20
+ metrics.wf_task_sched_to_start_latency(dur);
21
+ }
22
+ let work = match validate_wft(wft) {
23
+ Ok(w) => w,
24
+ Err(e) => {
25
+ error!(error=?e, "Server returned an unparseable workflow task");
26
+ continue;
27
+ }
28
+ };
29
+ metrics.wf_tq_poll_ok();
30
+ Some((Ok(work), (poller, metrics)))
31
+ }
32
+ Some(Err(e)) => {
33
+ warn!(error=?e, "Error while polling for workflow tasks");
34
+ Some((Err(e), (poller, metrics)))
35
+ }
36
+ // If poller returns None, it's dead, thus we also return None to terminate this
37
+ // stream.
38
+ None => None,
39
+ };
40
+ }
41
+ })
42
+ }
43
+
44
+ pub(crate) fn validate_wft(
45
+ wft: PollWorkflowTaskQueueResponse,
46
+ ) -> Result<ValidPollWFTQResponse, tonic::Status> {
47
+ wft.try_into().map_err(|resp| {
48
+ tonic::Status::new(
49
+ tonic::Code::DataLoss,
50
+ format!(
51
+ "Server returned a poll WFT response we couldn't interpret: {:?}",
52
+ resp
53
+ ),
54
+ )
55
+ })
56
+ }
57
+
58
+ #[cfg(test)]
59
+ mod tests {
60
+ use super::*;
61
+ use crate::test_help::mock_poller;
62
+ use futures::{pin_mut, StreamExt};
63
+
64
+ #[tokio::test]
65
+ async fn poll_timeouts_do_not_produce_responses() {
66
+ let mut mock_poller = mock_poller();
67
+ mock_poller
68
+ .expect_poll()
69
+ .times(1)
70
+ .returning(|| Some(Ok(PollWorkflowTaskQueueResponse::default())));
71
+ mock_poller.expect_poll().times(1).returning(|| None);
72
+ let stream = new_wft_poller(Box::new(mock_poller), Default::default());
73
+ pin_mut!(stream);
74
+ assert_matches!(stream.next().await, None);
75
+ }
76
+
77
+ #[tokio::test]
78
+ async fn poll_errors_do_produce_responses() {
79
+ let mut mock_poller = mock_poller();
80
+ mock_poller
81
+ .expect_poll()
82
+ .times(1)
83
+ .returning(|| Some(Err(tonic::Status::internal("ahhh"))));
84
+ let stream = new_wft_poller(Box::new(mock_poller), Default::default());
85
+ pin_mut!(stream);
86
+ assert_matches!(stream.next().await, Some(Err(_)));
87
+ }
88
+ }