@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
|
@@ -99,7 +99,7 @@ impl WfContext {
|
|
|
99
99
|
self.am_cancelled
|
|
100
100
|
.changed()
|
|
101
101
|
.await
|
|
102
|
-
.expect("Cancelled send half not dropped")
|
|
102
|
+
.expect("Cancelled send half not dropped");
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
/// Request to create a timer
|
|
@@ -206,7 +206,7 @@ impl WfContext {
|
|
|
206
206
|
|
|
207
207
|
/// Force a workflow task failure (EX: in order to retry on non-sticky queue)
|
|
208
208
|
pub fn force_task_fail(&self, with: anyhow::Error) {
|
|
209
|
-
self.send(with.into())
|
|
209
|
+
self.send(with.into());
|
|
210
210
|
}
|
|
211
211
|
|
|
212
212
|
/// Request the cancellation of an external workflow. May resolve as a failure if the workflow
|
|
@@ -262,7 +262,7 @@ impl WfContext {
|
|
|
262
262
|
|
|
263
263
|
/// Cancel any cancellable operation by ID
|
|
264
264
|
fn cancel(&mut self, cancellable_id: CancellableID) {
|
|
265
|
-
self.send(RustWfCmd::Cancel(cancellable_id))
|
|
265
|
+
self.send(RustWfCmd::Cancel(cancellable_id));
|
|
266
266
|
}
|
|
267
267
|
|
|
268
268
|
fn send(&self, c: RustWfCmd) {
|
|
@@ -280,7 +280,7 @@ pub trait CancellableFuture<T>: Future<Output = T> {
|
|
|
280
280
|
struct WFCommandFut<T, D> {
|
|
281
281
|
_unused: PhantomData<T>,
|
|
282
282
|
result_rx: oneshot::Receiver<UnblockEvent>,
|
|
283
|
-
other_dat: D
|
|
283
|
+
other_dat: Option<D>,
|
|
284
284
|
}
|
|
285
285
|
impl<T> WFCommandFut<T, ()> {
|
|
286
286
|
fn new() -> (Self, oneshot::Sender<UnblockEvent>) {
|
|
@@ -295,7 +295,7 @@ impl<T, D> WFCommandFut<T, D> {
|
|
|
295
295
|
Self {
|
|
296
296
|
_unused: PhantomData,
|
|
297
297
|
result_rx: rx,
|
|
298
|
-
other_dat,
|
|
298
|
+
other_dat: Some(other_dat),
|
|
299
299
|
},
|
|
300
300
|
tx,
|
|
301
301
|
)
|
|
@@ -310,9 +310,15 @@ where
|
|
|
310
310
|
type Output = T;
|
|
311
311
|
|
|
312
312
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
313
|
-
self.result_rx
|
|
314
|
-
|
|
315
|
-
|
|
313
|
+
self.result_rx.poll_unpin(cx).map(|x| {
|
|
314
|
+
// SAFETY: Because we can only enter this section once the future has resolved, we
|
|
315
|
+
// know it will never be polled again, therefore consuming the option is OK.
|
|
316
|
+
let od = self
|
|
317
|
+
.other_dat
|
|
318
|
+
.take()
|
|
319
|
+
.expect("Other data must exist when resolving command future");
|
|
320
|
+
Unblockable::unblock(x.unwrap(), od)
|
|
321
|
+
})
|
|
316
322
|
}
|
|
317
323
|
}
|
|
318
324
|
|
|
@@ -348,10 +354,7 @@ where
|
|
|
348
354
|
type Output = T;
|
|
349
355
|
|
|
350
356
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
|
351
|
-
self.cmd_fut
|
|
352
|
-
.result_rx
|
|
353
|
-
.poll_unpin(cx)
|
|
354
|
-
.map(|x| Unblockable::unblock(x.unwrap(), &self.cmd_fut.other_dat))
|
|
357
|
+
self.cmd_fut.poll_unpin(cx)
|
|
355
358
|
}
|
|
356
359
|
}
|
|
357
360
|
|
|
@@ -460,21 +463,24 @@ pub struct ChildWorkflow {
|
|
|
460
463
|
opts: ChildWorkflowOptions,
|
|
461
464
|
}
|
|
462
465
|
|
|
466
|
+
pub struct ChildWfCommon {
|
|
467
|
+
workflow_id: String,
|
|
468
|
+
result_future: CancellableWFCommandFut<ChildWorkflowResult, ()>,
|
|
469
|
+
}
|
|
470
|
+
|
|
463
471
|
pub struct PendingChildWorkflow {
|
|
464
|
-
pub(crate) child_wf_cmd_seq_num: u32,
|
|
465
472
|
pub status: ChildWorkflowStartStatus,
|
|
466
|
-
pub
|
|
473
|
+
pub common: ChildWfCommon,
|
|
467
474
|
}
|
|
468
475
|
|
|
469
476
|
impl PendingChildWorkflow {
|
|
470
477
|
/// Returns `None` if the child did not start successfully. The returned [StartedChildWorkflow]
|
|
471
478
|
/// can be used to wait on, signal, or cancel the child workflow.
|
|
472
|
-
pub fn
|
|
473
|
-
match
|
|
479
|
+
pub fn into_started(self) -> Option<StartedChildWorkflow> {
|
|
480
|
+
match self.status {
|
|
474
481
|
ChildWorkflowStartStatus::Succeeded(s) => Some(StartedChildWorkflow {
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
workflow_id: self.wfid.clone(),
|
|
482
|
+
run_id: s.run_id,
|
|
483
|
+
common: self.common,
|
|
478
484
|
}),
|
|
479
485
|
_ => None,
|
|
480
486
|
}
|
|
@@ -482,9 +488,8 @@ impl PendingChildWorkflow {
|
|
|
482
488
|
}
|
|
483
489
|
|
|
484
490
|
pub struct StartedChildWorkflow {
|
|
485
|
-
pub(crate) child_wf_cmd_seq_num: u32,
|
|
486
491
|
pub run_id: String,
|
|
487
|
-
|
|
492
|
+
common: ChildWfCommon,
|
|
488
493
|
}
|
|
489
494
|
|
|
490
495
|
impl ChildWorkflow {
|
|
@@ -492,10 +497,35 @@ impl ChildWorkflow {
|
|
|
492
497
|
pub fn start(self, cx: &mut WfContext) -> impl CancellableFuture<PendingChildWorkflow> {
|
|
493
498
|
let child_seq = cx.next_child_workflow_sequence_number;
|
|
494
499
|
cx.next_child_workflow_sequence_number += 1;
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
500
|
+
// Immediately create the command/future for the result, otherwise if the user does
|
|
501
|
+
// not await the result until *after* we receive an activation for it, there will be nothing
|
|
502
|
+
// to match when unblocking.
|
|
503
|
+
let cancel_seq = cx.next_cancel_external_wf_sequence_number;
|
|
504
|
+
cx.next_cancel_external_wf_sequence_number += 1;
|
|
505
|
+
let (result_cmd, unblocker) =
|
|
506
|
+
CancellableWFCommandFut::new(CancellableID::ExternalWorkflow {
|
|
507
|
+
seqnum: cancel_seq,
|
|
508
|
+
execution: NamespacedWorkflowExecution {
|
|
509
|
+
workflow_id: self.opts.workflow_id.clone(),
|
|
510
|
+
..Default::default()
|
|
511
|
+
},
|
|
512
|
+
only_child: true,
|
|
513
|
+
});
|
|
514
|
+
cx.send(
|
|
515
|
+
CommandSubscribeChildWorkflowCompletion {
|
|
516
|
+
seq: child_seq,
|
|
517
|
+
unblocker,
|
|
518
|
+
}
|
|
519
|
+
.into(),
|
|
498
520
|
);
|
|
521
|
+
|
|
522
|
+
let common = ChildWfCommon {
|
|
523
|
+
workflow_id: self.opts.workflow_id.clone(),
|
|
524
|
+
result_future: result_cmd,
|
|
525
|
+
};
|
|
526
|
+
|
|
527
|
+
let (cmd, unblocker) =
|
|
528
|
+
CancellableWFCommandFut::new_with_dat(CancellableID::ChildWorkflow(child_seq), common);
|
|
499
529
|
cx.send(
|
|
500
530
|
CommandCreateRequest {
|
|
501
531
|
cmd: self.opts.into_command(child_seq).into(),
|
|
@@ -503,38 +533,23 @@ impl ChildWorkflow {
|
|
|
503
533
|
}
|
|
504
534
|
.into(),
|
|
505
535
|
);
|
|
536
|
+
|
|
506
537
|
cmd
|
|
507
538
|
}
|
|
508
539
|
}
|
|
509
540
|
|
|
510
541
|
impl StartedChildWorkflow {
|
|
511
|
-
///
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
let (cmd, unblocker) = CancellableWFCommandFut::new(CancellableID::ExternalWorkflow {
|
|
516
|
-
seqnum: cancel_seq,
|
|
517
|
-
execution: NamespacedWorkflowExecution {
|
|
518
|
-
workflow_id: self.workflow_id.clone(),
|
|
519
|
-
..Default::default()
|
|
520
|
-
},
|
|
521
|
-
only_child: true,
|
|
522
|
-
});
|
|
523
|
-
cx.send(
|
|
524
|
-
CommandSubscribeChildWorkflowCompletion {
|
|
525
|
-
seq: self.child_wf_cmd_seq_num,
|
|
526
|
-
unblocker,
|
|
527
|
-
}
|
|
528
|
-
.into(),
|
|
529
|
-
);
|
|
530
|
-
cmd
|
|
542
|
+
/// Consumes self and returns a future that will wait until completion of this child workflow
|
|
543
|
+
/// execution
|
|
544
|
+
pub fn result(self) -> impl CancellableFuture<ChildWorkflowResult> {
|
|
545
|
+
self.common.result_future
|
|
531
546
|
}
|
|
532
547
|
|
|
533
548
|
/// Cancel the child workflow
|
|
534
549
|
pub fn cancel(&self, cx: &mut WfContext) -> impl Future<Output = CancelExternalWfResult> {
|
|
535
550
|
let target = NamespacedWorkflowExecution {
|
|
536
551
|
namespace: cx.namespace().to_string(),
|
|
537
|
-
workflow_id: self.workflow_id.clone(),
|
|
552
|
+
workflow_id: self.common.workflow_id.clone(),
|
|
538
553
|
..Default::default()
|
|
539
554
|
};
|
|
540
555
|
cx.cancel_external(target)
|
|
@@ -547,7 +562,7 @@ impl StartedChildWorkflow {
|
|
|
547
562
|
signal_name: impl Into<String>,
|
|
548
563
|
payload: impl Into<Payload>,
|
|
549
564
|
) -> impl CancellableFuture<SignalExternalWfResult> {
|
|
550
|
-
let target = sig_we::Target::ChildWorkflowId(self.workflow_id.clone());
|
|
565
|
+
let target = sig_we::Target::ChildWorkflowId(self.common.workflow_id.clone());
|
|
551
566
|
cx.send_signal_wf(signal_name, payload, target)
|
|
552
567
|
}
|
|
553
568
|
}
|
|
@@ -5,7 +5,7 @@ use crate::{
|
|
|
5
5
|
},
|
|
6
6
|
workflow::CommandID,
|
|
7
7
|
};
|
|
8
|
-
use anyhow::{bail, Context as AnyhowContext, Error};
|
|
8
|
+
use anyhow::{anyhow, bail, Context as AnyhowContext, Error};
|
|
9
9
|
use crossbeam::channel::Receiver;
|
|
10
10
|
use futures::{future::BoxFuture, FutureExt};
|
|
11
11
|
use parking_lot::RwLock;
|
|
@@ -113,7 +113,7 @@ pub struct WorkflowFuture {
|
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
impl WorkflowFuture {
|
|
116
|
-
fn unblock(&mut self, event: UnblockEvent) {
|
|
116
|
+
fn unblock(&mut self, event: UnblockEvent) -> Result<(), Error> {
|
|
117
117
|
let cmd_id = match event {
|
|
118
118
|
UnblockEvent::Timer(seq) => CommandID::Timer(seq),
|
|
119
119
|
UnblockEvent::Activity(seq, _) => CommandID::Activity(seq),
|
|
@@ -124,10 +124,11 @@ impl WorkflowFuture {
|
|
|
124
124
|
};
|
|
125
125
|
let unblocker = self.command_status.remove(&cmd_id);
|
|
126
126
|
unblocker
|
|
127
|
-
.
|
|
127
|
+
.ok_or_else(|| anyhow!("Command {:?} not found to unblock!", cmd_id))?
|
|
128
128
|
.unblocker
|
|
129
129
|
.send(event)
|
|
130
|
-
.
|
|
130
|
+
.expect("Receive half of unblock channel must exist");
|
|
131
|
+
Ok(())
|
|
131
132
|
}
|
|
132
133
|
|
|
133
134
|
fn fail_wft(&self, run_id: String, fail: Error) {
|
|
@@ -163,27 +164,27 @@ impl WorkflowFuture {
|
|
|
163
164
|
Variant::StartWorkflow(_) => {
|
|
164
165
|
// TODO: Can assign randomness seed whenever needed
|
|
165
166
|
}
|
|
166
|
-
Variant::FireTimer(FireTimer { seq }) => self.unblock(UnblockEvent::Timer(seq))
|
|
167
|
+
Variant::FireTimer(FireTimer { seq }) => self.unblock(UnblockEvent::Timer(seq))?,
|
|
167
168
|
Variant::ResolveActivity(ResolveActivity { seq, result }) => {
|
|
168
169
|
self.unblock(UnblockEvent::Activity(
|
|
169
170
|
seq,
|
|
170
171
|
Box::new(result.context("Activity must have result")?),
|
|
171
|
-
))
|
|
172
|
+
))?;
|
|
172
173
|
}
|
|
173
174
|
Variant::ResolveChildWorkflowExecutionStart(
|
|
174
175
|
ResolveChildWorkflowExecutionStart { seq, status },
|
|
175
176
|
) => self.unblock(UnblockEvent::WorkflowStart(
|
|
176
177
|
seq,
|
|
177
178
|
Box::new(status.context("Workflow start must have status")?),
|
|
178
|
-
))
|
|
179
|
+
))?,
|
|
179
180
|
Variant::ResolveChildWorkflowExecution(ResolveChildWorkflowExecution {
|
|
180
181
|
seq,
|
|
181
182
|
result,
|
|
182
183
|
}) => self.unblock(UnblockEvent::WorkflowComplete(
|
|
183
184
|
seq,
|
|
184
185
|
Box::new(result.context("Child Workflow execution must have a result")?),
|
|
185
|
-
))
|
|
186
|
-
Variant::UpdateRandomSeed(_) =>
|
|
186
|
+
))?,
|
|
187
|
+
Variant::UpdateRandomSeed(_) => (),
|
|
187
188
|
Variant::QueryWorkflow(_) => {
|
|
188
189
|
todo!()
|
|
189
190
|
}
|
|
@@ -208,10 +209,10 @@ impl WorkflowFuture {
|
|
|
208
209
|
self.ctx_shared.write().changes.insert(patch_id, true);
|
|
209
210
|
}
|
|
210
211
|
Variant::ResolveSignalExternalWorkflow(attrs) => {
|
|
211
|
-
self.unblock(UnblockEvent::SignalExternal(attrs.seq, attrs.failure))
|
|
212
|
+
self.unblock(UnblockEvent::SignalExternal(attrs.seq, attrs.failure))?;
|
|
212
213
|
}
|
|
213
214
|
Variant::ResolveRequestCancelExternalWorkflow(attrs) => {
|
|
214
|
-
self.unblock(UnblockEvent::CancelExternal(attrs.seq, attrs.failure))
|
|
215
|
+
self.unblock(UnblockEvent::CancelExternal(attrs.seq, attrs.failure))?;
|
|
215
216
|
}
|
|
216
217
|
|
|
217
218
|
Variant::RemoveFromCache(_) => {
|
|
@@ -301,7 +302,7 @@ impl Future for WorkflowFuture {
|
|
|
301
302
|
));
|
|
302
303
|
// TODO: cancelled timer should not simply be unblocked, in the
|
|
303
304
|
// other SDKs this returns an error
|
|
304
|
-
self.unblock(UnblockEvent::Timer(seq))
|
|
305
|
+
self.unblock(UnblockEvent::Timer(seq))?;
|
|
305
306
|
// Re-poll wf future since a timer is now unblocked
|
|
306
307
|
res = self.inner.poll_unpin(cx);
|
|
307
308
|
}
|
|
@@ -12,7 +12,10 @@ pub use workflow_context::{
|
|
|
12
12
|
ActivityOptions, CancellableFuture, ChildWorkflow, ChildWorkflowOptions, WfContext,
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
-
use crate::{
|
|
15
|
+
use crate::{
|
|
16
|
+
prototype_rust_sdk::workflow_context::{ChildWfCommon, PendingChildWorkflow},
|
|
17
|
+
Core,
|
|
18
|
+
};
|
|
16
19
|
use anyhow::{anyhow, bail};
|
|
17
20
|
use futures::{future::BoxFuture, stream::FuturesUnordered, FutureExt, StreamExt};
|
|
18
21
|
use std::{
|
|
@@ -219,12 +222,12 @@ pub type CancelExternalWfResult = Result<CancelExternalOk, Failure>;
|
|
|
219
222
|
trait Unblockable {
|
|
220
223
|
type OtherDat;
|
|
221
224
|
|
|
222
|
-
fn unblock(ue: UnblockEvent, od:
|
|
225
|
+
fn unblock(ue: UnblockEvent, od: Self::OtherDat) -> Self;
|
|
223
226
|
}
|
|
224
227
|
|
|
225
228
|
impl Unblockable for TimerResult {
|
|
226
229
|
type OtherDat = ();
|
|
227
|
-
fn unblock(ue: UnblockEvent, _:
|
|
230
|
+
fn unblock(ue: UnblockEvent, _: Self::OtherDat) -> Self {
|
|
228
231
|
match ue {
|
|
229
232
|
UnblockEvent::Timer(_) => TimerResult,
|
|
230
233
|
_ => panic!("Invalid unblock event for timer"),
|
|
@@ -234,7 +237,7 @@ impl Unblockable for TimerResult {
|
|
|
234
237
|
|
|
235
238
|
impl Unblockable for ActivityResult {
|
|
236
239
|
type OtherDat = ();
|
|
237
|
-
fn unblock(ue: UnblockEvent, _:
|
|
240
|
+
fn unblock(ue: UnblockEvent, _: Self::OtherDat) -> Self {
|
|
238
241
|
match ue {
|
|
239
242
|
UnblockEvent::Activity(_, result) => *result,
|
|
240
243
|
_ => panic!("Invalid unblock event for activity"),
|
|
@@ -244,13 +247,12 @@ impl Unblockable for ActivityResult {
|
|
|
244
247
|
|
|
245
248
|
impl Unblockable for PendingChildWorkflow {
|
|
246
249
|
// Other data here is workflow id
|
|
247
|
-
type OtherDat =
|
|
248
|
-
fn unblock(ue: UnblockEvent, od:
|
|
250
|
+
type OtherDat = ChildWfCommon;
|
|
251
|
+
fn unblock(ue: UnblockEvent, od: Self::OtherDat) -> Self {
|
|
249
252
|
match ue {
|
|
250
|
-
UnblockEvent::WorkflowStart(
|
|
251
|
-
child_wf_cmd_seq_num: seq,
|
|
253
|
+
UnblockEvent::WorkflowStart(_, result) => Self {
|
|
252
254
|
status: *result,
|
|
253
|
-
|
|
255
|
+
common: od,
|
|
254
256
|
},
|
|
255
257
|
_ => panic!("Invalid unblock event for child workflow start"),
|
|
256
258
|
}
|
|
@@ -259,7 +261,7 @@ impl Unblockable for PendingChildWorkflow {
|
|
|
259
261
|
|
|
260
262
|
impl Unblockable for ChildWorkflowResult {
|
|
261
263
|
type OtherDat = ();
|
|
262
|
-
fn unblock(ue: UnblockEvent, _:
|
|
264
|
+
fn unblock(ue: UnblockEvent, _: Self::OtherDat) -> Self {
|
|
263
265
|
match ue {
|
|
264
266
|
UnblockEvent::WorkflowComplete(_, result) => *result,
|
|
265
267
|
_ => panic!("Invalid unblock event for child workflow complete"),
|
|
@@ -269,14 +271,10 @@ impl Unblockable for ChildWorkflowResult {
|
|
|
269
271
|
|
|
270
272
|
impl Unblockable for SignalExternalWfResult {
|
|
271
273
|
type OtherDat = ();
|
|
272
|
-
fn unblock(ue: UnblockEvent, _:
|
|
274
|
+
fn unblock(ue: UnblockEvent, _: Self::OtherDat) -> Self {
|
|
273
275
|
match ue {
|
|
274
276
|
UnblockEvent::SignalExternal(_, maybefail) => {
|
|
275
|
-
|
|
276
|
-
Err(f)
|
|
277
|
-
} else {
|
|
278
|
-
Ok(SignalExternalOk)
|
|
279
|
-
}
|
|
277
|
+
maybefail.map_or(Ok(SignalExternalOk), Err)
|
|
280
278
|
}
|
|
281
279
|
_ => panic!("Invalid unblock event for signal external workflow result"),
|
|
282
280
|
}
|
|
@@ -285,14 +283,10 @@ impl Unblockable for SignalExternalWfResult {
|
|
|
285
283
|
|
|
286
284
|
impl Unblockable for CancelExternalWfResult {
|
|
287
285
|
type OtherDat = ();
|
|
288
|
-
fn unblock(ue: UnblockEvent, _:
|
|
286
|
+
fn unblock(ue: UnblockEvent, _: Self::OtherDat) -> Self {
|
|
289
287
|
match ue {
|
|
290
288
|
UnblockEvent::CancelExternal(_, maybefail) => {
|
|
291
|
-
|
|
292
|
-
Err(f)
|
|
293
|
-
} else {
|
|
294
|
-
Ok(CancelExternalOk)
|
|
295
|
-
}
|
|
289
|
+
maybefail.map_or(Ok(CancelExternalOk), Err)
|
|
296
290
|
}
|
|
297
291
|
_ => panic!("Invalid unblock event for signal external workflow result"),
|
|
298
292
|
}
|
|
@@ -383,7 +377,7 @@ pub enum WfExitValue<T: Debug> {
|
|
|
383
377
|
/// Confirm the workflow was cancelled (can be automatic in a more advanced iteration)
|
|
384
378
|
#[from(ignore)]
|
|
385
379
|
Cancelled,
|
|
386
|
-
///
|
|
380
|
+
/// The run was evicted
|
|
387
381
|
#[from(ignore)]
|
|
388
382
|
Evicted,
|
|
389
383
|
/// Finish with a result
|
|
@@ -360,16 +360,14 @@ impl AggregatorSelector for SDKAggSelector {
|
|
|
360
360
|
if *descriptor.instrument_kind() == InstrumentKind::ValueRecorder {
|
|
361
361
|
// Some recorders are just gauges
|
|
362
362
|
match descriptor.name() {
|
|
363
|
-
STICKY_CACHE_SIZE_NAME => return Some(Arc::new(last_value())),
|
|
364
|
-
NUM_POLLERS_NAME => return Some(Arc::new(last_value())),
|
|
363
|
+
STICKY_CACHE_SIZE_NAME | NUM_POLLERS_NAME => return Some(Arc::new(last_value())),
|
|
365
364
|
_ => (),
|
|
366
365
|
}
|
|
367
366
|
|
|
368
367
|
// Other recorders will select their appropriate buckets
|
|
369
368
|
let buckets = match descriptor.name() {
|
|
370
369
|
WF_E2E_LATENCY_NAME => WF_LATENCY_MS_BUCKETS,
|
|
371
|
-
WF_TASK_EXECUTION_LATENCY_NAME => WF_TASK_MS_BUCKETS,
|
|
372
|
-
WF_TASK_REPLAY_LATENCY_NAME => WF_TASK_MS_BUCKETS,
|
|
370
|
+
WF_TASK_EXECUTION_LATENCY_NAME | WF_TASK_REPLAY_LATENCY_NAME => WF_TASK_MS_BUCKETS,
|
|
373
371
|
WF_TASK_SCHED_TO_START_LATENCY_NAME | ACT_SCHED_TO_START_LATENCY_NAME => {
|
|
374
372
|
TASK_SCHED_TO_START_MS_BUCKETS
|
|
375
373
|
}
|
|
@@ -17,7 +17,7 @@ use opentelemetry::{
|
|
|
17
17
|
};
|
|
18
18
|
use opentelemetry_otlp::WithExportConfig;
|
|
19
19
|
use parking_lot::{const_mutex, Mutex};
|
|
20
|
-
use std::{collections::VecDeque, net::SocketAddr,
|
|
20
|
+
use std::{collections::VecDeque, net::SocketAddr, time::Duration};
|
|
21
21
|
use tracing_subscriber::{layer::SubscriberExt, EnvFilter};
|
|
22
22
|
use url::Url;
|
|
23
23
|
|
|
@@ -112,7 +112,7 @@ pub(crate) fn telemetry_init(opts: &TelemetryOptions) -> Result<(), anyhow::Erro
|
|
|
112
112
|
std::thread::spawn(move || {
|
|
113
113
|
let res = GLOBAL_TELEM_DAT.get_or_try_init::<_, anyhow::Error>(move || {
|
|
114
114
|
// Ensure closure captures the mutex guard
|
|
115
|
-
let _ = guard
|
|
115
|
+
let _ = &*guard;
|
|
116
116
|
|
|
117
117
|
let runtime = tokio::runtime::Builder::new_multi_thread()
|
|
118
118
|
.thread_name("telemetry")
|
|
@@ -120,13 +120,12 @@ pub(crate) fn telemetry_init(opts: &TelemetryOptions) -> Result<(), anyhow::Erro
|
|
|
120
120
|
.enable_all()
|
|
121
121
|
.build()?;
|
|
122
122
|
let mut globaldat = GlobalTelemDat::default();
|
|
123
|
-
let
|
|
123
|
+
let am_forwarding_logs = opts.log_forwarding_level != LevelFilter::Off;
|
|
124
124
|
|
|
125
|
-
if
|
|
125
|
+
if am_forwarding_logs {
|
|
126
126
|
log::set_max_level(opts.log_forwarding_level);
|
|
127
127
|
globaldat.core_export_logger =
|
|
128
128
|
Some(CoreExportLogger::new(opts.log_forwarding_level));
|
|
129
|
-
am_forwarding_logs = true;
|
|
130
129
|
}
|
|
131
130
|
|
|
132
131
|
let filter_layer = EnvFilter::try_from_env(LOG_FILTER_ENV_VAR).or_else(|_| {
|
|
@@ -232,7 +231,7 @@ pub(crate) fn test_telem_console() {
|
|
|
232
231
|
log_forwarding_level: LevelFilter::Off,
|
|
233
232
|
prometheus_export_bind_address: None,
|
|
234
233
|
})
|
|
235
|
-
.unwrap()
|
|
234
|
+
.unwrap();
|
|
236
235
|
}
|
|
237
236
|
|
|
238
237
|
#[allow(dead_code)] // Not always used, called to enable for debugging when needed
|
|
@@ -244,7 +243,7 @@ pub(crate) fn test_telem_collector() {
|
|
|
244
243
|
log_forwarding_level: LevelFilter::Off,
|
|
245
244
|
prometheus_export_bind_address: None,
|
|
246
245
|
})
|
|
247
|
-
.unwrap()
|
|
246
|
+
.unwrap();
|
|
248
247
|
}
|
|
249
248
|
|
|
250
249
|
/// A trait for using [Display] on the contents of vecs, etc, which don't implement it.
|
|
@@ -228,39 +228,9 @@ pub fn single_activity(activity_id: &str) -> TestHistoryBuilder {
|
|
|
228
228
|
let mut t = TestHistoryBuilder::default();
|
|
229
229
|
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
230
230
|
t.add_full_wf_task();
|
|
231
|
-
let scheduled_event_id = t.
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
history_event::Attributes::ActivityTaskScheduledEventAttributes(
|
|
235
|
-
ActivityTaskScheduledEventAttributes {
|
|
236
|
-
activity_id: activity_id.to_string(),
|
|
237
|
-
..Default::default()
|
|
238
|
-
},
|
|
239
|
-
),
|
|
240
|
-
),
|
|
241
|
-
);
|
|
242
|
-
let started_event_id = t.add_get_event_id(
|
|
243
|
-
EventType::ActivityTaskStarted,
|
|
244
|
-
Some(
|
|
245
|
-
history_event::Attributes::ActivityTaskStartedEventAttributes(
|
|
246
|
-
ActivityTaskStartedEventAttributes {
|
|
247
|
-
scheduled_event_id,
|
|
248
|
-
..Default::default()
|
|
249
|
-
},
|
|
250
|
-
),
|
|
251
|
-
),
|
|
252
|
-
);
|
|
253
|
-
t.add(
|
|
254
|
-
EventType::ActivityTaskCompleted,
|
|
255
|
-
history_event::Attributes::ActivityTaskCompletedEventAttributes(
|
|
256
|
-
ActivityTaskCompletedEventAttributes {
|
|
257
|
-
scheduled_event_id,
|
|
258
|
-
started_event_id,
|
|
259
|
-
// todo add the result payload
|
|
260
|
-
..Default::default()
|
|
261
|
-
},
|
|
262
|
-
),
|
|
263
|
-
);
|
|
231
|
+
let scheduled_event_id = t.add_activity_task_scheduled(activity_id);
|
|
232
|
+
let started_event_id = t.add_activity_task_started(scheduled_event_id);
|
|
233
|
+
t.add_activity_task_completed(scheduled_event_id, started_event_id, Default::default());
|
|
264
234
|
t.add_workflow_task_scheduled_and_started();
|
|
265
235
|
t
|
|
266
236
|
}
|
|
@@ -278,28 +248,8 @@ pub fn single_failed_activity(activity_id: &str) -> TestHistoryBuilder {
|
|
|
278
248
|
let mut t = TestHistoryBuilder::default();
|
|
279
249
|
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
280
250
|
t.add_full_wf_task();
|
|
281
|
-
let scheduled_event_id = t.
|
|
282
|
-
|
|
283
|
-
Some(
|
|
284
|
-
history_event::Attributes::ActivityTaskScheduledEventAttributes(
|
|
285
|
-
ActivityTaskScheduledEventAttributes {
|
|
286
|
-
activity_id: activity_id.to_string(),
|
|
287
|
-
..Default::default()
|
|
288
|
-
},
|
|
289
|
-
),
|
|
290
|
-
),
|
|
291
|
-
);
|
|
292
|
-
let started_event_id = t.add_get_event_id(
|
|
293
|
-
EventType::ActivityTaskStarted,
|
|
294
|
-
Some(
|
|
295
|
-
history_event::Attributes::ActivityTaskStartedEventAttributes(
|
|
296
|
-
ActivityTaskStartedEventAttributes {
|
|
297
|
-
scheduled_event_id,
|
|
298
|
-
..Default::default()
|
|
299
|
-
},
|
|
300
|
-
),
|
|
301
|
-
),
|
|
302
|
-
);
|
|
251
|
+
let scheduled_event_id = t.add_activity_task_scheduled(activity_id);
|
|
252
|
+
let started_event_id = t.add_activity_task_started(scheduled_event_id);
|
|
303
253
|
t.add(
|
|
304
254
|
EventType::ActivityTaskFailed,
|
|
305
255
|
history_event::Attributes::ActivityTaskFailedEventAttributes(
|
|
@@ -329,17 +279,7 @@ pub fn cancel_scheduled_activity(activity_id: &str, signal_id: &str) -> TestHist
|
|
|
329
279
|
let mut t = TestHistoryBuilder::default();
|
|
330
280
|
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
331
281
|
t.add_full_wf_task();
|
|
332
|
-
let scheduled_event_id = t.
|
|
333
|
-
EventType::ActivityTaskScheduled,
|
|
334
|
-
Some(
|
|
335
|
-
history_event::Attributes::ActivityTaskScheduledEventAttributes(
|
|
336
|
-
ActivityTaskScheduledEventAttributes {
|
|
337
|
-
activity_id: activity_id.to_string(),
|
|
338
|
-
..Default::default()
|
|
339
|
-
},
|
|
340
|
-
),
|
|
341
|
-
),
|
|
342
|
-
);
|
|
282
|
+
let scheduled_event_id = t.add_activity_task_scheduled(activity_id);
|
|
343
283
|
t.add_we_signaled(
|
|
344
284
|
signal_id,
|
|
345
285
|
vec![Payload {
|
|
@@ -375,17 +315,7 @@ pub fn scheduled_activity_timeout(activity_id: &str) -> TestHistoryBuilder {
|
|
|
375
315
|
let mut t = TestHistoryBuilder::default();
|
|
376
316
|
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
377
317
|
t.add_full_wf_task();
|
|
378
|
-
let scheduled_event_id = t.
|
|
379
|
-
EventType::ActivityTaskScheduled,
|
|
380
|
-
Some(
|
|
381
|
-
history_event::Attributes::ActivityTaskScheduledEventAttributes(
|
|
382
|
-
ActivityTaskScheduledEventAttributes {
|
|
383
|
-
activity_id: activity_id.to_string(),
|
|
384
|
-
..Default::default()
|
|
385
|
-
},
|
|
386
|
-
),
|
|
387
|
-
),
|
|
388
|
-
);
|
|
318
|
+
let scheduled_event_id = t.add_activity_task_scheduled(activity_id);
|
|
389
319
|
t.add(
|
|
390
320
|
EventType::ActivityTaskTimedOut,
|
|
391
321
|
history_event::Attributes::ActivityTaskTimedOutEventAttributes(
|
|
@@ -422,17 +352,7 @@ pub fn scheduled_cancelled_activity_timeout(
|
|
|
422
352
|
let mut t = TestHistoryBuilder::default();
|
|
423
353
|
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
424
354
|
t.add_full_wf_task();
|
|
425
|
-
let scheduled_event_id = t.
|
|
426
|
-
EventType::ActivityTaskScheduled,
|
|
427
|
-
Some(
|
|
428
|
-
history_event::Attributes::ActivityTaskScheduledEventAttributes(
|
|
429
|
-
ActivityTaskScheduledEventAttributes {
|
|
430
|
-
activity_id: activity_id.to_string(),
|
|
431
|
-
..Default::default()
|
|
432
|
-
},
|
|
433
|
-
),
|
|
434
|
-
),
|
|
435
|
-
);
|
|
355
|
+
let scheduled_event_id = t.add_activity_task_scheduled(activity_id);
|
|
436
356
|
t.add_we_signaled(
|
|
437
357
|
signal_id,
|
|
438
358
|
vec![Payload {
|
|
@@ -947,6 +867,7 @@ pub fn two_signals(sig_1_id: &str, sig_2_id: &str) -> TestHistoryBuilder {
|
|
|
947
867
|
/// x: EVENT_TYPE_TIMER_FIRED
|
|
948
868
|
/// x: EVENT_TYPE_WORKFLOW_TASK_SCHEDULED
|
|
949
869
|
/// x: EVENT_TYPE_WORKFLOW_TASK_STARTED
|
|
870
|
+
/// x: EVENT_TYPE_WORKFLOW_TASK_COMPLETED
|
|
950
871
|
/// --- End repeat ---
|
|
951
872
|
/// 4 + (num tasks - 1) * 4 + 1: EVENT_TYPE_WORKFLOW_EXECUTION_COMPLETED
|
|
952
873
|
pub fn long_sequential_timers(num_tasks: usize) -> TestHistoryBuilder {
|
|
@@ -954,7 +875,7 @@ pub fn long_sequential_timers(num_tasks: usize) -> TestHistoryBuilder {
|
|
|
954
875
|
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
955
876
|
t.add_full_wf_task();
|
|
956
877
|
|
|
957
|
-
for i in 1
|
|
878
|
+
for i in 1..=num_tasks {
|
|
958
879
|
let timer_started_event_id = t.add_get_event_id(EventType::TimerStarted, None);
|
|
959
880
|
t.add(
|
|
960
881
|
EventType::TimerFired,
|
|
@@ -1201,13 +1122,16 @@ pub fn timer_then_continue_as_new(timer_id: &str) -> TestHistoryBuilder {
|
|
|
1201
1122
|
/// 10: EVENT_TYPE_WORKFLOW_TASK_COMPLETED
|
|
1202
1123
|
/// 11: EVENT_TYPE_WORKFLOW_EXECUTION_CANCELED
|
|
1203
1124
|
pub fn timer_wf_cancel_req_cancelled(timer_id: &str) -> TestHistoryBuilder {
|
|
1204
|
-
timer_cancel_req_then(timer_id,
|
|
1125
|
+
timer_cancel_req_then(timer_id, TestHistoryBuilder::add_cancelled)
|
|
1205
1126
|
}
|
|
1206
1127
|
pub fn timer_wf_cancel_req_completed(timer_id: &str) -> TestHistoryBuilder {
|
|
1207
|
-
timer_cancel_req_then(
|
|
1128
|
+
timer_cancel_req_then(
|
|
1129
|
+
timer_id,
|
|
1130
|
+
TestHistoryBuilder::add_workflow_execution_completed,
|
|
1131
|
+
)
|
|
1208
1132
|
}
|
|
1209
1133
|
pub fn timer_wf_cancel_req_failed(timer_id: &str) -> TestHistoryBuilder {
|
|
1210
|
-
timer_cancel_req_then(timer_id,
|
|
1134
|
+
timer_cancel_req_then(timer_id, TestHistoryBuilder::add_workflow_execution_failed)
|
|
1211
1135
|
}
|
|
1212
1136
|
|
|
1213
1137
|
/// 1: EVENT_TYPE_WORKFLOW_EXECUTION_STARTED
|
|
@@ -1237,7 +1161,7 @@ pub fn timer_wf_cancel_req_do_another_timer_then_cancelled() -> TestHistoryBuild
|
|
|
1237
1161
|
}),
|
|
1238
1162
|
);
|
|
1239
1163
|
t.add_full_wf_task();
|
|
1240
|
-
t.add_cancelled()
|
|
1164
|
+
t.add_cancelled();
|
|
1241
1165
|
})
|
|
1242
1166
|
}
|
|
1243
1167
|
|