@temporalio/core-bridge 1.1.0 → 1.4.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 +765 -128
- package/Cargo.toml +2 -2
- package/common.js +7 -3
- package/index.d.ts +118 -5
- package/index.js +2 -6
- package/package.json +2 -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/scripts/build.js +4 -3
- package/sdk-core/.buildkite/docker/Dockerfile +2 -1
- package/sdk-core/.buildkite/pipeline.yml +2 -0
- package/sdk-core/.cargo/config.toml +1 -1
- package/sdk-core/ARCHITECTURE.md +2 -2
- package/sdk-core/README.md +12 -0
- package/sdk-core/bridge-ffi/Cargo.toml +2 -2
- package/sdk-core/bridge-ffi/src/lib.rs +2 -2
- package/sdk-core/client/Cargo.toml +7 -5
- package/sdk-core/client/src/lib.rs +354 -226
- package/sdk-core/client/src/metrics.rs +13 -11
- package/sdk-core/client/src/raw.rs +352 -107
- package/sdk-core/client/src/retry.rs +188 -147
- package/sdk-core/client/src/workflow_handle/mod.rs +1 -1
- package/sdk-core/core/Cargo.toml +28 -15
- package/sdk-core/core/src/core_tests/activity_tasks.rs +98 -33
- package/sdk-core/core/src/core_tests/child_workflows.rs +125 -3
- package/sdk-core/core/src/core_tests/local_activities.rs +6 -6
- package/sdk-core/core/src/core_tests/workers.rs +3 -2
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +70 -2
- package/sdk-core/core/src/ephemeral_server/mod.rs +515 -0
- package/sdk-core/core/src/lib.rs +62 -28
- package/sdk-core/core/src/pollers/mod.rs +2 -0
- package/sdk-core/core/src/pollers/poll_buffer.rs +4 -4
- package/sdk-core/core/src/replay/mod.rs +3 -3
- package/sdk-core/core/src/retry_logic.rs +10 -9
- package/sdk-core/core/src/telemetry/metrics.rs +48 -39
- package/sdk-core/core/src/telemetry/mod.rs +46 -12
- package/sdk-core/core/src/telemetry/prometheus_server.rs +17 -13
- package/sdk-core/core/src/test_help/mod.rs +18 -8
- package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +10 -10
- package/sdk-core/core/src/worker/activities/local_activities.rs +13 -13
- package/sdk-core/core/src/worker/activities.rs +6 -12
- package/sdk-core/core/src/worker/client/mocks.rs +1 -0
- package/sdk-core/core/src/worker/client.rs +193 -64
- package/sdk-core/core/src/worker/mod.rs +14 -19
- package/sdk-core/core/src/worker/workflow/driven_workflow.rs +3 -0
- package/sdk-core/core/src/worker/workflow/history_update.rs +5 -5
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +133 -85
- package/sdk-core/core/src/worker/workflow/machines/mod.rs +3 -2
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +160 -105
- package/sdk-core/core/src/worker/workflow/managed_run.rs +2 -1
- package/sdk-core/core/src/worker/workflow/mod.rs +62 -58
- package/sdk-core/core/src/worker/workflow/run_cache.rs +5 -3
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +7 -5
- package/sdk-core/core-api/Cargo.toml +3 -3
- package/sdk-core/core-api/src/errors.rs +3 -11
- package/sdk-core/core-api/src/worker.rs +7 -0
- package/sdk-core/protos/api_upstream/.buildkite/Dockerfile +1 -1
- package/sdk-core/protos/api_upstream/.github/CODEOWNERS +1 -1
- package/sdk-core/protos/api_upstream/.github/PULL_REQUEST_TEMPLATE.md +2 -6
- package/sdk-core/protos/api_upstream/.github/workflows/trigger-api-go-update.yml +29 -0
- package/sdk-core/protos/api_upstream/Makefile +2 -2
- package/sdk-core/protos/api_upstream/buf.yaml +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +86 -0
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +26 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +46 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +7 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +14 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +51 -0
- package/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +18 -0
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +57 -1
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +1 -3
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +4 -2
- package/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +11 -0
- package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +23 -0
- package/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +46 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +172 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +30 -0
- package/sdk-core/protos/grpc/health/v1/health.proto +63 -0
- package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +18 -15
- package/sdk-core/protos/testsrv_upstream/Makefile +80 -0
- package/sdk-core/protos/testsrv_upstream/api-linter.yaml +38 -0
- package/sdk-core/protos/testsrv_upstream/buf.yaml +13 -0
- package/sdk-core/protos/testsrv_upstream/dependencies/gogoproto/gogo.proto +141 -0
- package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +63 -0
- package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +90 -0
- package/sdk-core/sdk/Cargo.toml +2 -2
- package/sdk-core/sdk/src/lib.rs +2 -2
- package/sdk-core/sdk/src/workflow_context/options.rs +36 -8
- package/sdk-core/sdk/src/workflow_context.rs +30 -6
- package/sdk-core/sdk/src/workflow_future.rs +4 -4
- package/sdk-core/sdk-core-protos/Cargo.toml +5 -5
- package/sdk-core/sdk-core-protos/build.rs +9 -1
- package/sdk-core/sdk-core-protos/src/history_builder.rs +6 -1
- package/sdk-core/sdk-core-protos/src/lib.rs +93 -32
- package/sdk-core/test-utils/Cargo.toml +3 -3
- package/sdk-core/test-utils/src/canned_histories.rs +58 -0
- package/sdk-core/test-utils/src/lib.rs +35 -12
- package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +128 -0
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +55 -5
- package/sdk-core/tests/integ_tests/polling_tests.rs +2 -1
- package/sdk-core/tests/integ_tests/queries_tests.rs +5 -5
- package/sdk-core/tests/integ_tests/visibility_tests.rs +93 -0
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +93 -10
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +14 -14
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +2 -6
- package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +12 -12
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +12 -1
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +3 -3
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +8 -2
- package/sdk-core/tests/integ_tests/workflow_tests.rs +19 -4
- package/sdk-core/tests/load_tests.rs +2 -1
- package/sdk-core/tests/main.rs +17 -0
- package/sdk-core/tests/runner.rs +93 -0
- package/src/conversions.rs +157 -94
- package/src/helpers.rs +190 -0
- package/src/lib.rs +10 -912
- package/src/runtime.rs +436 -0
- package/src/testing.rs +67 -0
- package/src/worker.rs +465 -0
|
@@ -25,8 +25,8 @@ use crate::{
|
|
|
25
25
|
},
|
|
26
26
|
worker::{
|
|
27
27
|
activities::{DispatchOrTimeoutLA, LACompleteAction, LocalActivityManager},
|
|
28
|
-
client::
|
|
29
|
-
workflow::{LocalResolution, Workflows},
|
|
28
|
+
client::WorkerClient,
|
|
29
|
+
workflow::{LocalResolution, WorkflowBasics, Workflows},
|
|
30
30
|
},
|
|
31
31
|
ActivityHeartbeat, CompleteActivityError, PollActivityError, PollWfError, WorkerTrait,
|
|
32
32
|
};
|
|
@@ -50,14 +50,10 @@ use temporal_sdk_core_protos::{
|
|
|
50
50
|
};
|
|
51
51
|
use tokio_util::sync::CancellationToken;
|
|
52
52
|
|
|
53
|
-
#[cfg(test)]
|
|
54
|
-
use crate::worker::client::WorkerClient;
|
|
55
|
-
use crate::worker::workflow::WorkflowBasics;
|
|
56
|
-
|
|
57
53
|
/// A worker polls on a certain task queue
|
|
58
54
|
pub struct Worker {
|
|
59
55
|
config: WorkerConfig,
|
|
60
|
-
wf_client: Arc<
|
|
56
|
+
wf_client: Arc<dyn WorkerClient>,
|
|
61
57
|
|
|
62
58
|
/// Manages all workflows and WFT processing
|
|
63
59
|
workflows: Workflows,
|
|
@@ -156,7 +152,7 @@ impl Worker {
|
|
|
156
152
|
pub(crate) fn new(
|
|
157
153
|
config: WorkerConfig,
|
|
158
154
|
sticky_queue_name: Option<String>,
|
|
159
|
-
client: Arc<
|
|
155
|
+
client: Arc<dyn WorkerClient>,
|
|
160
156
|
metrics: MetricsContext,
|
|
161
157
|
) -> Self {
|
|
162
158
|
info!(task_queue = %config.task_queue, "Initializing worker");
|
|
@@ -228,13 +224,13 @@ impl Worker {
|
|
|
228
224
|
|
|
229
225
|
#[cfg(test)]
|
|
230
226
|
pub(crate) fn new_test(config: WorkerConfig, client: impl WorkerClient + 'static) -> Self {
|
|
231
|
-
Self::new(config, None, Arc::new(client
|
|
227
|
+
Self::new(config, None, Arc::new(client), Default::default())
|
|
232
228
|
}
|
|
233
229
|
|
|
234
230
|
pub(crate) fn new_with_pollers(
|
|
235
231
|
config: WorkerConfig,
|
|
236
232
|
sticky_queue_name: Option<String>,
|
|
237
|
-
client: Arc<
|
|
233
|
+
client: Arc<dyn WorkerClient>,
|
|
238
234
|
wft_stream: impl Stream<Item = Result<ValidPollWFTQResponse, tonic::Status>> + Send + 'static,
|
|
239
235
|
act_poller: Option<BoxedActPoller>,
|
|
240
236
|
metrics: MetricsContext,
|
|
@@ -266,6 +262,8 @@ impl Worker {
|
|
|
266
262
|
max_outstanding_wfts: config.max_outstanding_workflow_tasks,
|
|
267
263
|
shutdown_token: shutdown_token.child_token(),
|
|
268
264
|
metrics,
|
|
265
|
+
namespace: config.namespace.clone(),
|
|
266
|
+
task_queue: config.task_queue.clone(),
|
|
269
267
|
},
|
|
270
268
|
sticky_queue_name.map(|sq| StickyExecutionAttributes {
|
|
271
269
|
worker_task_queue: Some(TaskQueue {
|
|
@@ -273,7 +271,10 @@ impl Worker {
|
|
|
273
271
|
kind: TaskQueueKind::Sticky as i32,
|
|
274
272
|
}),
|
|
275
273
|
schedule_to_start_timeout: Some(
|
|
276
|
-
config
|
|
274
|
+
config
|
|
275
|
+
.sticky_queue_schedule_to_start_timeout
|
|
276
|
+
.try_into()
|
|
277
|
+
.expect("timeout fits into proto"),
|
|
277
278
|
),
|
|
278
279
|
}),
|
|
279
280
|
client,
|
|
@@ -422,20 +423,14 @@ impl Worker {
|
|
|
422
423
|
}
|
|
423
424
|
|
|
424
425
|
if let Some(atm) = &self.at_task_mgr {
|
|
425
|
-
|
|
426
|
-
Err(CompleteActivityError::TonicError(e)) if should_swallow_net_error(&e) => {
|
|
427
|
-
warn!(error=?e, "Network error while completing activity");
|
|
428
|
-
Ok(())
|
|
429
|
-
}
|
|
430
|
-
o => o,
|
|
431
|
-
}
|
|
426
|
+
atm.complete(task_token, status, &*self.wf_client).await;
|
|
432
427
|
} else {
|
|
433
428
|
error!(
|
|
434
429
|
"Tried to complete activity {} on a worker that does not have an activity manager",
|
|
435
430
|
task_token
|
|
436
431
|
);
|
|
437
|
-
Ok(())
|
|
438
432
|
}
|
|
433
|
+
Ok(())
|
|
439
434
|
}
|
|
440
435
|
|
|
441
436
|
#[instrument(level = "debug", skip(self), fields(run_id))]
|
|
@@ -45,6 +45,9 @@ impl DrivenWorkflow {
|
|
|
45
45
|
.workflow_execution_timeout
|
|
46
46
|
.clone()
|
|
47
47
|
.try_into_or_none(),
|
|
48
|
+
memo: attribs.memo.clone(),
|
|
49
|
+
search_attrs: attribs.search_attributes.clone(),
|
|
50
|
+
retry_policy: attribs.retry_policy.clone(),
|
|
48
51
|
};
|
|
49
52
|
self.send_job(start_workflow_from_attribs(attribs, workflow_id, randomness_seed).into());
|
|
50
53
|
self.started_attrs = Some(started_info);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
use crate::{
|
|
2
2
|
replay::{HistoryInfo, TestHistoryBuilder},
|
|
3
|
-
worker::client::
|
|
3
|
+
worker::client::WorkerClient,
|
|
4
4
|
};
|
|
5
5
|
use futures::{future::BoxFuture, stream, stream::BoxStream, FutureExt, Stream, StreamExt};
|
|
6
6
|
use std::{
|
|
@@ -42,7 +42,7 @@ impl Debug for HistoryUpdate {
|
|
|
42
42
|
|
|
43
43
|
pub struct HistoryPaginator {
|
|
44
44
|
// Potentially this could actually be a ref w/ lifetime here
|
|
45
|
-
client: Arc<
|
|
45
|
+
client: Arc<dyn WorkerClient>,
|
|
46
46
|
event_queue: VecDeque<HistoryEvent>,
|
|
47
47
|
wf_id: String,
|
|
48
48
|
run_id: String,
|
|
@@ -82,7 +82,7 @@ impl HistoryPaginator {
|
|
|
82
82
|
wf_id: String,
|
|
83
83
|
run_id: String,
|
|
84
84
|
next_page_token: impl Into<NextPageToken>,
|
|
85
|
-
client: Arc<
|
|
85
|
+
client: Arc<dyn WorkerClient>,
|
|
86
86
|
) -> Self {
|
|
87
87
|
let next_page_token = next_page_token.into();
|
|
88
88
|
let (event_queue, final_events) =
|
|
@@ -397,7 +397,7 @@ pub mod tests {
|
|
|
397
397
|
"wfid".to_string(),
|
|
398
398
|
"runid".to_string(),
|
|
399
399
|
vec![2], // Start at page "2"
|
|
400
|
-
Arc::new(mock_client
|
|
400
|
+
Arc::new(mock_client),
|
|
401
401
|
),
|
|
402
402
|
prev_started,
|
|
403
403
|
);
|
|
@@ -442,7 +442,7 @@ pub mod tests {
|
|
|
442
442
|
"runid".to_string(),
|
|
443
443
|
// A cache miss means we'll try to fetch from start
|
|
444
444
|
NextPageToken::FetchFromStart,
|
|
445
|
-
Arc::new(mock_client
|
|
445
|
+
Arc::new(mock_client),
|
|
446
446
|
),
|
|
447
447
|
1,
|
|
448
448
|
);
|
|
@@ -7,7 +7,8 @@ use std::convert::{TryFrom, TryInto};
|
|
|
7
7
|
use temporal_sdk_core_protos::{
|
|
8
8
|
coresdk::{
|
|
9
9
|
child_workflow::{
|
|
10
|
-
self as wfr, child_workflow_result::Status as ChildWorkflowStatus,
|
|
10
|
+
self as wfr, child_workflow_result::Status as ChildWorkflowStatus,
|
|
11
|
+
ChildWorkflowCancellationType, ChildWorkflowResult,
|
|
11
12
|
},
|
|
12
13
|
workflow_activation::{
|
|
13
14
|
resolve_child_workflow_execution_start, ResolveChildWorkflowExecution,
|
|
@@ -17,7 +18,7 @@ use temporal_sdk_core_protos::{
|
|
|
17
18
|
workflow_commands::StartChildWorkflowExecution,
|
|
18
19
|
},
|
|
19
20
|
temporal::api::{
|
|
20
|
-
command::v1::Command,
|
|
21
|
+
command::v1::{Command, RequestCancelExternalWorkflowExecutionCommandAttributes},
|
|
21
22
|
common::v1::{Payload, Payloads, WorkflowExecution, WorkflowType},
|
|
22
23
|
enums::v1::{
|
|
23
24
|
CommandType, EventType, RetryState, StartChildWorkflowExecutionFailedCause, TimeoutType,
|
|
@@ -26,8 +27,7 @@ use temporal_sdk_core_protos::{
|
|
|
26
27
|
history::v1::{
|
|
27
28
|
history_event, ChildWorkflowExecutionCompletedEventAttributes,
|
|
28
29
|
ChildWorkflowExecutionFailedEventAttributes,
|
|
29
|
-
ChildWorkflowExecutionStartedEventAttributes,
|
|
30
|
-
ChildWorkflowExecutionTimedOutEventAttributes, HistoryEvent,
|
|
30
|
+
ChildWorkflowExecutionStartedEventAttributes, HistoryEvent,
|
|
31
31
|
StartChildWorkflowExecutionFailedEventAttributes,
|
|
32
32
|
},
|
|
33
33
|
},
|
|
@@ -41,17 +41,32 @@ fsm! {
|
|
|
41
41
|
|
|
42
42
|
Created --(Schedule, on_schedule) --> StartCommandCreated;
|
|
43
43
|
StartCommandCreated --(CommandStartChildWorkflowExecution) --> StartCommandCreated;
|
|
44
|
-
StartCommandCreated --(StartChildWorkflowExecutionInitiated(i64),
|
|
44
|
+
StartCommandCreated --(StartChildWorkflowExecutionInitiated(i64),
|
|
45
|
+
shared on_start_child_workflow_execution_initiated) --> StartEventRecorded;
|
|
45
46
|
StartCommandCreated --(Cancel, shared on_cancelled) --> Cancelled;
|
|
46
47
|
|
|
47
|
-
StartEventRecorded --(ChildWorkflowExecutionStarted(ChildWorkflowExecutionStartedEvent),
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
Started --(
|
|
53
|
-
|
|
54
|
-
Started --(
|
|
48
|
+
StartEventRecorded --(ChildWorkflowExecutionStarted(ChildWorkflowExecutionStartedEvent),
|
|
49
|
+
shared on_child_workflow_execution_started) --> Started;
|
|
50
|
+
StartEventRecorded --(StartChildWorkflowExecutionFailed(StartChildWorkflowExecutionFailedCause),
|
|
51
|
+
on_start_child_workflow_execution_failed) --> StartFailed;
|
|
52
|
+
|
|
53
|
+
Started --(ChildWorkflowExecutionCompleted(Option<Payloads>),
|
|
54
|
+
on_child_workflow_execution_completed) --> Completed;
|
|
55
|
+
Started --(ChildWorkflowExecutionFailed(ChildWorkflowExecutionFailedEventAttributes),
|
|
56
|
+
shared on_child_workflow_execution_failed) --> Failed;
|
|
57
|
+
Started --(ChildWorkflowExecutionTimedOut(RetryState),
|
|
58
|
+
shared on_child_workflow_execution_timed_out) --> TimedOut;
|
|
59
|
+
Started --(ChildWorkflowExecutionCancelled,
|
|
60
|
+
on_child_workflow_execution_cancelled) --> Cancelled;
|
|
61
|
+
Started --(ChildWorkflowExecutionTerminated,
|
|
62
|
+
shared on_child_workflow_execution_terminated) --> Terminated;
|
|
63
|
+
// If cancelled after started, we need to issue a cancel external workflow command, and then
|
|
64
|
+
// the child workflow will resolve somehow, so we want to go back to started and wait for that
|
|
65
|
+
// resolution.
|
|
66
|
+
Started --(Cancel, shared on_cancelled) --> Started;
|
|
67
|
+
// Abandon & try cancel modes may immediately move to cancelled
|
|
68
|
+
Started --(Cancel, shared on_cancelled) --> Cancelled;
|
|
69
|
+
Started --(CommandRequestCancelExternalWorkflowExecution) --> Started;
|
|
55
70
|
|
|
56
71
|
// Ignore any spurious cancellations after resolution
|
|
57
72
|
Cancelled --(Cancel) --> Cancelled;
|
|
@@ -74,11 +89,13 @@ pub(super) enum ChildWorkflowCommand {
|
|
|
74
89
|
#[display(fmt = "Fail")]
|
|
75
90
|
Fail(Failure),
|
|
76
91
|
#[display(fmt = "Cancel")]
|
|
77
|
-
Cancel
|
|
92
|
+
Cancel,
|
|
78
93
|
#[display(fmt = "StartFail")]
|
|
79
94
|
StartFail(StartChildWorkflowExecutionFailedCause),
|
|
80
95
|
#[display(fmt = "StartCancel")]
|
|
81
96
|
StartCancel(Failure),
|
|
97
|
+
#[display(fmt = "CancelAfterStarted")]
|
|
98
|
+
IssueCancelAfterStarted { reason: String },
|
|
82
99
|
}
|
|
83
100
|
|
|
84
101
|
#[derive(Default, Clone)]
|
|
@@ -137,10 +154,7 @@ impl StartCommandCreated {
|
|
|
137
154
|
)),
|
|
138
155
|
..Default::default()
|
|
139
156
|
})),
|
|
140
|
-
failure_info: failure_info_from_state(
|
|
141
|
-
state.clone(),
|
|
142
|
-
RetryState::NonRetryableFailure as i32,
|
|
143
|
-
),
|
|
157
|
+
failure_info: failure_info_from_state(&state, RetryState::NonRetryableFailure),
|
|
144
158
|
..Default::default()
|
|
145
159
|
})],
|
|
146
160
|
Cancelled::default(),
|
|
@@ -188,7 +202,7 @@ pub(super) struct StartFailed {}
|
|
|
188
202
|
pub(super) struct Started {}
|
|
189
203
|
|
|
190
204
|
impl Started {
|
|
191
|
-
|
|
205
|
+
fn on_child_workflow_execution_completed(
|
|
192
206
|
self,
|
|
193
207
|
result: Option<Payloads>,
|
|
194
208
|
) -> ChildWorkflowMachineTransition<Completed> {
|
|
@@ -197,7 +211,7 @@ impl Started {
|
|
|
197
211
|
Completed::default(),
|
|
198
212
|
)
|
|
199
213
|
}
|
|
200
|
-
|
|
214
|
+
fn on_child_workflow_execution_failed(
|
|
201
215
|
self,
|
|
202
216
|
state: SharedState,
|
|
203
217
|
attrs: ChildWorkflowExecutionFailedEventAttributes,
|
|
@@ -205,17 +219,17 @@ impl Started {
|
|
|
205
219
|
ChildWorkflowMachineTransition::ok(
|
|
206
220
|
vec![ChildWorkflowCommand::Fail(Failure {
|
|
207
221
|
message: "Child Workflow execution failed".to_owned(),
|
|
222
|
+
failure_info: failure_info_from_state(&state, attrs.retry_state()),
|
|
208
223
|
cause: attrs.failure.map(Box::new),
|
|
209
|
-
failure_info: failure_info_from_state(state, attrs.retry_state),
|
|
210
224
|
..Default::default()
|
|
211
225
|
})],
|
|
212
226
|
Failed::default(),
|
|
213
227
|
)
|
|
214
228
|
}
|
|
215
|
-
|
|
229
|
+
fn on_child_workflow_execution_timed_out(
|
|
216
230
|
self,
|
|
217
231
|
state: SharedState,
|
|
218
|
-
retry_state:
|
|
232
|
+
retry_state: RetryState,
|
|
219
233
|
) -> ChildWorkflowMachineTransition<TimedOut> {
|
|
220
234
|
ChildWorkflowMachineTransition::ok(
|
|
221
235
|
vec![ChildWorkflowCommand::Fail(Failure {
|
|
@@ -230,37 +244,16 @@ impl Started {
|
|
|
230
244
|
)),
|
|
231
245
|
..Default::default()
|
|
232
246
|
})),
|
|
233
|
-
failure_info: failure_info_from_state(state, retry_state),
|
|
247
|
+
failure_info: failure_info_from_state(&state, retry_state),
|
|
234
248
|
..Default::default()
|
|
235
249
|
})],
|
|
236
250
|
TimedOut::default(),
|
|
237
251
|
)
|
|
238
252
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
state: SharedState,
|
|
242
|
-
) -> ChildWorkflowMachineTransition<Cancelled> {
|
|
243
|
-
ChildWorkflowMachineTransition::ok(
|
|
244
|
-
vec![ChildWorkflowCommand::Cancel(Failure {
|
|
245
|
-
message: "Child Workflow execution cancelled".to_owned(),
|
|
246
|
-
cause: Some(Box::new(Failure {
|
|
247
|
-
failure_info: Some(FailureInfo::CanceledFailureInfo(
|
|
248
|
-
failure::CanceledFailureInfo {
|
|
249
|
-
..Default::default()
|
|
250
|
-
},
|
|
251
|
-
)),
|
|
252
|
-
..Default::default()
|
|
253
|
-
})),
|
|
254
|
-
failure_info: failure_info_from_state(
|
|
255
|
-
state,
|
|
256
|
-
RetryState::NonRetryableFailure as i32,
|
|
257
|
-
),
|
|
258
|
-
..Default::default()
|
|
259
|
-
})],
|
|
260
|
-
Cancelled::default(),
|
|
261
|
-
)
|
|
253
|
+
fn on_child_workflow_execution_cancelled(self) -> ChildWorkflowMachineTransition<Cancelled> {
|
|
254
|
+
ChildWorkflowMachineTransition::ok(vec![ChildWorkflowCommand::Cancel], Cancelled::default())
|
|
262
255
|
}
|
|
263
|
-
|
|
256
|
+
fn on_child_workflow_execution_terminated(
|
|
264
257
|
self,
|
|
265
258
|
state: SharedState,
|
|
266
259
|
) -> ChildWorkflowMachineTransition<Terminated> {
|
|
@@ -274,15 +267,29 @@ impl Started {
|
|
|
274
267
|
)),
|
|
275
268
|
..Default::default()
|
|
276
269
|
})),
|
|
277
|
-
failure_info: failure_info_from_state(
|
|
278
|
-
state,
|
|
279
|
-
RetryState::NonRetryableFailure as i32,
|
|
280
|
-
),
|
|
270
|
+
failure_info: failure_info_from_state(&state, RetryState::NonRetryableFailure),
|
|
281
271
|
..Default::default()
|
|
282
272
|
})],
|
|
283
273
|
Terminated::default(),
|
|
284
274
|
)
|
|
285
275
|
}
|
|
276
|
+
fn on_cancelled(
|
|
277
|
+
self,
|
|
278
|
+
state: SharedState,
|
|
279
|
+
) -> ChildWorkflowMachineTransition<StartedOrCancelled> {
|
|
280
|
+
let dest = match state.cancel_type {
|
|
281
|
+
ChildWorkflowCancellationType::Abandon | ChildWorkflowCancellationType::TryCancel => {
|
|
282
|
+
StartedOrCancelled::Cancelled(Default::default())
|
|
283
|
+
}
|
|
284
|
+
_ => StartedOrCancelled::Started(Default::default()),
|
|
285
|
+
};
|
|
286
|
+
TransitionResult::ok(
|
|
287
|
+
[ChildWorkflowCommand::IssueCancelAfterStarted {
|
|
288
|
+
reason: "Parent workflow requested cancel".to_string(),
|
|
289
|
+
}],
|
|
290
|
+
dest,
|
|
291
|
+
)
|
|
292
|
+
}
|
|
286
293
|
}
|
|
287
294
|
|
|
288
295
|
#[derive(Default, Clone)]
|
|
@@ -301,6 +308,7 @@ pub(super) struct SharedState {
|
|
|
301
308
|
run_id: String,
|
|
302
309
|
workflow_type: String,
|
|
303
310
|
cancelled_before_sent: bool,
|
|
311
|
+
cancel_type: ChildWorkflowCancellationType,
|
|
304
312
|
}
|
|
305
313
|
|
|
306
314
|
/// Creates a new child workflow state machine and a command to start it on the server.
|
|
@@ -322,6 +330,7 @@ impl ChildWorkflowMachine {
|
|
|
322
330
|
workflow_id: attribs.workflow_id.clone(),
|
|
323
331
|
workflow_type: attribs.workflow_type.clone(),
|
|
324
332
|
namespace: attribs.namespace.clone(),
|
|
333
|
+
cancel_type: attribs.cancellation_type(),
|
|
325
334
|
..Default::default()
|
|
326
335
|
},
|
|
327
336
|
};
|
|
@@ -333,6 +342,33 @@ impl ChildWorkflowMachine {
|
|
|
333
342
|
};
|
|
334
343
|
(s, cmd)
|
|
335
344
|
}
|
|
345
|
+
|
|
346
|
+
fn resolve_cancelled_msg(&self) -> ResolveChildWorkflowExecution {
|
|
347
|
+
let failure = Failure {
|
|
348
|
+
message: "Child Workflow execution cancelled".to_owned(),
|
|
349
|
+
cause: Some(Box::new(Failure {
|
|
350
|
+
failure_info: Some(FailureInfo::CanceledFailureInfo(
|
|
351
|
+
failure::CanceledFailureInfo {
|
|
352
|
+
..Default::default()
|
|
353
|
+
},
|
|
354
|
+
)),
|
|
355
|
+
..Default::default()
|
|
356
|
+
})),
|
|
357
|
+
failure_info: failure_info_from_state(
|
|
358
|
+
&self.shared_state,
|
|
359
|
+
RetryState::NonRetryableFailure,
|
|
360
|
+
),
|
|
361
|
+
..Default::default()
|
|
362
|
+
};
|
|
363
|
+
ResolveChildWorkflowExecution {
|
|
364
|
+
seq: self.shared_state.lang_sequence_number,
|
|
365
|
+
result: Some(ChildWorkflowResult {
|
|
366
|
+
status: Some(ChildWorkflowStatus::Cancelled(wfr::Cancellation {
|
|
367
|
+
failure: Some(failure),
|
|
368
|
+
})),
|
|
369
|
+
}),
|
|
370
|
+
}
|
|
371
|
+
}
|
|
336
372
|
}
|
|
337
373
|
|
|
338
374
|
impl TryFrom<HistoryEvent> for ChildWorkflowMachineEvents {
|
|
@@ -415,12 +451,10 @@ impl TryFrom<HistoryEvent> for ChildWorkflowMachineEvents {
|
|
|
415
451
|
}
|
|
416
452
|
Some(EventType::ChildWorkflowExecutionTimedOut) => {
|
|
417
453
|
if let Some(
|
|
418
|
-
history_event::Attributes::ChildWorkflowExecutionTimedOutEventAttributes(
|
|
419
|
-
ChildWorkflowExecutionTimedOutEventAttributes { retry_state, .. },
|
|
420
|
-
),
|
|
454
|
+
history_event::Attributes::ChildWorkflowExecutionTimedOutEventAttributes(atts),
|
|
421
455
|
) = e.attributes
|
|
422
456
|
{
|
|
423
|
-
Self::ChildWorkflowExecutionTimedOut(retry_state)
|
|
457
|
+
Self::ChildWorkflowExecutionTimedOut(atts.retry_state())
|
|
424
458
|
} else {
|
|
425
459
|
return Err(WFMachinesError::Fatal(
|
|
426
460
|
"ChildWorkflowExecutionTimedOut attributes were unset or malformed"
|
|
@@ -435,9 +469,10 @@ impl TryFrom<HistoryEvent> for ChildWorkflowMachineEvents {
|
|
|
435
469
|
Self::ChildWorkflowExecutionCancelled
|
|
436
470
|
}
|
|
437
471
|
_ => {
|
|
438
|
-
return Err(WFMachinesError::Fatal(
|
|
439
|
-
"Child workflow machine does not handle this event"
|
|
440
|
-
|
|
472
|
+
return Err(WFMachinesError::Fatal(format!(
|
|
473
|
+
"Child workflow machine does not handle this event: {:?}",
|
|
474
|
+
e
|
|
475
|
+
)))
|
|
441
476
|
}
|
|
442
477
|
})
|
|
443
478
|
}
|
|
@@ -505,16 +540,33 @@ impl WFMachinesAdapter for ChildWorkflowMachine {
|
|
|
505
540
|
}
|
|
506
541
|
.into()]
|
|
507
542
|
}
|
|
508
|
-
ChildWorkflowCommand::Cancel
|
|
509
|
-
vec![
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
543
|
+
ChildWorkflowCommand::Cancel => {
|
|
544
|
+
vec![self.resolve_cancelled_msg().into()]
|
|
545
|
+
}
|
|
546
|
+
ChildWorkflowCommand::IssueCancelAfterStarted { reason } => {
|
|
547
|
+
let mut resps = vec![];
|
|
548
|
+
if self.shared_state.cancel_type != ChildWorkflowCancellationType::Abandon {
|
|
549
|
+
resps.push(MachineResponse::NewCoreOriginatedCommand(
|
|
550
|
+
RequestCancelExternalWorkflowExecutionCommandAttributes {
|
|
551
|
+
namespace: self.shared_state.namespace.clone(),
|
|
552
|
+
workflow_id: self.shared_state.workflow_id.clone(),
|
|
553
|
+
run_id: self.shared_state.run_id.clone(),
|
|
554
|
+
child_workflow_only: true,
|
|
555
|
+
reason,
|
|
556
|
+
control: "".to_string(),
|
|
557
|
+
}
|
|
558
|
+
.into(),
|
|
559
|
+
))
|
|
516
560
|
}
|
|
517
|
-
|
|
561
|
+
// Immediately resolve abandon/trycancel modes
|
|
562
|
+
if matches!(
|
|
563
|
+
self.shared_state.cancel_type,
|
|
564
|
+
ChildWorkflowCancellationType::Abandon
|
|
565
|
+
| ChildWorkflowCancellationType::TryCancel
|
|
566
|
+
) {
|
|
567
|
+
resps.push(self.resolve_cancelled_msg().into())
|
|
568
|
+
}
|
|
569
|
+
resps
|
|
518
570
|
}
|
|
519
571
|
})
|
|
520
572
|
}
|
|
@@ -544,34 +596,30 @@ impl TryFrom<CommandType> for ChildWorkflowMachineEvents {
|
|
|
544
596
|
fn try_from(c: CommandType) -> Result<Self, Self::Error> {
|
|
545
597
|
Ok(match c {
|
|
546
598
|
CommandType::StartChildWorkflowExecution => Self::CommandStartChildWorkflowExecution,
|
|
599
|
+
CommandType::RequestCancelExternalWorkflowExecution => {
|
|
600
|
+
Self::CommandRequestCancelExternalWorkflowExecution
|
|
601
|
+
}
|
|
547
602
|
_ => return Err(()),
|
|
548
603
|
})
|
|
549
604
|
}
|
|
550
605
|
}
|
|
551
606
|
|
|
552
|
-
/// Cancellation through this machine is valid only when start child workflow command is not sent
|
|
553
|
-
/// yet. Cancellation of an initiated child workflow is done through CancelExternal.
|
|
554
|
-
/// All of the types besides ABANDON are treated differently.
|
|
555
607
|
impl Cancellable for ChildWorkflowMachine {
|
|
556
608
|
fn cancel(&mut self) -> Result<Vec<MachineResponse>, MachineError<Self::Error>> {
|
|
557
609
|
let event = ChildWorkflowMachineEvents::Cancel;
|
|
558
610
|
let vec = OnEventWrapper::on_event_mut(self, event)?;
|
|
559
611
|
let res = vec
|
|
560
612
|
.into_iter()
|
|
561
|
-
.
|
|
562
|
-
ChildWorkflowCommand::StartCancel(
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
status: Some(resolve_child_workflow_execution_start::Status::Cancelled(
|
|
566
|
-
ResolveChildWorkflowExecutionStartCancelled {
|
|
567
|
-
failure: Some(failure),
|
|
568
|
-
},
|
|
569
|
-
)),
|
|
570
|
-
}
|
|
571
|
-
.into()]
|
|
613
|
+
.map(|mc| match mc {
|
|
614
|
+
c @ ChildWorkflowCommand::StartCancel(_)
|
|
615
|
+
| c @ ChildWorkflowCommand::IssueCancelAfterStarted { .. } => {
|
|
616
|
+
self.adapt_response(c, None)
|
|
572
617
|
}
|
|
573
618
|
x => panic!("Invalid cancel event response {:?}", x),
|
|
574
619
|
})
|
|
620
|
+
.collect::<Result<Vec<_>, _>>()?
|
|
621
|
+
.into_iter()
|
|
622
|
+
.flatten()
|
|
575
623
|
.collect();
|
|
576
624
|
Ok(res)
|
|
577
625
|
}
|
|
@@ -581,7 +629,7 @@ impl Cancellable for ChildWorkflowMachine {
|
|
|
581
629
|
}
|
|
582
630
|
}
|
|
583
631
|
|
|
584
|
-
fn failure_info_from_state(state: SharedState, retry_state:
|
|
632
|
+
fn failure_info_from_state(state: &SharedState, retry_state: RetryState) -> Option<FailureInfo> {
|
|
585
633
|
Some(FailureInfo::ChildWorkflowExecutionFailureInfo(
|
|
586
634
|
failure::ChildWorkflowExecutionFailureInfo {
|
|
587
635
|
namespace: state.namespace.clone(),
|
|
@@ -590,10 +638,10 @@ fn failure_info_from_state(state: SharedState, retry_state: i32) -> Option<Failu
|
|
|
590
638
|
}),
|
|
591
639
|
initiated_event_id: state.initiated_event_id,
|
|
592
640
|
started_event_id: state.started_event_id,
|
|
593
|
-
retry_state,
|
|
641
|
+
retry_state: retry_state as i32,
|
|
594
642
|
workflow_execution: Some(WorkflowExecution {
|
|
595
643
|
workflow_id: state.workflow_id.clone(),
|
|
596
|
-
run_id: state.run_id,
|
|
644
|
+
run_id: state.run_id.clone(),
|
|
597
645
|
}),
|
|
598
646
|
},
|
|
599
647
|
))
|