@temporalio/core-bridge 0.14.0 → 0.16.4
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 +162 -38
- package/Cargo.toml +3 -3
- package/index.d.ts +14 -1
- package/index.node +0 -0
- package/package.json +8 -5
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/{x86_64-pc-windows-gnu → 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/scripts/build.js +77 -34
- package/sdk-core/.buildkite/docker/Dockerfile +1 -1
- package/sdk-core/Cargo.toml +6 -5
- package/sdk-core/fsm/Cargo.toml +1 -1
- package/sdk-core/fsm/rustfsm_procmacro/Cargo.toml +2 -2
- package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +8 -9
- package/sdk-core/fsm/rustfsm_procmacro/tests/trybuild/no_handle_conversions_require_into_fail.stderr +13 -7
- package/sdk-core/fsm/rustfsm_trait/Cargo.toml +2 -2
- package/sdk-core/fsm/rustfsm_trait/src/lib.rs +1 -1
- package/sdk-core/protos/local/workflow_activation.proto +6 -3
- package/sdk-core/sdk-core-protos/Cargo.toml +4 -4
- package/sdk-core/sdk-core-protos/src/lib.rs +38 -50
- package/sdk-core/src/core_tests/activity_tasks.rs +5 -5
- package/sdk-core/src/core_tests/child_workflows.rs +55 -29
- package/sdk-core/src/core_tests/determinism.rs +19 -9
- package/sdk-core/src/core_tests/mod.rs +3 -3
- package/sdk-core/src/core_tests/retry.rs +14 -8
- package/sdk-core/src/core_tests/workers.rs +1 -1
- package/sdk-core/src/core_tests/workflow_tasks.rs +347 -4
- package/sdk-core/src/errors.rs +27 -44
- package/sdk-core/src/lib.rs +13 -3
- package/sdk-core/src/machines/activity_state_machine.rs +44 -5
- package/sdk-core/src/machines/child_workflow_state_machine.rs +31 -11
- package/sdk-core/src/machines/complete_workflow_state_machine.rs +1 -1
- package/sdk-core/src/machines/continue_as_new_workflow_state_machine.rs +1 -1
- package/sdk-core/src/machines/mod.rs +18 -23
- package/sdk-core/src/machines/patch_state_machine.rs +8 -8
- package/sdk-core/src/machines/signal_external_state_machine.rs +22 -1
- package/sdk-core/src/machines/timer_state_machine.rs +21 -3
- package/sdk-core/src/machines/transition_coverage.rs +3 -3
- package/sdk-core/src/machines/workflow_machines.rs +11 -11
- package/sdk-core/src/pending_activations.rs +27 -22
- package/sdk-core/src/pollers/gateway.rs +15 -7
- package/sdk-core/src/pollers/poll_buffer.rs +6 -5
- package/sdk-core/src/pollers/retry.rs +153 -120
- package/sdk-core/src/prototype_rust_sdk/workflow_context.rs +61 -46
- package/sdk-core/src/prototype_rust_sdk/workflow_future.rs +13 -12
- package/sdk-core/src/prototype_rust_sdk.rs +17 -23
- package/sdk-core/src/telemetry/metrics.rs +2 -4
- package/sdk-core/src/telemetry/mod.rs +6 -7
- package/sdk-core/src/test_help/canned_histories.rs +17 -93
- package/sdk-core/src/test_help/history_builder.rs +61 -2
- package/sdk-core/src/test_help/history_info.rs +21 -2
- package/sdk-core/src/test_help/mod.rs +26 -34
- package/sdk-core/src/worker/activities/activity_heartbeat_manager.rs +246 -138
- package/sdk-core/src/worker/activities.rs +46 -45
- package/sdk-core/src/worker/config.rs +11 -0
- package/sdk-core/src/worker/dispatcher.rs +5 -5
- package/sdk-core/src/worker/mod.rs +86 -56
- package/sdk-core/src/workflow/driven_workflow.rs +3 -3
- package/sdk-core/src/workflow/history_update.rs +1 -1
- package/sdk-core/src/workflow/mod.rs +2 -1
- package/sdk-core/src/workflow/workflow_tasks/cache_manager.rs +13 -17
- package/sdk-core/src/workflow/workflow_tasks/concurrency_manager.rs +10 -18
- package/sdk-core/src/workflow/workflow_tasks/mod.rs +72 -57
- package/sdk-core/test_utils/Cargo.toml +1 -1
- package/sdk-core/test_utils/src/lib.rs +2 -2
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +61 -1
- package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +2 -2
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +49 -0
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +2 -2
- package/sdk-core/tests/integ_tests/workflow_tests.rs +1 -0
- package/src/conversions.rs +17 -0
- package/src/errors.rs +0 -7
- package/src/lib.rs +0 -20
|
@@ -9,7 +9,10 @@ use crate::{
|
|
|
9
9
|
use anyhow::bail;
|
|
10
10
|
use std::time::SystemTime;
|
|
11
11
|
use temporal_sdk_core_protos::{
|
|
12
|
-
coresdk::common::{
|
|
12
|
+
coresdk::common::{
|
|
13
|
+
build_has_change_marker_details, NamespacedWorkflowExecution, Payload as CorePayload,
|
|
14
|
+
},
|
|
15
|
+
coresdk::IntoPayloadsExt,
|
|
13
16
|
temporal::api::{
|
|
14
17
|
common::v1::{Payload, Payloads, WorkflowExecution, WorkflowType},
|
|
15
18
|
enums::v1::{EventType, WorkflowTaskFailedCause},
|
|
@@ -136,6 +139,52 @@ impl TestHistoryBuilder {
|
|
|
136
139
|
self.build_and_push_event(EventType::WorkflowExecutionCanceled, attrs.into());
|
|
137
140
|
}
|
|
138
141
|
|
|
142
|
+
pub fn add_activity_task_scheduled(&mut self, activity_id: impl Into<String>) -> i64 {
|
|
143
|
+
self.add_get_event_id(
|
|
144
|
+
EventType::ActivityTaskScheduled,
|
|
145
|
+
Some(
|
|
146
|
+
history_event::Attributes::ActivityTaskScheduledEventAttributes(
|
|
147
|
+
ActivityTaskScheduledEventAttributes {
|
|
148
|
+
activity_id: activity_id.into(),
|
|
149
|
+
..Default::default()
|
|
150
|
+
},
|
|
151
|
+
),
|
|
152
|
+
),
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
pub fn add_activity_task_started(&mut self, scheduled_event_id: i64) -> i64 {
|
|
156
|
+
self.add_get_event_id(
|
|
157
|
+
EventType::ActivityTaskStarted,
|
|
158
|
+
Some(
|
|
159
|
+
history_event::Attributes::ActivityTaskStartedEventAttributes(
|
|
160
|
+
ActivityTaskStartedEventAttributes {
|
|
161
|
+
scheduled_event_id,
|
|
162
|
+
..Default::default()
|
|
163
|
+
},
|
|
164
|
+
),
|
|
165
|
+
),
|
|
166
|
+
)
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
pub fn add_activity_task_completed(
|
|
170
|
+
&mut self,
|
|
171
|
+
scheduled_event_id: i64,
|
|
172
|
+
started_event_id: i64,
|
|
173
|
+
payload: CorePayload,
|
|
174
|
+
) {
|
|
175
|
+
self.add(
|
|
176
|
+
EventType::ActivityTaskCompleted,
|
|
177
|
+
history_event::Attributes::ActivityTaskCompletedEventAttributes(
|
|
178
|
+
ActivityTaskCompletedEventAttributes {
|
|
179
|
+
scheduled_event_id,
|
|
180
|
+
started_event_id,
|
|
181
|
+
result: vec![payload].into_payloads(),
|
|
182
|
+
..Default::default()
|
|
183
|
+
},
|
|
184
|
+
),
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
139
188
|
pub fn add_activity_task_cancel_requested(&mut self, scheduled_event_id: i64) {
|
|
140
189
|
let attrs = ActivityTaskCancelRequestedEventAttributes {
|
|
141
190
|
scheduled_event_id,
|
|
@@ -293,6 +342,16 @@ impl TestHistoryBuilder {
|
|
|
293
342
|
HistoryInfo::new_from_history(&self.events.clone().into(), None)
|
|
294
343
|
}
|
|
295
344
|
|
|
345
|
+
pub(crate) fn get_one_wft(
|
|
346
|
+
&self,
|
|
347
|
+
from_wft_number: usize,
|
|
348
|
+
) -> Result<HistoryInfo, HistoryInfoError> {
|
|
349
|
+
let mut histinfo =
|
|
350
|
+
HistoryInfo::new_from_history(&self.events.clone().into(), Some(from_wft_number))?;
|
|
351
|
+
histinfo.make_incremental();
|
|
352
|
+
Ok(histinfo)
|
|
353
|
+
}
|
|
354
|
+
|
|
296
355
|
fn build_and_push_event(&mut self, event_type: EventType, attribs: Attributes) {
|
|
297
356
|
self.current_event_id += 1;
|
|
298
357
|
let evt = HistoryEvent {
|
|
@@ -309,7 +368,7 @@ impl TestHistoryBuilder {
|
|
|
309
368
|
},
|
|
310
369
|
)) = &evt.attributes
|
|
311
370
|
{
|
|
312
|
-
self.original_run_id = original_execution_run_id.
|
|
371
|
+
self.original_run_id = original_execution_run_id.clone();
|
|
313
372
|
};
|
|
314
373
|
self.events.push(evt);
|
|
315
374
|
}
|
|
@@ -100,19 +100,31 @@ impl HistoryInfo {
|
|
|
100
100
|
unreachable!()
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
/// Remove events from the beginning of this history such that it looks like what would've been
|
|
104
|
+
/// delivered on a sticky queue where the previously started task was the one before the last
|
|
105
|
+
/// task in this history.
|
|
106
|
+
pub(crate) fn make_incremental(&mut self) {
|
|
107
|
+
let last_complete_ix = self
|
|
108
|
+
.events
|
|
109
|
+
.iter()
|
|
110
|
+
.rposition(|he| he.event_type() == EventType::WorkflowTaskCompleted)
|
|
111
|
+
.expect("Must be a WFT completed event in history");
|
|
112
|
+
self.events.drain(0..=last_complete_ix);
|
|
113
|
+
}
|
|
114
|
+
|
|
103
115
|
pub(crate) fn events(&self) -> &[HistoryEvent] {
|
|
104
116
|
&self.events
|
|
105
117
|
}
|
|
106
118
|
|
|
107
119
|
/// Non-test code should *not* rely on just counting workflow tasks b/c of pagination
|
|
108
|
-
pub(crate) fn wf_task_count(&self) -> usize {
|
|
120
|
+
pub(crate) const fn wf_task_count(&self) -> usize {
|
|
109
121
|
self.wf_task_count
|
|
110
122
|
}
|
|
111
123
|
}
|
|
112
124
|
|
|
113
125
|
impl From<HistoryInfo> for HistoryUpdate {
|
|
114
126
|
fn from(v: HistoryInfo) -> Self {
|
|
115
|
-
|
|
127
|
+
Self::new_from_events(v.events, v.previous_started_event_id)
|
|
116
128
|
}
|
|
117
129
|
}
|
|
118
130
|
|
|
@@ -135,4 +147,11 @@ mod tests {
|
|
|
135
147
|
let history_info = t.get_history_info(2).unwrap();
|
|
136
148
|
assert_eq!(8, history_info.events.len());
|
|
137
149
|
}
|
|
150
|
+
|
|
151
|
+
#[test]
|
|
152
|
+
fn incremental_works() {
|
|
153
|
+
let t = canned_histories::single_timer("timer1");
|
|
154
|
+
let hi = t.get_one_wft(2).unwrap();
|
|
155
|
+
dbg!(hi.events);
|
|
156
|
+
}
|
|
138
157
|
}
|
|
@@ -47,22 +47,27 @@ use temporal_sdk_core_protos::{
|
|
|
47
47
|
|
|
48
48
|
pub type Result<T, E = anyhow::Error> = std::result::Result<T, E>;
|
|
49
49
|
pub const TEST_Q: &str = "q";
|
|
50
|
+
pub static NO_MORE_WORK_ERROR_MSG: &str = "No more work to do";
|
|
50
51
|
|
|
51
52
|
/// When constructing responses for mocks, indicates how a given response should be built
|
|
52
53
|
#[derive(derive_more::From, Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
|
53
54
|
pub enum ResponseType {
|
|
54
55
|
ToTaskNum(usize),
|
|
56
|
+
/// Returns just the history after the WFT completed of the provided task number - 1, through to
|
|
57
|
+
/// the next WFT started. Simulating the incremental history for just the provided task number
|
|
58
|
+
#[from(ignore)]
|
|
59
|
+
OneTask(usize),
|
|
55
60
|
AllHistory,
|
|
56
61
|
}
|
|
57
62
|
|
|
58
63
|
impl From<&usize> for ResponseType {
|
|
59
64
|
fn from(u: &usize) -> Self {
|
|
60
|
-
|
|
65
|
+
Self::ToTaskNum(*u)
|
|
61
66
|
}
|
|
62
67
|
}
|
|
63
68
|
// :shrug:
|
|
64
|
-
impl From<&
|
|
65
|
-
fn from(r: &
|
|
69
|
+
impl From<&Self> for ResponseType {
|
|
70
|
+
fn from(r: &Self) -> Self {
|
|
66
71
|
*r
|
|
67
72
|
}
|
|
68
73
|
}
|
|
@@ -164,7 +169,7 @@ pub struct MockWorker {
|
|
|
164
169
|
|
|
165
170
|
impl Default for MockWorker {
|
|
166
171
|
fn default() -> Self {
|
|
167
|
-
|
|
172
|
+
Self {
|
|
168
173
|
wf_poller: Box::from(mock_poller()),
|
|
169
174
|
act_poller: None,
|
|
170
175
|
config: WorkerConfig::default_test_q(),
|
|
@@ -174,14 +179,14 @@ impl Default for MockWorker {
|
|
|
174
179
|
|
|
175
180
|
impl MockWorker {
|
|
176
181
|
pub fn new(q: &str, wf_poller: BoxedWFPoller) -> Self {
|
|
177
|
-
|
|
182
|
+
Self {
|
|
178
183
|
wf_poller,
|
|
179
184
|
act_poller: None,
|
|
180
185
|
config: WorkerConfig::default(q),
|
|
181
186
|
}
|
|
182
187
|
}
|
|
183
188
|
pub fn for_queue(q: &str) -> Self {
|
|
184
|
-
|
|
189
|
+
Self {
|
|
185
190
|
wf_poller: Box::from(mock_poller()),
|
|
186
191
|
act_poller: None,
|
|
187
192
|
config: WorkerConfig::default(q),
|
|
@@ -193,15 +198,12 @@ impl<SG> MocksHolder<SG>
|
|
|
193
198
|
where
|
|
194
199
|
SG: ServerGatewayApis + Send + Sync + 'static,
|
|
195
200
|
{
|
|
196
|
-
pub fn from_mock_workers(
|
|
197
|
-
sg: SG,
|
|
198
|
-
mock_workers: impl IntoIterator<Item = MockWorker>,
|
|
199
|
-
) -> MocksHolder<SG> {
|
|
201
|
+
pub fn from_mock_workers(sg: SG, mock_workers: impl IntoIterator<Item = MockWorker>) -> Self {
|
|
200
202
|
let mock_pollers = mock_workers
|
|
201
203
|
.into_iter()
|
|
202
204
|
.map(|w| (w.config.task_queue.clone(), w))
|
|
203
205
|
.collect();
|
|
204
|
-
|
|
206
|
+
Self {
|
|
205
207
|
sg,
|
|
206
208
|
mock_pollers,
|
|
207
209
|
outstanding_task_map: None,
|
|
@@ -209,16 +211,12 @@ where
|
|
|
209
211
|
}
|
|
210
212
|
|
|
211
213
|
/// Uses the provided list of tasks to create a mock poller for the `TEST_Q`
|
|
212
|
-
pub fn from_gateway_with_responses<WFT, ACT>(
|
|
213
|
-
sg: SG,
|
|
214
|
-
wf_tasks: WFT,
|
|
215
|
-
act_tasks: ACT,
|
|
216
|
-
) -> MocksHolder<SG>
|
|
214
|
+
pub fn from_gateway_with_responses<WFT, ACT>(sg: SG, wf_tasks: WFT, act_tasks: ACT) -> Self
|
|
217
215
|
where
|
|
218
216
|
WFT: IntoIterator<Item = PollWorkflowTaskQueueResponse>,
|
|
219
217
|
ACT: IntoIterator<Item = PollActivityTaskQueueResponse>,
|
|
220
|
-
<WFT as IntoIterator>::IntoIter:
|
|
221
|
-
<ACT as IntoIterator>::IntoIter:
|
|
218
|
+
<WFT as IntoIterator>::IntoIter: Send + 'static,
|
|
219
|
+
<ACT as IntoIterator>::IntoIter: Send + 'static,
|
|
222
220
|
{
|
|
223
221
|
let mut mock_pollers = HashMap::new();
|
|
224
222
|
let mock_poller = mock_poller_from_resps(wf_tasks);
|
|
@@ -234,7 +232,7 @@ where
|
|
|
234
232
|
.unwrap(),
|
|
235
233
|
},
|
|
236
234
|
);
|
|
237
|
-
|
|
235
|
+
Self {
|
|
238
236
|
sg,
|
|
239
237
|
mock_pollers,
|
|
240
238
|
outstanding_task_map: None,
|
|
@@ -246,7 +244,7 @@ pub fn mock_poller_from_resps<T, I>(tasks: I) -> BoxedPoller<T>
|
|
|
246
244
|
where
|
|
247
245
|
T: Send + Sync + 'static,
|
|
248
246
|
I: IntoIterator<Item = T>,
|
|
249
|
-
<I as IntoIterator>::IntoIter:
|
|
247
|
+
<I as IntoIterator>::IntoIter: Send + 'static,
|
|
250
248
|
{
|
|
251
249
|
let mut mock_poller = mock_poller();
|
|
252
250
|
let mut tasks = tasks.into_iter();
|
|
@@ -254,9 +252,7 @@ where
|
|
|
254
252
|
if let Some(t) = tasks.next() {
|
|
255
253
|
Some(Ok(t))
|
|
256
254
|
} else {
|
|
257
|
-
Some(Err(tonic::Status::
|
|
258
|
-
"Ran out of mock responses!",
|
|
259
|
-
)))
|
|
255
|
+
Some(Err(tonic::Status::cancelled(NO_MORE_WORK_ERROR_MSG)))
|
|
260
256
|
}
|
|
261
257
|
});
|
|
262
258
|
Box::new(mock_poller) as BoxedPoller<T>
|
|
@@ -412,7 +408,7 @@ pub fn build_mock_pollers(mut cfg: MockPollCfg) -> MocksHolder<MockServerGateway
|
|
|
412
408
|
let cur_attempt = attempts_at_task_num.entry(to_task_num).or_insert(1);
|
|
413
409
|
let mut r = hist_to_poll_resp(
|
|
414
410
|
&hist.hist,
|
|
415
|
-
hist.wf_id.
|
|
411
|
+
hist.wf_id.clone(),
|
|
416
412
|
*to_task_num,
|
|
417
413
|
hist.task_q.clone(),
|
|
418
414
|
);
|
|
@@ -430,7 +426,7 @@ pub fn build_mock_pollers(mut cfg: MockPollCfg) -> MocksHolder<MockServerGateway
|
|
|
430
426
|
}
|
|
431
427
|
|
|
432
428
|
let mut mock_pollers = HashMap::new();
|
|
433
|
-
for (task_q, mut queue_tasks) in task_queues_to_resps
|
|
429
|
+
for (task_q, mut queue_tasks) in task_queues_to_resps {
|
|
434
430
|
let mut mock_poller = mock_poller();
|
|
435
431
|
|
|
436
432
|
// The poller will return history from any workflow runs that do not have currently
|
|
@@ -438,11 +434,7 @@ pub fn build_mock_pollers(mut cfg: MockPollCfg) -> MocksHolder<MockServerGateway
|
|
|
438
434
|
let outstanding = outstanding_wf_task_tokens.clone();
|
|
439
435
|
mock_poller
|
|
440
436
|
.expect_poll()
|
|
441
|
-
.times(
|
|
442
|
-
correct_num_polls
|
|
443
|
-
.map::<TimesRange, _>(Into::into)
|
|
444
|
-
.unwrap_or_else(|| RangeFull.into()),
|
|
445
|
-
)
|
|
437
|
+
.times(correct_num_polls.map_or_else(|| RangeFull.into(), Into::<TimesRange>::into))
|
|
446
438
|
.returning(move || {
|
|
447
439
|
for (_, tasks) in queue_tasks.iter_mut() {
|
|
448
440
|
// Must extract run id from a workflow task associated with this workflow
|
|
@@ -458,7 +450,7 @@ pub fn build_mock_pollers(mut cfg: MockPollCfg) -> MocksHolder<MockServerGateway
|
|
|
458
450
|
}
|
|
459
451
|
}
|
|
460
452
|
}
|
|
461
|
-
Some(Err(tonic::Status::cancelled(
|
|
453
|
+
Some(Err(tonic::Status::cancelled(NO_MORE_WORK_ERROR_MSG)))
|
|
462
454
|
});
|
|
463
455
|
let mw = MockWorker::new(&task_q, Box::from(mock_poller));
|
|
464
456
|
mock_pollers.insert(task_q, mw);
|
|
@@ -477,8 +469,7 @@ pub fn build_mock_pollers(mut cfg: MockPollCfg) -> MocksHolder<MockServerGateway
|
|
|
477
469
|
.withf(cfg.expect_fail_wft_matcher)
|
|
478
470
|
.times(
|
|
479
471
|
cfg.num_expected_fails
|
|
480
|
-
.
|
|
481
|
-
.unwrap_or_else(|| RangeFull.into()),
|
|
472
|
+
.map_or_else(|| RangeFull.into(), Into::<TimesRange>::into),
|
|
482
473
|
)
|
|
483
474
|
.returning(move |tt, _, _| {
|
|
484
475
|
outstanding.write().remove_by_right(&tt);
|
|
@@ -508,6 +499,7 @@ pub fn hist_to_poll_resp(
|
|
|
508
499
|
};
|
|
509
500
|
let hist_info = match response_type {
|
|
510
501
|
ResponseType::ToTaskNum(tn) => t.get_history_info(tn).unwrap(),
|
|
502
|
+
ResponseType::OneTask(tn) => t.get_one_wft(tn).unwrap(),
|
|
511
503
|
ResponseType::AllHistory => t.get_full_history_info().unwrap(),
|
|
512
504
|
};
|
|
513
505
|
let batch = hist_info.events().to_vec();
|
|
@@ -557,7 +549,7 @@ pub(crate) async fn poll_and_reply<'a>(
|
|
|
557
549
|
eviction_mode: WorkflowCachingPolicy,
|
|
558
550
|
expect_and_reply: &'a [AsserterWithReply<'a>],
|
|
559
551
|
) {
|
|
560
|
-
poll_and_reply_clears_outstanding_evicts(core, None, eviction_mode, expect_and_reply).await
|
|
552
|
+
poll_and_reply_clears_outstanding_evicts(core, None, eviction_mode, expect_and_reply).await;
|
|
561
553
|
}
|
|
562
554
|
|
|
563
555
|
pub(crate) async fn poll_and_reply_clears_outstanding_evicts<'a>(
|