@temporalio/core-bridge 1.11.1 → 1.11.2
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 +86 -88
- package/lib/index.d.ts +3 -0
- package/lib/index.js.map +1 -1
- package/package.json +3 -3
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/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/sdk-core/.github/workflows/per-pr.yml +7 -1
- package/sdk-core/Cargo.toml +1 -1
- package/sdk-core/client/Cargo.toml +3 -3
- package/sdk-core/client/src/lib.rs +1 -1
- package/sdk-core/client/src/metrics.rs +2 -2
- package/sdk-core/client/src/raw.rs +39 -13
- package/sdk-core/client/src/retry.rs +108 -62
- package/sdk-core/client/src/workflow_handle/mod.rs +1 -2
- package/sdk-core/core/Cargo.toml +4 -5
- package/sdk-core/core/src/abstractions.rs +2 -3
- package/sdk-core/core/src/core_tests/activity_tasks.rs +1 -1
- package/sdk-core/core/src/core_tests/local_activities.rs +2 -2
- package/sdk-core/core/src/core_tests/queries.rs +8 -4
- package/sdk-core/core/src/core_tests/updates.rs +2 -2
- package/sdk-core/core/src/core_tests/workflow_cancels.rs +3 -3
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +55 -54
- package/sdk-core/core/src/ephemeral_server/mod.rs +5 -3
- package/sdk-core/core/src/protosext/mod.rs +3 -0
- package/sdk-core/core/src/telemetry/mod.rs +0 -8
- package/sdk-core/core/src/telemetry/otel.rs +7 -3
- package/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +11 -0
- package/sdk-core/core/src/worker/activities.rs +1 -1
- package/sdk-core/core/src/worker/mod.rs +6 -6
- package/sdk-core/core/src/worker/slot_provider.rs +4 -3
- package/sdk-core/core/src/worker/tuner/resource_based.rs +1 -1
- package/sdk-core/core/src/worker/workflow/driven_workflow.rs +28 -2
- package/sdk-core/core/src/worker/workflow/history_update.rs +2 -2
- package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +8 -5
- package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -1
- package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +1 -1
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +7 -7
- package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +10 -15
- package/sdk-core/core/src/worker/workflow/machines/mod.rs +1 -1
- package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +3 -2
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -1
- package/sdk-core/core/src/worker/workflow/machines/update_state_machine.rs +4 -4
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +30 -20
- package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +2 -2
- package/sdk-core/core/src/worker/workflow/managed_run.rs +20 -4
- package/sdk-core/core/src/worker/workflow/mod.rs +33 -29
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +2 -2
- package/sdk-core/core-api/src/telemetry.rs +1 -0
- package/sdk-core/docker/docker-compose-telem.yaml +4 -4
- package/sdk-core/etc/otel-collector-config.yaml +12 -9
- package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +2 -2
- package/sdk-core/sdk/src/lib.rs +30 -3
- package/sdk-core/sdk/src/workflow_context.rs +15 -2
- package/sdk-core/sdk/src/workflow_future.rs +28 -8
- package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +31 -12
- package/sdk-core/sdk-core-protos/src/lib.rs +104 -63
- package/sdk-core/test-utils/src/lib.rs +4 -3
- package/sdk-core/tests/integ_tests/client_tests.rs +36 -7
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +1 -1
- package/sdk-core/tests/integ_tests/metrics_tests.rs +50 -4
- package/sdk-core/tests/integ_tests/queries_tests.rs +95 -62
- package/sdk-core/tests/integ_tests/update_tests.rs +16 -9
- package/sdk-core/tests/integ_tests/visibility_tests.rs +1 -1
- package/sdk-core/tests/integ_tests/worker_tests.rs +82 -1
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +46 -8
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +81 -2
- package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +139 -4
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +43 -28
- package/sdk-core/tests/integ_tests/workflow_tests.rs +2 -1
- package/sdk-core/tests/main.rs +28 -19
- package/sdk-core/tests/runner.rs +7 -2
- package/ts/index.ts +3 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
use crate::{
|
|
2
|
-
ClientOptions, ListClosedFilters, ListOpenFilters, Namespace,
|
|
3
|
-
|
|
2
|
+
raw::IsUserLongPoll, ClientOptions, ListClosedFilters, ListOpenFilters, Namespace,
|
|
3
|
+
RegisterNamespaceOptions, Result, RetryConfig, SignalWithStartOptions, StartTimeFilter,
|
|
4
|
+
WorkflowClientTrait, WorkflowOptions,
|
|
4
5
|
};
|
|
5
6
|
use backoff::{backoff::Backoff, exponential::ExponentialBackoff, Clock, SystemClock};
|
|
6
7
|
use futures_retry::{ErrorHandler, FutureRetry, RetryPolicy};
|
|
7
|
-
use std::{fmt::Debug, future::Future, sync::Arc, time::Duration};
|
|
8
|
+
use std::{error::Error, fmt::Debug, future::Future, sync::Arc, time::Duration};
|
|
8
9
|
use temporal_sdk_core_protos::{
|
|
9
10
|
coresdk::workflow_commands::QueryResult,
|
|
10
11
|
temporal::api::{
|
|
@@ -16,7 +17,7 @@ use temporal_sdk_core_protos::{
|
|
|
16
17
|
},
|
|
17
18
|
TaskToken,
|
|
18
19
|
};
|
|
19
|
-
use tonic::Code;
|
|
20
|
+
use tonic::{Code, Request};
|
|
20
21
|
|
|
21
22
|
/// List of gRPC error codes that client will retry.
|
|
22
23
|
pub const RETRYABLE_ERROR_CODES: [Code; 7] = [
|
|
@@ -71,6 +72,7 @@ impl<SG> RetryClient<SG> {
|
|
|
71
72
|
/// Wraps a call to the underlying client with retry capability.
|
|
72
73
|
///
|
|
73
74
|
/// This is the "old" path used by higher-level [WorkflowClientTrait] implementors
|
|
75
|
+
// TODO: Get rid of this
|
|
74
76
|
pub(crate) async fn call_with_retry<R, F, Fut>(
|
|
75
77
|
&self,
|
|
76
78
|
factory: F,
|
|
@@ -80,22 +82,41 @@ impl<SG> RetryClient<SG> {
|
|
|
80
82
|
F: Fn() -> Fut + Unpin,
|
|
81
83
|
Fut: Future<Output = Result<R>>,
|
|
82
84
|
{
|
|
83
|
-
let
|
|
84
|
-
let res = Self::make_future_retry(
|
|
85
|
+
let info = self.get_call_info::<()>(call_name, None);
|
|
86
|
+
let res = Self::make_future_retry(info, factory).await;
|
|
85
87
|
Ok(res.map_err(|(e, _attempt)| e)?.0)
|
|
86
88
|
}
|
|
87
89
|
|
|
88
|
-
pub(crate) fn
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
pub(crate) fn get_call_info<R>(
|
|
91
|
+
&self,
|
|
92
|
+
call_name: &'static str,
|
|
93
|
+
request: Option<&Request<R>>,
|
|
94
|
+
) -> CallInfo {
|
|
95
|
+
let mut call_type = CallType::Normal;
|
|
96
|
+
let retry_cfg = {
|
|
97
|
+
match call_name {
|
|
98
|
+
POLL_WORKFLOW_METH_NAME | POLL_ACTIVITY_METH_NAME => {
|
|
99
|
+
call_type = CallType::LongPoll;
|
|
100
|
+
RetryConfig::poll_retry_policy()
|
|
101
|
+
}
|
|
102
|
+
_ => (*self.retry_config).clone(),
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
if let Some(r) = request.as_ref() {
|
|
106
|
+
if r.extensions().get::<IsUserLongPoll>().is_some() {
|
|
107
|
+
call_type = CallType::UserLongPoll;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
CallInfo {
|
|
111
|
+
call_type,
|
|
112
|
+
call_name,
|
|
113
|
+
retry_cfg,
|
|
92
114
|
}
|
|
93
115
|
}
|
|
94
116
|
|
|
95
117
|
pub(crate) fn make_future_retry<R, F, Fut>(
|
|
96
|
-
|
|
118
|
+
info: CallInfo,
|
|
97
119
|
factory: F,
|
|
98
|
-
call_name: &'static str,
|
|
99
120
|
) -> FutureRetry<F, TonicErrorHandler<SystemClock>>
|
|
100
121
|
where
|
|
101
122
|
F: FnMut() -> Fut + Unpin,
|
|
@@ -103,7 +124,7 @@ impl<SG> RetryClient<SG> {
|
|
|
103
124
|
{
|
|
104
125
|
FutureRetry::new(
|
|
105
126
|
factory,
|
|
106
|
-
TonicErrorHandler::new(
|
|
127
|
+
TonicErrorHandler::new(info, RetryConfig::throttle_retry_policy()),
|
|
107
128
|
)
|
|
108
129
|
}
|
|
109
130
|
}
|
|
@@ -115,13 +136,13 @@ pub(crate) struct TonicErrorHandler<C: Clock> {
|
|
|
115
136
|
max_retries: usize,
|
|
116
137
|
call_type: CallType,
|
|
117
138
|
call_name: &'static str,
|
|
139
|
+
have_retried_goaway_cancel: bool,
|
|
118
140
|
}
|
|
119
141
|
impl TonicErrorHandler<SystemClock> {
|
|
120
|
-
fn new(
|
|
142
|
+
fn new(call_info: CallInfo, throttle_cfg: RetryConfig) -> Self {
|
|
121
143
|
Self::new_with_clock(
|
|
122
|
-
|
|
144
|
+
call_info,
|
|
123
145
|
throttle_cfg,
|
|
124
|
-
call_name,
|
|
125
146
|
SystemClock::default(),
|
|
126
147
|
SystemClock::default(),
|
|
127
148
|
)
|
|
@@ -132,18 +153,18 @@ where
|
|
|
132
153
|
C: Clock,
|
|
133
154
|
{
|
|
134
155
|
fn new_with_clock(
|
|
135
|
-
|
|
156
|
+
call_info: CallInfo,
|
|
136
157
|
throttle_cfg: RetryConfig,
|
|
137
|
-
call_name: &'static str,
|
|
138
158
|
clock: C,
|
|
139
159
|
throttle_clock: C,
|
|
140
160
|
) -> Self {
|
|
141
161
|
Self {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
backoff:
|
|
162
|
+
call_type: call_info.call_type,
|
|
163
|
+
call_name: call_info.call_name,
|
|
164
|
+
max_retries: call_info.retry_cfg.max_retries,
|
|
165
|
+
backoff: call_info.retry_cfg.into_exp_backoff(clock),
|
|
146
166
|
throttle_backoff: throttle_cfg.into_exp_backoff(throttle_clock),
|
|
167
|
+
have_retried_goaway_cancel: false,
|
|
147
168
|
}
|
|
148
169
|
}
|
|
149
170
|
|
|
@@ -168,19 +189,21 @@ where
|
|
|
168
189
|
}
|
|
169
190
|
}
|
|
170
191
|
}
|
|
192
|
+
|
|
193
|
+
#[derive(Clone, Debug, PartialEq)]
|
|
194
|
+
pub(crate) struct CallInfo {
|
|
195
|
+
call_type: CallType,
|
|
196
|
+
call_name: &'static str,
|
|
197
|
+
retry_cfg: RetryConfig,
|
|
198
|
+
}
|
|
199
|
+
|
|
171
200
|
#[doc(hidden)]
|
|
172
201
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
|
173
202
|
pub enum CallType {
|
|
174
203
|
Normal,
|
|
175
204
|
LongPoll,
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
fn from_call_name(call_name: &str) -> Self {
|
|
179
|
-
match call_name {
|
|
180
|
-
POLL_WORKFLOW_METH_NAME | POLL_ACTIVITY_METH_NAME => CallType::LongPoll,
|
|
181
|
-
_ => CallType::Normal,
|
|
182
|
-
}
|
|
183
|
-
}
|
|
205
|
+
// Like a long poll but won't always retry timeouts/cancels
|
|
206
|
+
UserLongPoll,
|
|
184
207
|
}
|
|
185
208
|
|
|
186
209
|
impl<C> ErrorHandler<tonic::Status> for TonicErrorHandler<C>
|
|
@@ -201,7 +224,26 @@ where
|
|
|
201
224
|
let long_poll_allowed =
|
|
202
225
|
is_long_poll && [Code::Cancelled, Code::DeadlineExceeded].contains(&e.code());
|
|
203
226
|
|
|
204
|
-
|
|
227
|
+
// Sometimes we can get a GOAWAY that, for whatever reason, isn't quite properly handled
|
|
228
|
+
// by hyper or some other internal lib, and we want to retry that still. We'll retry that
|
|
229
|
+
// at most once. Ideally this bit should be removed eventually if we can repro the upstream
|
|
230
|
+
// bug and it is fixed.
|
|
231
|
+
let mut goaway_retry_allowed = false;
|
|
232
|
+
if !self.have_retried_goaway_cancel && e.code() == Code::Cancelled {
|
|
233
|
+
if let Some(e) = e
|
|
234
|
+
.source()
|
|
235
|
+
.and_then(|e| e.downcast_ref::<tonic::transport::Error>())
|
|
236
|
+
.and_then(|te| te.source())
|
|
237
|
+
.and_then(|tec| tec.downcast_ref::<hyper::Error>())
|
|
238
|
+
{
|
|
239
|
+
if format!("{e:?}").contains("connection closed") {
|
|
240
|
+
goaway_retry_allowed = true;
|
|
241
|
+
self.have_retried_goaway_cancel = true;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if RETRYABLE_ERROR_CODES.contains(&e.code()) || long_poll_allowed || goaway_retry_allowed {
|
|
205
247
|
if current_attempt == 1 {
|
|
206
248
|
debug!(error=?e, "gRPC call {} failed on first attempt", self.call_name);
|
|
207
249
|
} else {
|
|
@@ -630,14 +672,16 @@ mod tests {
|
|
|
630
672
|
Code::Unimplemented,
|
|
631
673
|
] {
|
|
632
674
|
for call_name in [POLL_WORKFLOW_METH_NAME, POLL_ACTIVITY_METH_NAME] {
|
|
633
|
-
let mut err_handler = TonicErrorHandler
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
675
|
+
let mut err_handler = TonicErrorHandler::new_with_clock(
|
|
676
|
+
CallInfo {
|
|
677
|
+
call_type: CallType::LongPoll,
|
|
678
|
+
call_name,
|
|
679
|
+
retry_cfg: TEST_RETRY_CONFIG,
|
|
680
|
+
},
|
|
681
|
+
TEST_RETRY_CONFIG,
|
|
682
|
+
FixedClock(Instant::now()),
|
|
683
|
+
FixedClock(Instant::now()),
|
|
684
|
+
);
|
|
641
685
|
let result = err_handler.handle(1, Status::new(code, "Ahh"));
|
|
642
686
|
assert_matches!(result, RetryPolicy::WaitRetry(_));
|
|
643
687
|
err_handler.backoff.clock.0 = err_handler
|
|
@@ -655,14 +699,16 @@ mod tests {
|
|
|
655
699
|
async fn long_poll_retryable_errors_never_fatal() {
|
|
656
700
|
for code in RETRYABLE_ERROR_CODES {
|
|
657
701
|
for call_name in [POLL_WORKFLOW_METH_NAME, POLL_ACTIVITY_METH_NAME] {
|
|
658
|
-
let mut err_handler = TonicErrorHandler
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
702
|
+
let mut err_handler = TonicErrorHandler::new_with_clock(
|
|
703
|
+
CallInfo {
|
|
704
|
+
call_type: CallType::LongPoll,
|
|
705
|
+
call_name,
|
|
706
|
+
retry_cfg: TEST_RETRY_CONFIG,
|
|
707
|
+
},
|
|
708
|
+
TEST_RETRY_CONFIG,
|
|
709
|
+
FixedClock(Instant::now()),
|
|
710
|
+
FixedClock(Instant::now()),
|
|
711
|
+
);
|
|
666
712
|
let result = err_handler.handle(1, Status::new(code, "Ahh"));
|
|
667
713
|
assert_matches!(result, RetryPolicy::WaitRetry(_));
|
|
668
714
|
err_handler.backoff.clock.0 = err_handler
|
|
@@ -705,21 +751,23 @@ mod tests {
|
|
|
705
751
|
|
|
706
752
|
#[tokio::test]
|
|
707
753
|
async fn retry_resource_exhausted() {
|
|
708
|
-
let mut err_handler = TonicErrorHandler
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
754
|
+
let mut err_handler = TonicErrorHandler::new_with_clock(
|
|
755
|
+
CallInfo {
|
|
756
|
+
call_type: CallType::LongPoll,
|
|
757
|
+
call_name: POLL_WORKFLOW_METH_NAME,
|
|
758
|
+
retry_cfg: TEST_RETRY_CONFIG,
|
|
759
|
+
},
|
|
760
|
+
RetryConfig {
|
|
714
761
|
initial_interval: Duration::from_millis(2),
|
|
715
762
|
randomization_factor: 0.0,
|
|
716
763
|
multiplier: 4.0,
|
|
717
764
|
max_interval: Duration::from_millis(10),
|
|
718
765
|
max_elapsed_time: None,
|
|
719
766
|
max_retries: 10,
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
|
|
767
|
+
},
|
|
768
|
+
FixedClock(Instant::now()),
|
|
769
|
+
FixedClock(Instant::now()),
|
|
770
|
+
);
|
|
723
771
|
let result = err_handler.handle(1, Status::new(Code::ResourceExhausted, "leave me alone"));
|
|
724
772
|
match result {
|
|
725
773
|
RetryPolicy::WaitRetry(duration) => assert_eq!(duration, Duration::from_millis(2)),
|
|
@@ -746,9 +794,8 @@ mod tests {
|
|
|
746
794
|
for i in 1..=50 {
|
|
747
795
|
for call in [POLL_WORKFLOW_METH_NAME, POLL_ACTIVITY_METH_NAME] {
|
|
748
796
|
let mut err_handler = TonicErrorHandler::new(
|
|
749
|
-
fake_retry.
|
|
750
|
-
|
|
751
|
-
call,
|
|
797
|
+
fake_retry.get_call_info::<()>(call, None),
|
|
798
|
+
RetryConfig::throttle_retry_policy(),
|
|
752
799
|
);
|
|
753
800
|
let result = err_handler.handle(i, Status::new(Code::Unknown, "Ahh"));
|
|
754
801
|
assert_matches!(result, RetryPolicy::WaitRetry(_));
|
|
@@ -763,9 +810,8 @@ mod tests {
|
|
|
763
810
|
for code in [Code::Cancelled, Code::DeadlineExceeded] {
|
|
764
811
|
for call in [POLL_WORKFLOW_METH_NAME, POLL_ACTIVITY_METH_NAME] {
|
|
765
812
|
let mut err_handler = TonicErrorHandler::new(
|
|
766
|
-
fake_retry.
|
|
767
|
-
|
|
768
|
-
call,
|
|
813
|
+
fake_retry.get_call_info::<()>(call, None),
|
|
814
|
+
RetryConfig::throttle_retry_policy(),
|
|
769
815
|
);
|
|
770
816
|
for i in 1..=5 {
|
|
771
817
|
let result = err_handler.handle(i, Status::new(code, "retryable failure"));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
use crate::{InterceptedMetricsSvc, RawClientLike};
|
|
1
|
+
use crate::{InterceptedMetricsSvc, RawClientLike, WorkflowService};
|
|
2
2
|
use anyhow::{anyhow, bail};
|
|
3
3
|
use std::marker::PhantomData;
|
|
4
4
|
use temporal_sdk_core_protos::{
|
|
@@ -107,7 +107,6 @@ where
|
|
|
107
107
|
let server_res = self
|
|
108
108
|
.client
|
|
109
109
|
.clone()
|
|
110
|
-
.workflow_client_mut()
|
|
111
110
|
.get_workflow_execution_history(GetWorkflowExecutionHistoryRequest {
|
|
112
111
|
namespace: self.info.namespace.to_string(),
|
|
113
112
|
execution: Some(WorkflowExecution {
|
package/sdk-core/core/Cargo.toml
CHANGED
|
@@ -40,11 +40,11 @@ hyper = { version = "1.2", optional = true }
|
|
|
40
40
|
hyper-util = { version = "0.1", features = ["server", "http1", "http2", "tokio"], optional = true }
|
|
41
41
|
itertools = "0.13"
|
|
42
42
|
lru = "0.12"
|
|
43
|
-
mockall = "0.
|
|
43
|
+
mockall = "0.13"
|
|
44
44
|
once_cell = { workspace = true }
|
|
45
45
|
opentelemetry = { workspace = true, features = ["metrics"], optional = true }
|
|
46
46
|
opentelemetry_sdk = { version = "0.24", features = ["rt-tokio", "metrics"], optional = true }
|
|
47
|
-
opentelemetry-otlp = { version = "0.17", features = ["tokio", "metrics"], optional = true }
|
|
47
|
+
opentelemetry-otlp = { version = "0.17", features = ["tokio", "metrics", "tls"], optional = true }
|
|
48
48
|
opentelemetry-prometheus = { version = "0.17", optional = true }
|
|
49
49
|
parking_lot = { version = "0.12", features = ["send_guard"] }
|
|
50
50
|
pid = "4.0"
|
|
@@ -59,7 +59,7 @@ serde = "1.0"
|
|
|
59
59
|
serde_json = "1.0"
|
|
60
60
|
siphasher = "1.0"
|
|
61
61
|
slotmap = "1.0"
|
|
62
|
-
sysinfo = "0.
|
|
62
|
+
sysinfo = { version = "0.31", default-features = false, features = ["system"] }
|
|
63
63
|
tar = { version = "0.4", optional = true }
|
|
64
64
|
thiserror = "1.0"
|
|
65
65
|
tokio = { version = "1.37", features = ["rt", "rt-multi-thread", "parking_lot", "time", "fs", "process"] }
|
|
@@ -92,8 +92,7 @@ assert_matches = "1.4"
|
|
|
92
92
|
bimap = "0.6.1"
|
|
93
93
|
clap = { version = "4.0", features = ["derive"] }
|
|
94
94
|
criterion = "0.5"
|
|
95
|
-
rstest = "0.
|
|
96
|
-
sysinfo = "0.30"
|
|
95
|
+
rstest = "0.22"
|
|
97
96
|
temporal-sdk-core-test-utils = { path = "../test-utils" }
|
|
98
97
|
temporal-sdk = { path = "../sdk" }
|
|
99
98
|
tokio-stream = { version = "0.1", features = ["net"] }
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
pub(crate) mod take_cell;
|
|
4
4
|
|
|
5
5
|
use crate::MetricsContext;
|
|
6
|
-
use derive_more::DebugCustom;
|
|
7
6
|
use std::{
|
|
8
7
|
fmt::{Debug, Formatter},
|
|
9
8
|
sync::{
|
|
@@ -217,9 +216,9 @@ where
|
|
|
217
216
|
}
|
|
218
217
|
|
|
219
218
|
/// Tracks an OwnedMeteredSemPermit and calls on_drop when dropped.
|
|
220
|
-
#[derive(
|
|
219
|
+
#[derive(derive_more::Debug)]
|
|
220
|
+
#[debug("Tracked({inner:?})")]
|
|
221
221
|
#[clippy::has_significant_drop]
|
|
222
|
-
#[debug(fmt = "Tracked({inner:?})")]
|
|
223
222
|
pub(crate) struct TrackedOwnedMeteredSemPermit<SK: SlotKind> {
|
|
224
223
|
inner: Option<OwnedMeteredSemPermit<SK>>,
|
|
225
224
|
on_drop: Box<dyn Fn() + Send + Sync>,
|
|
@@ -462,7 +462,7 @@ async fn activity_timeout_no_double_resolve() {
|
|
|
462
462
|
WorkflowCachingPolicy::NonSticky,
|
|
463
463
|
&[
|
|
464
464
|
gen_assert_and_reply(
|
|
465
|
-
&job_assert!(workflow_activation_job::Variant::
|
|
465
|
+
&job_assert!(workflow_activation_job::Variant::InitializeWorkflow(_)),
|
|
466
466
|
vec![ScheduleActivity {
|
|
467
467
|
seq: activity_id,
|
|
468
468
|
activity_id: activity_id.to_string(),
|
|
@@ -636,7 +636,7 @@ async fn la_resolve_during_legacy_query_does_not_combine(#[case] impossible_quer
|
|
|
636
636
|
assert_matches!(
|
|
637
637
|
task.jobs.as_slice(),
|
|
638
638
|
&[WorkflowActivationJob {
|
|
639
|
-
variant: Some(workflow_activation_job::Variant::
|
|
639
|
+
variant: Some(workflow_activation_job::Variant::InitializeWorkflow(_)),
|
|
640
640
|
},]
|
|
641
641
|
);
|
|
642
642
|
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
@@ -1239,7 +1239,7 @@ async fn queries_can_be_received_while_heartbeating() {
|
|
|
1239
1239
|
assert_matches!(
|
|
1240
1240
|
task.jobs.as_slice(),
|
|
1241
1241
|
&[WorkflowActivationJob {
|
|
1242
|
-
variant: Some(workflow_activation_job::Variant::
|
|
1242
|
+
variant: Some(workflow_activation_job::Variant::InitializeWorkflow(_)),
|
|
1243
1243
|
},]
|
|
1244
1244
|
);
|
|
1245
1245
|
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
@@ -272,6 +272,7 @@ async fn legacy_query_failure_on_wft_failure() {
|
|
|
272
272
|
message: "Ahh i broke".to_string(),
|
|
273
273
|
..Default::default()
|
|
274
274
|
},
|
|
275
|
+
None,
|
|
275
276
|
))
|
|
276
277
|
.await
|
|
277
278
|
.unwrap();
|
|
@@ -312,11 +313,14 @@ async fn query_failure_because_nondeterminism(#[values(true, false)] legacy: boo
|
|
|
312
313
|
mock.num_expected_fails = 1;
|
|
313
314
|
}
|
|
314
315
|
let mut mock = build_mock_pollers(mock);
|
|
315
|
-
mock.worker_cfg(|wc|
|
|
316
|
+
mock.worker_cfg(|wc| {
|
|
317
|
+
wc.max_cached_workflows = 10;
|
|
318
|
+
wc.ignore_evicts_on_shutdown = false;
|
|
319
|
+
});
|
|
316
320
|
let core = mock_worker(mock);
|
|
317
321
|
|
|
318
322
|
let task = core.poll_workflow_activation().await.unwrap();
|
|
319
|
-
// Nondeterminism, should result in WFT
|
|
323
|
+
// Nondeterminism, should result in WFT being failed
|
|
320
324
|
core.complete_workflow_activation(WorkflowActivationCompletion::empty(task.run_id))
|
|
321
325
|
.await
|
|
322
326
|
.unwrap();
|
|
@@ -474,7 +478,7 @@ async fn query_cache_miss_causes_page_fetch_dont_reply_wft_too_early(
|
|
|
474
478
|
assert_matches!(
|
|
475
479
|
task.jobs.as_slice(),
|
|
476
480
|
[WorkflowActivationJob {
|
|
477
|
-
variant: Some(workflow_activation_job::Variant::
|
|
481
|
+
variant: Some(workflow_activation_job::Variant::InitializeWorkflow(_)),
|
|
478
482
|
}]
|
|
479
483
|
);
|
|
480
484
|
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmd(
|
|
@@ -696,7 +700,7 @@ async fn new_query_fail() {
|
|
|
696
700
|
assert_matches!(
|
|
697
701
|
task.jobs[0],
|
|
698
702
|
WorkflowActivationJob {
|
|
699
|
-
variant: Some(workflow_activation_job::Variant::
|
|
703
|
+
variant: Some(workflow_activation_job::Variant::InitializeWorkflow(_)),
|
|
700
704
|
}
|
|
701
705
|
);
|
|
702
706
|
|
|
@@ -46,10 +46,10 @@ async fn replay_with_empty_first_task() {
|
|
|
46
46
|
task.jobs.as_slice(),
|
|
47
47
|
[
|
|
48
48
|
WorkflowActivationJob {
|
|
49
|
-
variant: Some(workflow_activation_job::Variant::
|
|
49
|
+
variant: Some(workflow_activation_job::Variant::InitializeWorkflow(_)),
|
|
50
50
|
},
|
|
51
51
|
WorkflowActivationJob {
|
|
52
|
-
variant: Some(workflow_activation_job::Variant::
|
|
52
|
+
variant: Some(workflow_activation_job::Variant::DoUpdate(_)),
|
|
53
53
|
},
|
|
54
54
|
]
|
|
55
55
|
);
|
|
@@ -58,7 +58,7 @@ async fn timer_then_cancel_req(
|
|
|
58
58
|
NonSticky,
|
|
59
59
|
&[
|
|
60
60
|
gen_assert_and_reply(
|
|
61
|
-
&job_assert!(workflow_activation_job::Variant::
|
|
61
|
+
&job_assert!(workflow_activation_job::Variant::InitializeWorkflow(_)),
|
|
62
62
|
vec![start_timer_cmd(timer_seq, Duration::from_secs(1))],
|
|
63
63
|
),
|
|
64
64
|
gen_assert_and_reply(
|
|
@@ -84,7 +84,7 @@ async fn timer_then_cancel_req_then_timer_then_cancelled() {
|
|
|
84
84
|
NonSticky,
|
|
85
85
|
&[
|
|
86
86
|
gen_assert_and_reply(
|
|
87
|
-
&job_assert!(workflow_activation_job::Variant::
|
|
87
|
+
&job_assert!(workflow_activation_job::Variant::InitializeWorkflow(_)),
|
|
88
88
|
vec![start_timer_cmd(1, Duration::from_secs(1))],
|
|
89
89
|
),
|
|
90
90
|
gen_assert_and_reply(
|
|
@@ -114,7 +114,7 @@ async fn immediate_cancel() {
|
|
|
114
114
|
NonSticky,
|
|
115
115
|
&[gen_assert_and_reply(
|
|
116
116
|
&job_assert!(
|
|
117
|
-
workflow_activation_job::Variant::
|
|
117
|
+
workflow_activation_job::Variant::InitializeWorkflow(_),
|
|
118
118
|
workflow_activation_job::Variant::CancelWorkflow(_)
|
|
119
119
|
),
|
|
120
120
|
vec![CancelWorkflowExecution {}.into()],
|