@temporalio/core-bridge 0.16.4 → 0.18.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 (170) hide show
  1. package/Cargo.lock +339 -226
  2. package/Cargo.toml +7 -3
  3. package/common.js +50 -0
  4. package/index.d.ts +7 -0
  5. package/index.js +12 -0
  6. package/package.json +7 -4
  7. package/releases/aarch64-apple-darwin/index.node +0 -0
  8. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  9. package/{index.node → releases/index.node} +0 -0
  10. package/releases/x86_64-apple-darwin/index.node +0 -0
  11. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  12. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  13. package/scripts/build.js +10 -50
  14. package/sdk-core/.buildkite/docker/Dockerfile +1 -1
  15. package/sdk-core/.buildkite/docker/docker-compose.yaml +2 -2
  16. package/sdk-core/.buildkite/pipeline.yml +2 -0
  17. package/sdk-core/Cargo.toml +1 -88
  18. package/sdk-core/README.md +30 -6
  19. package/sdk-core/bridge-ffi/Cargo.toml +24 -0
  20. package/sdk-core/bridge-ffi/LICENSE.txt +23 -0
  21. package/sdk-core/bridge-ffi/build.rs +25 -0
  22. package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +216 -0
  23. package/sdk-core/bridge-ffi/src/lib.rs +829 -0
  24. package/sdk-core/bridge-ffi/src/wrappers.rs +193 -0
  25. package/sdk-core/client/Cargo.toml +32 -0
  26. package/sdk-core/{src/pollers/gateway.rs → client/src/lib.rs} +101 -195
  27. package/sdk-core/client/src/metrics.rs +89 -0
  28. package/sdk-core/client/src/mocks.rs +167 -0
  29. package/sdk-core/{src/pollers → client/src}/retry.rs +172 -14
  30. package/sdk-core/core/Cargo.toml +96 -0
  31. package/sdk-core/{src → core/src}/core_tests/activity_tasks.rs +193 -37
  32. package/sdk-core/{src → core/src}/core_tests/child_workflows.rs +14 -14
  33. package/sdk-core/{src → core/src}/core_tests/determinism.rs +8 -8
  34. package/sdk-core/core/src/core_tests/local_activities.rs +328 -0
  35. package/sdk-core/{src → core/src}/core_tests/mod.rs +6 -9
  36. package/sdk-core/{src → core/src}/core_tests/queries.rs +54 -54
  37. package/sdk-core/{src → core/src}/core_tests/replay_flag.rs +8 -12
  38. package/sdk-core/{src → core/src}/core_tests/workers.rs +120 -33
  39. package/sdk-core/{src → core/src}/core_tests/workflow_cancels.rs +16 -26
  40. package/sdk-core/{src → core/src}/core_tests/workflow_tasks.rs +280 -292
  41. package/sdk-core/core/src/lib.rs +374 -0
  42. package/sdk-core/{src → core/src}/log_export.rs +3 -27
  43. package/sdk-core/core/src/pending_activations.rs +162 -0
  44. package/sdk-core/{src → core/src}/pollers/mod.rs +4 -22
  45. package/sdk-core/{src → core/src}/pollers/poll_buffer.rs +1 -1
  46. package/sdk-core/core/src/protosext/mod.rs +396 -0
  47. package/sdk-core/core/src/replay/mod.rs +210 -0
  48. package/sdk-core/core/src/retry_logic.rs +144 -0
  49. package/sdk-core/{src → core/src}/telemetry/metrics.rs +3 -58
  50. package/sdk-core/{src → core/src}/telemetry/mod.rs +8 -8
  51. package/sdk-core/{src → core/src}/telemetry/prometheus_server.rs +0 -0
  52. package/sdk-core/{src → core/src}/test_help/mod.rs +35 -83
  53. package/sdk-core/{src → core/src}/worker/activities/activity_heartbeat_manager.rs +95 -42
  54. package/sdk-core/core/src/worker/activities/local_activities.rs +973 -0
  55. package/sdk-core/{src → core/src}/worker/activities.rs +52 -33
  56. package/sdk-core/{src → core/src}/worker/dispatcher.rs +8 -6
  57. package/sdk-core/{src → core/src}/worker/mod.rs +347 -221
  58. package/sdk-core/core/src/worker/wft_delivery.rs +81 -0
  59. package/sdk-core/{src → core/src}/workflow/bridge.rs +5 -2
  60. package/sdk-core/{src → core/src}/workflow/driven_workflow.rs +17 -7
  61. package/sdk-core/{src → core/src}/workflow/history_update.rs +33 -7
  62. package/sdk-core/{src → core/src/workflow}/machines/activity_state_machine.rs +26 -26
  63. package/sdk-core/{src → core/src/workflow}/machines/cancel_external_state_machine.rs +8 -11
  64. package/sdk-core/{src → core/src/workflow}/machines/cancel_workflow_state_machine.rs +19 -21
  65. package/sdk-core/{src → core/src/workflow}/machines/child_workflow_state_machine.rs +20 -31
  66. package/sdk-core/{src → core/src/workflow}/machines/complete_workflow_state_machine.rs +3 -5
  67. package/sdk-core/{src → core/src/workflow}/machines/continue_as_new_workflow_state_machine.rs +18 -18
  68. package/sdk-core/{src → core/src/workflow}/machines/fail_workflow_state_machine.rs +5 -6
  69. package/sdk-core/core/src/workflow/machines/local_activity_state_machine.rs +1451 -0
  70. package/sdk-core/{src → core/src/workflow}/machines/mod.rs +54 -107
  71. package/sdk-core/{src → core/src/workflow}/machines/mutable_side_effect_state_machine.rs +0 -0
  72. package/sdk-core/{src → core/src/workflow}/machines/patch_state_machine.rs +29 -30
  73. package/sdk-core/{src → core/src/workflow}/machines/side_effect_state_machine.rs +0 -0
  74. package/sdk-core/{src → core/src/workflow}/machines/signal_external_state_machine.rs +17 -19
  75. package/sdk-core/{src → core/src/workflow}/machines/timer_state_machine.rs +20 -21
  76. package/sdk-core/{src → core/src/workflow}/machines/transition_coverage.rs +5 -2
  77. package/sdk-core/{src → core/src/workflow}/machines/upsert_search_attributes_state_machine.rs +0 -0
  78. package/sdk-core/core/src/workflow/machines/workflow_machines/local_acts.rs +96 -0
  79. package/sdk-core/{src → core/src/workflow}/machines/workflow_machines.rs +357 -171
  80. package/sdk-core/{src → core/src/workflow}/machines/workflow_task_state_machine.rs +1 -1
  81. package/sdk-core/{src → core/src}/workflow/mod.rs +200 -39
  82. package/sdk-core/{src → core/src}/workflow/workflow_tasks/cache_manager.rs +0 -0
  83. package/sdk-core/{src → core/src}/workflow/workflow_tasks/concurrency_manager.rs +38 -5
  84. package/sdk-core/{src → core/src}/workflow/workflow_tasks/mod.rs +317 -103
  85. package/sdk-core/{test_utils → core-api}/Cargo.toml +10 -7
  86. package/sdk-core/{src → core-api/src}/errors.rs +42 -92
  87. package/sdk-core/core-api/src/lib.rs +158 -0
  88. package/sdk-core/{src/worker/config.rs → core-api/src/worker.rs} +18 -23
  89. package/sdk-core/etc/deps.svg +156 -0
  90. package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +5 -5
  91. package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +3 -5
  92. package/sdk-core/fsm/rustfsm_trait/src/lib.rs +7 -1
  93. package/sdk-core/histories/fail_wf_task.bin +0 -0
  94. package/sdk-core/histories/timer_workflow_history.bin +0 -0
  95. package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +44 -13
  96. package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +19 -1
  97. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +1 -1
  98. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +9 -0
  99. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +1 -0
  100. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +1 -0
  101. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +13 -0
  102. package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +14 -7
  103. package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +176 -18
  104. package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -0
  105. package/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +11 -0
  106. package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +3 -0
  107. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +156 -7
  108. package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +135 -104
  109. package/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +78 -0
  110. package/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +78 -0
  111. package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +205 -0
  112. package/sdk-core/protos/local/temporal/sdk/core/bridge/service.proto +61 -0
  113. package/sdk-core/protos/local/{child_workflow.proto → temporal/sdk/core/child_workflow/child_workflow.proto} +1 -1
  114. package/sdk-core/protos/local/{common.proto → temporal/sdk/core/common/common.proto} +5 -3
  115. package/sdk-core/protos/local/{core_interface.proto → temporal/sdk/core/core_interface.proto} +10 -10
  116. package/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +30 -0
  117. package/sdk-core/protos/local/{workflow_activation.proto → temporal/sdk/core/workflow_activation/workflow_activation.proto} +35 -11
  118. package/sdk-core/protos/local/{workflow_commands.proto → temporal/sdk/core/workflow_commands/workflow_commands.proto} +55 -4
  119. package/sdk-core/protos/local/{workflow_completion.proto → temporal/sdk/core/workflow_completion/workflow_completion.proto} +3 -3
  120. package/sdk-core/sdk/Cargo.toml +32 -0
  121. package/sdk-core/{src/prototype_rust_sdk → sdk/src}/conversions.rs +0 -0
  122. package/sdk-core/sdk/src/lib.rs +699 -0
  123. package/sdk-core/sdk/src/payload_converter.rs +11 -0
  124. package/sdk-core/sdk/src/workflow_context/options.rs +180 -0
  125. package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_context.rs +201 -124
  126. package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_future.rs +63 -30
  127. package/sdk-core/sdk-core-protos/Cargo.toml +10 -0
  128. package/sdk-core/sdk-core-protos/build.rs +28 -6
  129. package/sdk-core/sdk-core-protos/src/constants.rs +7 -0
  130. package/sdk-core/{src/test_help → sdk-core-protos/src}/history_builder.rs +134 -49
  131. package/sdk-core/sdk-core-protos/src/history_info.rs +216 -0
  132. package/sdk-core/sdk-core-protos/src/lib.rs +601 -168
  133. package/sdk-core/sdk-core-protos/src/task_token.rs +38 -0
  134. package/sdk-core/sdk-core-protos/src/utilities.rs +14 -0
  135. package/sdk-core/test-utils/Cargo.toml +32 -0
  136. package/sdk-core/{src/test_help → test-utils/src}/canned_histories.rs +59 -78
  137. package/sdk-core/test-utils/src/histfetch.rs +28 -0
  138. package/sdk-core/{test_utils → test-utils}/src/lib.rs +131 -68
  139. package/sdk-core/tests/integ_tests/client_tests.rs +1 -1
  140. package/sdk-core/tests/integ_tests/heartbeat_tests.rs +11 -7
  141. package/sdk-core/tests/integ_tests/polling_tests.rs +12 -11
  142. package/sdk-core/tests/integ_tests/queries_tests.rs +82 -78
  143. package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +91 -71
  144. package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +3 -4
  145. package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +2 -4
  146. package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +4 -6
  147. package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +4 -6
  148. package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -4
  149. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +496 -0
  150. package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +5 -8
  151. package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +125 -0
  152. package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +7 -13
  153. package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +33 -5
  154. package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +12 -16
  155. package/sdk-core/tests/integ_tests/workflow_tests.rs +85 -82
  156. package/sdk-core/tests/load_tests.rs +6 -6
  157. package/sdk-core/tests/main.rs +2 -2
  158. package/src/conversions.rs +24 -21
  159. package/src/errors.rs +8 -0
  160. package/src/lib.rs +323 -211
  161. package/sdk-core/protos/local/activity_result.proto +0 -46
  162. package/sdk-core/protos/local/activity_task.proto +0 -66
  163. package/sdk-core/src/core_tests/retry.rs +0 -147
  164. package/sdk-core/src/lib.rs +0 -403
  165. package/sdk-core/src/machines/local_activity_state_machine.rs +0 -117
  166. package/sdk-core/src/pending_activations.rs +0 -249
  167. package/sdk-core/src/protosext/mod.rs +0 -160
  168. package/sdk-core/src/prototype_rust_sdk.rs +0 -412
  169. package/sdk-core/src/task_token.rs +0 -20
  170. package/sdk-core/src/test_help/history_info.rs +0 -157
