@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.
- package/Cargo.lock +339 -226
- package/Cargo.toml +7 -3
- package/common.js +50 -0
- package/index.d.ts +7 -0
- package/index.js +12 -0
- package/package.json +7 -4
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/{index.node → releases/index.node} +0 -0
- package/releases/x86_64-apple-darwin/index.node +0 -0
- package/releases/x86_64-pc-windows-msvc/index.node +0 -0
- package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
- package/scripts/build.js +10 -50
- package/sdk-core/.buildkite/docker/Dockerfile +1 -1
- package/sdk-core/.buildkite/docker/docker-compose.yaml +2 -2
- package/sdk-core/.buildkite/pipeline.yml +2 -0
- package/sdk-core/Cargo.toml +1 -88
- package/sdk-core/README.md +30 -6
- package/sdk-core/bridge-ffi/Cargo.toml +24 -0
- package/sdk-core/bridge-ffi/LICENSE.txt +23 -0
- package/sdk-core/bridge-ffi/build.rs +25 -0
- package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +216 -0
- package/sdk-core/bridge-ffi/src/lib.rs +829 -0
- package/sdk-core/bridge-ffi/src/wrappers.rs +193 -0
- package/sdk-core/client/Cargo.toml +32 -0
- package/sdk-core/{src/pollers/gateway.rs → client/src/lib.rs} +101 -195
- package/sdk-core/client/src/metrics.rs +89 -0
- package/sdk-core/client/src/mocks.rs +167 -0
- package/sdk-core/{src/pollers → client/src}/retry.rs +172 -14
- package/sdk-core/core/Cargo.toml +96 -0
- package/sdk-core/{src → core/src}/core_tests/activity_tasks.rs +193 -37
- package/sdk-core/{src → core/src}/core_tests/child_workflows.rs +14 -14
- package/sdk-core/{src → core/src}/core_tests/determinism.rs +8 -8
- package/sdk-core/core/src/core_tests/local_activities.rs +328 -0
- package/sdk-core/{src → core/src}/core_tests/mod.rs +6 -9
- package/sdk-core/{src → core/src}/core_tests/queries.rs +54 -54
- package/sdk-core/{src → core/src}/core_tests/replay_flag.rs +8 -12
- package/sdk-core/{src → core/src}/core_tests/workers.rs +120 -33
- package/sdk-core/{src → core/src}/core_tests/workflow_cancels.rs +16 -26
- package/sdk-core/{src → core/src}/core_tests/workflow_tasks.rs +280 -292
- package/sdk-core/core/src/lib.rs +374 -0
- package/sdk-core/{src → core/src}/log_export.rs +3 -27
- package/sdk-core/core/src/pending_activations.rs +162 -0
- package/sdk-core/{src → core/src}/pollers/mod.rs +4 -22
- package/sdk-core/{src → core/src}/pollers/poll_buffer.rs +1 -1
- package/sdk-core/core/src/protosext/mod.rs +396 -0
- package/sdk-core/core/src/replay/mod.rs +210 -0
- package/sdk-core/core/src/retry_logic.rs +144 -0
- package/sdk-core/{src → core/src}/telemetry/metrics.rs +3 -58
- package/sdk-core/{src → core/src}/telemetry/mod.rs +8 -8
- package/sdk-core/{src → core/src}/telemetry/prometheus_server.rs +0 -0
- package/sdk-core/{src → core/src}/test_help/mod.rs +35 -83
- package/sdk-core/{src → core/src}/worker/activities/activity_heartbeat_manager.rs +95 -42
- package/sdk-core/core/src/worker/activities/local_activities.rs +973 -0
- package/sdk-core/{src → core/src}/worker/activities.rs +52 -33
- package/sdk-core/{src → core/src}/worker/dispatcher.rs +8 -6
- package/sdk-core/{src → core/src}/worker/mod.rs +347 -221
- package/sdk-core/core/src/worker/wft_delivery.rs +81 -0
- package/sdk-core/{src → core/src}/workflow/bridge.rs +5 -2
- package/sdk-core/{src → core/src}/workflow/driven_workflow.rs +17 -7
- package/sdk-core/{src → core/src}/workflow/history_update.rs +33 -7
- package/sdk-core/{src → core/src/workflow}/machines/activity_state_machine.rs +26 -26
- package/sdk-core/{src → core/src/workflow}/machines/cancel_external_state_machine.rs +8 -11
- package/sdk-core/{src → core/src/workflow}/machines/cancel_workflow_state_machine.rs +19 -21
- package/sdk-core/{src → core/src/workflow}/machines/child_workflow_state_machine.rs +20 -31
- package/sdk-core/{src → core/src/workflow}/machines/complete_workflow_state_machine.rs +3 -5
- package/sdk-core/{src → core/src/workflow}/machines/continue_as_new_workflow_state_machine.rs +18 -18
- package/sdk-core/{src → core/src/workflow}/machines/fail_workflow_state_machine.rs +5 -6
- package/sdk-core/core/src/workflow/machines/local_activity_state_machine.rs +1451 -0
- package/sdk-core/{src → core/src/workflow}/machines/mod.rs +54 -107
- package/sdk-core/{src → core/src/workflow}/machines/mutable_side_effect_state_machine.rs +0 -0
- package/sdk-core/{src → core/src/workflow}/machines/patch_state_machine.rs +29 -30
- package/sdk-core/{src → core/src/workflow}/machines/side_effect_state_machine.rs +0 -0
- package/sdk-core/{src → core/src/workflow}/machines/signal_external_state_machine.rs +17 -19
- package/sdk-core/{src → core/src/workflow}/machines/timer_state_machine.rs +20 -21
- package/sdk-core/{src → core/src/workflow}/machines/transition_coverage.rs +5 -2
- package/sdk-core/{src → core/src/workflow}/machines/upsert_search_attributes_state_machine.rs +0 -0
- package/sdk-core/core/src/workflow/machines/workflow_machines/local_acts.rs +96 -0
- package/sdk-core/{src → core/src/workflow}/machines/workflow_machines.rs +357 -171
- package/sdk-core/{src → core/src/workflow}/machines/workflow_task_state_machine.rs +1 -1
- package/sdk-core/{src → core/src}/workflow/mod.rs +200 -39
- package/sdk-core/{src → core/src}/workflow/workflow_tasks/cache_manager.rs +0 -0
- package/sdk-core/{src → core/src}/workflow/workflow_tasks/concurrency_manager.rs +38 -5
- package/sdk-core/{src → core/src}/workflow/workflow_tasks/mod.rs +317 -103
- package/sdk-core/{test_utils → core-api}/Cargo.toml +10 -7
- package/sdk-core/{src → core-api/src}/errors.rs +42 -92
- package/sdk-core/core-api/src/lib.rs +158 -0
- package/sdk-core/{src/worker/config.rs → core-api/src/worker.rs} +18 -23
- package/sdk-core/etc/deps.svg +156 -0
- package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +5 -5
- package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +3 -5
- package/sdk-core/fsm/rustfsm_trait/src/lib.rs +7 -1
- package/sdk-core/histories/fail_wf_task.bin +0 -0
- package/sdk-core/histories/timer_workflow_history.bin +0 -0
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +44 -13
- package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +19 -1
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +1 -1
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +9 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +13 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +14 -7
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +176 -18
- package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -0
- package/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +11 -0
- package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +3 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +156 -7
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +135 -104
- package/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +78 -0
- package/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +78 -0
- package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +205 -0
- package/sdk-core/protos/local/temporal/sdk/core/bridge/service.proto +61 -0
- package/sdk-core/protos/local/{child_workflow.proto → temporal/sdk/core/child_workflow/child_workflow.proto} +1 -1
- package/sdk-core/protos/local/{common.proto → temporal/sdk/core/common/common.proto} +5 -3
- package/sdk-core/protos/local/{core_interface.proto → temporal/sdk/core/core_interface.proto} +10 -10
- package/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +30 -0
- package/sdk-core/protos/local/{workflow_activation.proto → temporal/sdk/core/workflow_activation/workflow_activation.proto} +35 -11
- package/sdk-core/protos/local/{workflow_commands.proto → temporal/sdk/core/workflow_commands/workflow_commands.proto} +55 -4
- package/sdk-core/protos/local/{workflow_completion.proto → temporal/sdk/core/workflow_completion/workflow_completion.proto} +3 -3
- package/sdk-core/sdk/Cargo.toml +32 -0
- package/sdk-core/{src/prototype_rust_sdk → sdk/src}/conversions.rs +0 -0
- package/sdk-core/sdk/src/lib.rs +699 -0
- package/sdk-core/sdk/src/payload_converter.rs +11 -0
- package/sdk-core/sdk/src/workflow_context/options.rs +180 -0
- package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_context.rs +201 -124
- package/sdk-core/{src/prototype_rust_sdk → sdk/src}/workflow_future.rs +63 -30
- package/sdk-core/sdk-core-protos/Cargo.toml +10 -0
- package/sdk-core/sdk-core-protos/build.rs +28 -6
- package/sdk-core/sdk-core-protos/src/constants.rs +7 -0
- package/sdk-core/{src/test_help → sdk-core-protos/src}/history_builder.rs +134 -49
- package/sdk-core/sdk-core-protos/src/history_info.rs +216 -0
- package/sdk-core/sdk-core-protos/src/lib.rs +601 -168
- package/sdk-core/sdk-core-protos/src/task_token.rs +38 -0
- package/sdk-core/sdk-core-protos/src/utilities.rs +14 -0
- package/sdk-core/test-utils/Cargo.toml +32 -0
- package/sdk-core/{src/test_help → test-utils/src}/canned_histories.rs +59 -78
- package/sdk-core/test-utils/src/histfetch.rs +28 -0
- package/sdk-core/{test_utils → test-utils}/src/lib.rs +131 -68
- package/sdk-core/tests/integ_tests/client_tests.rs +1 -1
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +11 -7
- package/sdk-core/tests/integ_tests/polling_tests.rs +12 -11
- package/sdk-core/tests/integ_tests/queries_tests.rs +82 -78
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +91 -71
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +3 -4
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +2 -4
- package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +4 -6
- package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +4 -6
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -4
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +496 -0
- package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +5 -8
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +125 -0
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +7 -13
- package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +33 -5
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +12 -16
- package/sdk-core/tests/integ_tests/workflow_tests.rs +85 -82
- package/sdk-core/tests/load_tests.rs +6 -6
- package/sdk-core/tests/main.rs +2 -2
- package/src/conversions.rs +24 -21
- package/src/errors.rs +8 -0
- package/src/lib.rs +323 -211
- package/sdk-core/protos/local/activity_result.proto +0 -46
- package/sdk-core/protos/local/activity_task.proto +0 -66
- package/sdk-core/src/core_tests/retry.rs +0 -147
- package/sdk-core/src/lib.rs +0 -403
- package/sdk-core/src/machines/local_activity_state_machine.rs +0 -117
- package/sdk-core/src/pending_activations.rs +0 -249
- package/sdk-core/src/protosext/mod.rs +0 -160
- package/sdk-core/src/prototype_rust_sdk.rs +0 -412
- package/sdk-core/src/task_token.rs +0 -20
- 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(
|
|
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()
|
|
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
|
|
File without changes
|
|
@@ -1,43 +1,35 @@
|
|
|
1
|
-
pub
|
|
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
|
-
|
|
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,
|
|
16
|
-
|
|
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::
|
|
25
|
+
workflow_activation::WorkflowActivation,
|
|
32
26
|
workflow_commands::workflow_command,
|
|
33
|
-
workflow_completion::{self,
|
|
27
|
+
workflow_completion::{self, workflow_activation_completion, WorkflowActivationCompletion},
|
|
34
28
|
},
|
|
35
29
|
temporal::api::{
|
|
36
|
-
common::v1::
|
|
37
|
-
enums::v1::
|
|
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:
|
|
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:
|
|
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
|
|
506
|
-
|
|
507
|
-
|
|
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> = (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(&
|
|
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(&
|
|
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
|
-
[$(
|
|
627
|
+
[$(WorkflowActivationJob {
|
|
676
628
|
variant: Some($pat),
|
|
677
629
|
}),+]
|
|
678
630
|
);
|