@@ -0,0 +1,144 @@
1
+ use std::time::Duration;
2
+ use temporal_sdk_core_protos::{coresdk::common::RetryPolicy, utilities::TryIntoOrNone};
3
+
4
+ pub(crate) trait RetryPolicyExt {
5
+ /// Ask this retry policy if a retry should be performed. Caller provides the current attempt
6
+ /// number - the first attempt should start at 1.
7
+ ///
8
+ /// Returns `None` if it should not, otherwise a duration indicating how long to wait before
9
+ /// performing the retry.
10
+ fn should_retry(&self, attempt_number: usize, err_type_str: &str) -> Option<Duration>;
11
+ }
12
+
13
+ impl RetryPolicyExt for RetryPolicy {
14
+ fn should_retry(&self, attempt_number: usize, err_type_str: &str) -> Option<Duration> {
15
+ let realmax = self.maximum_attempts.max(0);
16
+ if realmax > 0 && attempt_number >= realmax as usize {
17
+ return None;
18
+ }
19
+
20
+ for pat in &self.non_retryable_error_types {
21
+ if err_type_str.to_lowercase() == pat.to_lowercase() {
22
+ return None;
23
+ }
24
+ }
25
+
26
+ let converted_interval = self.initial_interval.clone().try_into_or_none();
27
+ if attempt_number == 1 {
28
+ return converted_interval;
29
+ }
30
+ let coeff = if self.backoff_coefficient != 0. {
31
+ self.backoff_coefficient
32
+ } else {
33
+ 2.0
34
+ };
35
+
36
+ if let Some(interval) = converted_interval {
37
+ let max_iv = self
38
+ .maximum_interval
39
+ .clone()
40
+ .try_into_or_none()
41
+ .unwrap_or_else(|| interval.saturating_mul(100));
42
+ let mul_factor = coeff.powi(attempt_number as i32 - 1);
43
+ let tried_mul = try_from_secs_f64(mul_factor * interval.as_secs_f64());
44
+ Some(tried_mul.unwrap_or(max_iv).min(max_iv))
45
+ } else {
46
+ // No retries if initial interval is not specified
47
+ None
48
+ }
49
+ }
50
+ }
51
+
52
+ const NANOS_PER_SEC: u32 = 1_000_000_000;
53
+ /// modified from rust stdlib since this feature is currently nightly only
54
+ fn try_from_secs_f64(secs: f64) -> Option<Duration> {
55
+ const MAX_NANOS_F64: f64 = ((u64::MAX as u128 + 1) * (NANOS_PER_SEC as u128)) as f64;
56
+ let nanos = secs * (NANOS_PER_SEC as f64);
57
+ if !nanos.is_finite() || nanos >= MAX_NANOS_F64 || nanos < 0.0 {
58
+ None
59
+ } else {
60
+ Some(Duration::from_secs_f64(secs))
61
+ }
62
+ }
63
+
64
+ #[cfg(test)]
65
+ mod tests {
66
+ use super::*;
67
+
68
+ #[test]
69
+ fn calcs_backoffs_properly() {
70
+ let rp = RetryPolicy {
71
+ initial_interval: Some(Duration::from_secs(1).into()),
72
+ backoff_coefficient: 2.0,
73
+ maximum_interval: Some(Duration::from_secs(10).into()),
74
+ maximum_attempts: 10,
75
+ non_retryable_error_types: vec![],
76
+ };
77
+ let res = rp.should_retry(1, "").unwrap();
78
+ assert_eq!(res.as_millis(), 1_000);
79
+ let res = rp.should_retry(2, "").unwrap();
80
+ assert_eq!(res.as_millis(), 2_000);
81
+ let res = rp.should_retry(3, "").unwrap();
82
+ assert_eq!(res.as_millis(), 4_000);
83
+ let res = rp.should_retry(4, "").unwrap();
84
+ assert_eq!(res.as_millis(), 8_000);
85
+ let res = rp.should_retry(5, "").unwrap();
86
+ assert_eq!(res.as_millis(), 10_000);
87
+ let res = rp.should_retry(6, "").unwrap();
88
+ assert_eq!(res.as_millis(), 10_000);
89
+ // Max attempts - no retry
90
+ assert!(rp.should_retry(10, "").is_none());
91
+ }
92
+
93
+ #[test]
94
+ fn no_interval_no_backoff() {
95
+ let rp = RetryPolicy {
96
+ initial_interval: None,
97
+ backoff_coefficient: 2.0,
98
+ maximum_interval: None,
99
+ maximum_attempts: 10,
100
+ non_retryable_error_types: vec![],
101
+ };
102
+ assert!(rp.should_retry(1, "").is_none());
103
+ }
104
+
105
+ #[test]
106
+ fn max_attempts_zero_retry_forever() {
107
+ let rp = RetryPolicy {
108
+ initial_interval: Some(Duration::from_secs(1).into()),
109
+ backoff_coefficient: 1.2,
110
+ maximum_interval: None,
111
+ maximum_attempts: 0,
112
+ non_retryable_error_types: vec![],
113
+ };
114
+ for i in 0..50 {
115
+ assert!(rp.should_retry(i, "").is_some());
116
+ }
117
+ }
118
+
119
+ #[test]
120
+ fn no_overflows() {
121
+ let rp = RetryPolicy {
122
+ initial_interval: Some(Duration::from_secs(1).into()),
123
+ backoff_coefficient: 10.,
124
+ maximum_interval: None,
125
+ maximum_attempts: 0,
126
+ non_retryable_error_types: vec![],
127
+ };
128
+ for i in 0..50 {
129
+ assert!(rp.should_retry(i, "").is_some());
130
+ }
131
+ }
132
+
133
+ #[test]
134
+ fn no_retry_err_str_match() {
135
+ let rp = RetryPolicy {
136
+ initial_interval: Some(Duration::from_secs(1).into()),
137
+ backoff_coefficient: 2.0,
138
+ maximum_interval: Some(Duration::from_secs(10).into()),
139
+ maximum_attempts: 10,
140
+ non_retryable_error_types: vec!["no retry".to_string()],
141
+ };
142
+ assert!(rp.should_retry(1, "no retry").is_none());
143
+ }
144
+ }
@@ -20,15 +20,11 @@ pub(crate) struct MetricsContext {
20
20
  // of lifetime issues: https://github.com/open-telemetry/opentelemetry-rust/issues/629
21
21
  // Use once fixed.
22
22
  kvs: Arc<Vec<KeyValue>>,
23
- poll_is_long: bool,
24
23
  }
25
24
 
26
25
  impl MetricsContext {
27
26
  fn new(kvs: Vec<KeyValue>) -> Self {
28
- Self {
29
- kvs: Arc::new(kvs),
30
- poll_is_long: false,
31
- }
27
+ Self { kvs: Arc::new(kvs) }
32
28
  }
33
29
 
34
30
  pub(crate) fn top_level(namespace: String) -> Self {
@@ -39,14 +35,7 @@ impl MetricsContext {
39
35
  pub(crate) fn with_new_attrs(&self, new_kvs: impl IntoIterator<Item = KeyValue>) -> Self {
40
36
  let mut kvs = self.kvs.clone();
41
37
  Arc::make_mut(&mut kvs).extend(new_kvs);
42
- Self {
43
- kvs,
44
- poll_is_long: false,
45
- }
46
- }
47
-
48
- pub(crate) fn set_is_long_poll(&mut self) {
49
- self.poll_is_long = true;
38
+ Self { kvs }
50
39
  }
51
40
 
52
41
  /// A workflow task queue poll succeeded
@@ -149,37 +138,10 @@ impl MetricsContext {
149
138
  pub(crate) fn cache_size(&self, size: u64) {
150
139
  STICKY_CACHE_SIZE.record(size, &self.kvs);
151
140
  }
152
-
153
- /// A request to the temporal service was made
154
- pub(crate) fn svc_request(&self) {
155
- if self.poll_is_long {
156
- LONG_SVC_REQUEST.add(1, &self.kvs);
157
- } else {
158
- SVC_REQUEST.add(1, &self.kvs);
159
- }
160
- }
161
-
162
- /// A request to the temporal service failed
163
- pub(crate) fn svc_request_failed(&self) {
164
- if self.poll_is_long {
165
- LONG_SVC_REQUEST_FAILED.add(1, &self.kvs);
166
- } else {
167
- SVC_REQUEST_FAILED.add(1, &self.kvs);
168
- }
169
- }
170
-
171
- /// Record service request latency
172
- pub(crate) fn record_svc_req_latency(&self, dur: Duration) {
173
- if self.poll_is_long {
174
- LONG_SVC_REQUEST_LATENCY.record(dur.as_millis() as u64, &self.kvs);
175
- } else {
176
- SVC_REQUEST_LATENCY.record(dur.as_millis() as u64, &self.kvs);
177
- }
178
- }
179
141
  }
180
142
 
181
143
  lazy_static::lazy_static! {
182
- static ref METRIC_METER: Meter = {
144
+ pub(crate) static ref METRIC_METER: Meter = {
183
145
  #[cfg(not(test))]
184
146
  if crate::telemetry::GLOBAL_TELEM_DAT.get().is_none() {
185
147
  panic!("Tried to use a metric but telemetry has not been initialized")
@@ -212,7 +174,6 @@ const KEY_WF_TYPE: &str = "workflow_type";
212
174
  const KEY_TASK_QUEUE: &str = "task_queue";
213
175
  const KEY_ACT_TYPE: &str = "activity_type";
214
176
  const KEY_POLLER_TYPE: &str = "poller_type";
215
- const KEY_SVC_METHOD: &str = "operation";
216
177
 
217
178
  pub(crate) fn workflow_poller() -> KeyValue {
218
179
  KeyValue::new(KEY_POLLER_TYPE, "workflow_task")
@@ -232,9 +193,6 @@ pub(crate) fn activity_type(ty: String) -> KeyValue {
232
193
  pub(crate) fn workflow_type(ty: String) -> KeyValue {
233
194
  KeyValue::new(KEY_WF_TYPE, ty)
234
195
  }
235
- pub(crate) fn svc_operation(op: String) -> KeyValue {
236
- KeyValue::new(KEY_SVC_METHOD, op)
237
- }
238
196
 
239
197
  tm!(ctr, WF_COMPLETED_COUNTER, "workflow_completed");
240
198
  tm!(ctr, WF_CANCELED_COUNTER, "workflow_canceled");
@@ -296,19 +254,6 @@ tm!(ctr, STICKY_CACHE_MISS, "sticky_cache_miss");
296
254
  const STICKY_CACHE_SIZE_NAME: &str = "sticky_cache_size";
297
255
  tm!(vr_u64, STICKY_CACHE_SIZE, STICKY_CACHE_SIZE_NAME);
298
256
 
299
- tm!(ctr, SVC_REQUEST, "request");
300
- tm!(ctr, SVC_REQUEST_FAILED, "request_failure");
301
- const SVC_REQUEST_LATENCY_NAME: &str = "request_latency";
302
- tm!(vr_u64, SVC_REQUEST_LATENCY, SVC_REQUEST_LATENCY_NAME);
303
- tm!(ctr, LONG_SVC_REQUEST, "long_request");
304
- tm!(ctr, LONG_SVC_REQUEST_FAILED, "long_request_failure");
305
- const LONG_SVC_REQUEST_LATENCY_NAME: &str = "long_request_latency";
306
- tm!(
307
- vr_u64,
308
- LONG_SVC_REQUEST_LATENCY,
309
- LONG_SVC_REQUEST_LATENCY_NAME
310
- );
311
-
312
257
  /// Artisanal, handcrafted latency buckets for workflow e2e latency which should expose a useful
313
258
  /// set of buckets for < 1 day runtime workflows. Beyond that, this metric probably isn't very
314
259
  /// helpful
@@ -66,7 +66,7 @@ impl Default for TelemetryOptions {
66
66
 
67
67
  /// Things that need to not be dropped while telemetry is ongoing
68
68
  #[derive(Default)]
69
- struct GlobalTelemDat {
69
+ pub(crate) struct GlobalTelemDat {
70
70
  metric_push_controller: Option<PushController>,
71
71
  core_export_logger: Option<CoreExportLogger>,
72
72
  runtime: Option<tokio::runtime::Runtime>,
@@ -92,14 +92,16 @@ impl GlobalTelemDat {
92
92
  /// called more than once, subsequent calls do nothing.
93
93
  ///
94
94
  /// See [TelemetryOptions] docs for more on configuration.
95
- pub(crate) fn telemetry_init(opts: &TelemetryOptions) -> Result<(), anyhow::Error> {
95
+ pub(crate) fn telemetry_init(
96
+ opts: &TelemetryOptions,
97
+ ) -> Result<&'static GlobalTelemDat, anyhow::Error> {
96
98
  // TODO: Per-layer filtering has been implemented but does not yet support
97
99
  // env-filter. When it does, allow filtering logs/telemetry separately.
98
100
 
99
101
  // Ensure we don't pointlessly spawn threads that won't do anything or call telem dat's init 2x
100
102
  let guard = TELETM_MUTEX.lock();
101
- if GLOBAL_TELEM_DAT.get().is_some() {
102
- return Ok(());
103
+ if let Some(gtd) = GLOBAL_TELEM_DAT.get() {
104
+ return Ok(gtd);
103
105
  }
104
106
 
105
107
  // This is a bit odd, but functional. It's desirable to create a separate tokio runtime for
@@ -202,12 +204,10 @@ pub(crate) fn telemetry_init(opts: &TelemetryOptions) -> Result<(), anyhow::Erro
202
204
  })?;
203
205
 
204
206
  res.init();
205
- Result::<_, anyhow::Error>::Ok(())
207
+ Result::<_, anyhow::Error>::Ok(res)
206
208
  })
207
209
  .join()
208
- .expect("Telemetry initialization panicked")?;
209
-
210
- Ok(())
210
+ .expect("Telemetry initialization panicked")
211
211
  }
212
212
 
213
213
  /// Returned buffered logs for export to lang from the global logging instance
@@ -1,43 +1,35 @@
1
- pub mod canned_histories;
2
-
3
- mod history_builder;
4
- mod history_info;
5
-
6
- pub(crate) use history_builder::{TestHistoryBuilder, DEFAULT_WORKFLOW_TYPE};
1
+ pub(crate) use temporal_sdk_core_test_utils::canned_histories;
7
2
 
8
3
  use crate::{
9
- pollers::{
10
- BoxedActPoller, BoxedPoller, BoxedWFPoller, MockManualPoller, MockPoller,
11
- MockServerGatewayApis,
12
- },
13
- task_token::TaskToken,
4
+ pollers::{BoxedActPoller, BoxedPoller, BoxedWFPoller, MockManualPoller, MockPoller},
5
+ replay::TestHistoryBuilder,
14
6
  workflow::WorkflowCachingPolicy,
15
- Core, CoreInitOptionsBuilder, CoreSDK, ServerGatewayApis, ServerGatewayOptions, Url,
16
- WorkerConfig, WorkerConfigBuilder,
7
+ Core, CoreInitOptionsBuilder, CoreSDK, ServerGatewayApis, TaskToken, WorkerConfig,
8
+ WorkerConfigBuilder,
17
9
  };
18
10
  use bimap::BiMap;
19
11
  use futures::FutureExt;
20
12
  use mockall::TimesRange;
21
13
  use parking_lot::RwLock;
22
- use rand::{thread_rng, Rng};
23
14
  use std::{
24
15
  collections::{BTreeMap, HashMap, HashSet, VecDeque},
25
16
  ops::RangeFull,
26
- str::FromStr,
27
17
  sync::Arc,
28
18
  };
19
+ use temporal_client::{
20
+ mocks::{fake_sg_opts, mock_gateway},
21
+ MockServerGatewayApis,
22
+ };
29
23
  use temporal_sdk_core_protos::{
30
24
  coresdk::{
31
- workflow_activation::WfActivation,
25
+ workflow_activation::WorkflowActivation,
32
26
  workflow_commands::workflow_command,
33
- workflow_completion::{self, wf_activation_completion, WfActivationCompletion},
27
+ workflow_completion::{self, workflow_activation_completion, WorkflowActivationCompletion},
34
28
  },
35
29
  temporal::api::{
36
- common::v1::{WorkflowExecution, WorkflowType},
37
- enums::v1::{TaskQueueKind, WorkflowTaskFailedCause},
30
+ common::v1::WorkflowExecution,
31
+ enums::v1::WorkflowTaskFailedCause,
38
32
  failure::v1::Failure,
39
- history::v1::History,
40
- taskqueue::v1::TaskQueue,
41
33
  workflowservice::v1::{
42
34
  PollActivityTaskQueueResponse, PollWorkflowTaskQueueResponse,
43
35
  RespondWorkflowTaskCompletedResponse,
@@ -45,7 +37,6 @@ use temporal_sdk_core_protos::{
45
37
  },
46
38
  };
47
39
 
48
- pub type Result<T, E = anyhow::Error> = std::result::Result<T, E>;
49
40
  pub const TEST_Q: &str = "q";
50
41
  pub static NO_MORE_WORK_ERROR_MSG: &str = "No more work to do";
51
42
 
@@ -146,6 +137,7 @@ pub struct FakeWfResponses {
146
137
  pub struct MocksHolder<SG> {
147
138
  sg: SG,
148
139
  mock_pollers: HashMap<String, MockWorker>,
140
+ // bidirectional mapping of run id / task token
149
141
  pub outstanding_task_map: Option<Arc<RwLock<BiMap<String, TaskToken>>>>,
150
142
  }
151
143
 
@@ -169,11 +161,7 @@ pub struct MockWorker {
169
161
 
170
162
  impl Default for MockWorker {
171
163
  fn default() -> Self {
172
- Self {
173
- wf_poller: Box::from(mock_poller()),
174
- act_poller: None,
175
- config: WorkerConfig::default_test_q(),
176
- }
164
+ Self::for_queue(TEST_Q)
177
165
  }
178
166
  }
179
167
 
@@ -182,15 +170,15 @@ impl MockWorker {
182
170
  Self {
183
171
  wf_poller,
184
172
  act_poller: None,
185
- config: WorkerConfig::default(q),
173
+ config: WorkerConfigBuilder::default()
174
+ .task_queue(q)
175
+ .build()
176
+ .unwrap(),
186
177
  }
187
178
  }
179
+
188
180
  pub fn for_queue(q: &str) -> Self {
189
- Self {
190
- wf_poller: Box::from(mock_poller()),
191
- act_poller: None,
192
- config: WorkerConfig::default(q),
193
- }
181
+ Self::new(q, Box::from(mock_poller()))
194
182
  }
195
183
  }
196
184
 
@@ -335,7 +323,7 @@ impl MockPollCfg {
335
323
  hists,
336
324
  enforce_correct_number_of_polls,
337
325
  num_expected_fails,
338
- mock_gateway: MockServerGatewayApis::new(),
326
+ mock_gateway: mock_gateway(),
339
327
  expect_fail_wft_matcher: Box::new(|_, _, _| true),
340
328
  }
341
329
  }
@@ -381,16 +369,6 @@ pub fn build_mock_pollers(mut cfg: MockPollCfg) -> MocksHolder<MockServerGateway
381
369
  }
382
370
  }
383
371
 
384
- // TODO: Fix -- or not? Sticky invalidation could make this pointless anyway
385
- // Verify response batches only ever return longer histories (IE: Are sorted ascending)
386
- // assert!(
387
- // hist.response_batches
388
- // .as_slice()
389
- // .windows(2)
390
- // .all(|w| w[0] <= w[1]),
391
- // "response batches must have increasing wft numbers"
392
- // );
393
-
394
372
  if cfg.enforce_correct_number_of_polls {
395
373
  *correct_num_polls.get_or_insert(0) += hist.response_batches.len();
396
374
  }
@@ -502,40 +480,15 @@ pub fn hist_to_poll_resp(
502
480
  ResponseType::OneTask(tn) => t.get_one_wft(tn).unwrap(),
503
481
  ResponseType::AllHistory => t.get_full_history_info().unwrap(),
504
482
  };
505
- let batch = hist_info.events().to_vec();
506
- let task_token: [u8; 16] = thread_rng().gen();
507
- PollWorkflowTaskQueueResponse {
508
- history: Some(History { events: batch }),
509
- workflow_execution: Some(wf),
510
- task_token: task_token.to_vec(),
511
- workflow_type: Some(WorkflowType {
512
- name: DEFAULT_WORKFLOW_TYPE.to_owned(),
513
- }),
514
- workflow_execution_task_queue: Some(TaskQueue {
515
- name: task_queue,
516
- kind: TaskQueueKind::Normal as i32,
517
- }),
518
- previous_started_event_id: hist_info.previous_started_event_id,
519
- started_event_id: hist_info.workflow_task_started_event_id,
520
- ..Default::default()
521
- }
522
- }
523
-
524
- pub fn fake_sg_opts() -> ServerGatewayOptions {
525
- ServerGatewayOptions {
526
- target_url: Url::from_str("https://fake").unwrap(),
527
- namespace: "".to_string(),
528
- client_name: "".to_string(),
529
- client_version: "".to_string(),
530
- static_headers: Default::default(),
531
- identity: "".to_string(),
532
- worker_binary_id: "".to_string(),
533
- tls_cfg: None,
534
- retry_config: Default::default(),
535
- }
483
+ let mut resp = hist_info.as_poll_wft_response(task_queue);
484
+ resp.workflow_execution = Some(wf);
485
+ resp
536
486
  }
537
487
 
538
- type AsserterWithReply<'a> = (&'a dyn Fn(&WfActivation), wf_activation_completion::Status);
488
+ type AsserterWithReply<'a> = (
489
+ &'a dyn Fn(&WorkflowActivation),
490
+ workflow_activation_completion::Status,
491
+ );
539
492
 
540
493
  /// This function accepts a list of asserts and replies to workflow activations to run against the
541
494
  /// provided instance of fake core.
@@ -601,10 +554,10 @@ pub(crate) async fn poll_and_reply_clears_outstanding_evicts<'a>(
601
554
 
602
555
  let reply = if res.jobs.is_empty() {
603
556
  // Just an eviction
604
- WfActivationCompletion::empty(TEST_Q, res.run_id.clone())
557
+ WorkflowActivationCompletion::empty(TEST_Q, res.run_id.clone())
605
558
  } else {
606
559
  // Eviction plus some work, we still want to issue the reply
607
- WfActivationCompletion {
560
+ WorkflowActivationCompletion {
608
561
  task_queue: TEST_Q.to_string(),
609
562
  run_id: res.run_id.clone(),
610
563
  status: Some(reply.clone()),
@@ -638,12 +591,11 @@ pub(crate) async fn poll_and_reply_clears_outstanding_evicts<'a>(
638
591
  }
639
592
 
640
593
  assert_eq!(expected_fail_count, executed_failures.len());
641
- // TODO: Really need a worker abstraction for testing
642
- // assert_eq!(core.wft_manager.outstanding_wft(), 0);
594
+ assert_eq!(core.outstanding_wfts(TEST_Q), 0);
643
595
  }
644
596
 
645
597
  pub(crate) fn gen_assert_and_reply(
646
- asserter: &dyn Fn(&WfActivation),
598
+ asserter: &dyn Fn(&WorkflowActivation),
647
599
  reply_commands: Vec<workflow_command::Variant>,
648
600
  ) -> AsserterWithReply<'_> {
649
601
  (
@@ -652,7 +604,7 @@ pub(crate) fn gen_assert_and_reply(
652
604
  )
653
605
  }
654
606
 
655
- pub(crate) fn gen_assert_and_fail(asserter: &dyn Fn(&WfActivation)) -> AsserterWithReply<'_> {
607
+ pub(crate) fn gen_assert_and_fail(asserter: &dyn Fn(&WorkflowActivation)) -> AsserterWithReply<'_> {
656
608
  (
657
609
  asserter,
658
610
  workflow_completion::Failure {
@@ -672,7 +624,7 @@ macro_rules! job_assert {
672
624
  |res| {
673
625
  assert_matches!(
674
626
  res.jobs.as_slice(),
675
- [$(WfActivationJob {
627
+ [$(WorkflowActivationJob {
676
628
  variant: Some($pat),
677
629
  }),+]
678
630
  );