@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
|
@@ -27,7 +27,7 @@ use crate::{
|
|
|
27
27
|
},
|
|
28
28
|
};
|
|
29
29
|
use siphasher::sip::SipHasher13;
|
|
30
|
-
use slotmap::SlotMap;
|
|
30
|
+
use slotmap::{SlotMap, SparseSecondaryMap};
|
|
31
31
|
use std::{
|
|
32
32
|
borrow::{Borrow, BorrowMut},
|
|
33
33
|
collections::{HashMap, VecDeque},
|
|
@@ -39,13 +39,14 @@ use temporal_sdk_core_protos::{
|
|
|
39
39
|
coresdk::{
|
|
40
40
|
common::NamespacedWorkflowExecution,
|
|
41
41
|
workflow_activation::{
|
|
42
|
-
workflow_activation_job
|
|
43
|
-
|
|
42
|
+
workflow_activation_job, NotifyHasPatch, UpdateRandomSeed, WorkflowActivation,
|
|
43
|
+
},
|
|
44
|
+
workflow_commands::{
|
|
45
|
+
request_cancel_external_workflow_execution as cancel_we, ContinueAsNewWorkflowExecution,
|
|
44
46
|
},
|
|
45
|
-
workflow_commands::request_cancel_external_workflow_execution as cancel_we,
|
|
46
47
|
},
|
|
47
48
|
temporal::api::{
|
|
48
|
-
command::v1::Command as ProtoCommand,
|
|
49
|
+
command::v1::{command::Attributes as ProtoCmdAttrs, Command as ProtoCommand},
|
|
49
50
|
enums::v1::EventType,
|
|
50
51
|
history::v1::{history_event, HistoryEvent},
|
|
51
52
|
},
|
|
@@ -94,6 +95,9 @@ pub(crate) struct WorkflowMachines {
|
|
|
94
95
|
current_wf_time: Option<SystemTime>,
|
|
95
96
|
|
|
96
97
|
all_machines: SlotMap<MachineKey, Machines>,
|
|
98
|
+
/// If a machine key is in this map, that machine was created internally by core, not as a
|
|
99
|
+
/// command from lang.
|
|
100
|
+
machine_is_core_created: SparseSecondaryMap<MachineKey, ()>,
|
|
97
101
|
|
|
98
102
|
/// A mapping for accessing machines associated to a particular event, where the key is the id
|
|
99
103
|
/// of the initiating event for that machine.
|
|
@@ -153,7 +157,14 @@ pub enum MachineResponse {
|
|
|
153
157
|
#[display(fmt = "PushWFJob({})", "_0")]
|
|
154
158
|
PushWFJob(workflow_activation_job::Variant),
|
|
155
159
|
|
|
160
|
+
/// Pushes a new command into the list that will be sent to server once we respond with the
|
|
161
|
+
/// workflow task completion
|
|
156
162
|
IssueNewCommand(ProtoCommand),
|
|
163
|
+
/// The machine requests the creation of another *different* machine. This acts as if lang
|
|
164
|
+
/// had replied to the activation with a command, but we use a special set of IDs to avoid
|
|
165
|
+
/// collisions.
|
|
166
|
+
#[display(fmt = "NewCoreOriginatedCommand({:?})", "_0")]
|
|
167
|
+
NewCoreOriginatedCommand(ProtoCmdAttrs),
|
|
157
168
|
#[display(fmt = "IssueFakeLocalActivityMarker({})", "_0")]
|
|
158
169
|
IssueFakeLocalActivityMarker(u32),
|
|
159
170
|
#[display(fmt = "TriggerWFTaskStarted")]
|
|
@@ -162,9 +173,7 @@ pub enum MachineResponse {
|
|
|
162
173
|
time: SystemTime,
|
|
163
174
|
},
|
|
164
175
|
#[display(fmt = "UpdateRunIdOnWorkflowReset({})", run_id)]
|
|
165
|
-
UpdateRunIdOnWorkflowReset {
|
|
166
|
-
run_id: String,
|
|
167
|
-
},
|
|
176
|
+
UpdateRunIdOnWorkflowReset { run_id: String },
|
|
168
177
|
|
|
169
178
|
/// Queue a local activity to be processed by the worker
|
|
170
179
|
#[display(fmt = "QueueLocalActivity")]
|
|
@@ -220,6 +229,7 @@ impl WorkflowMachines {
|
|
|
220
229
|
wft_start_time: None,
|
|
221
230
|
current_wf_time: None,
|
|
222
231
|
all_machines: Default::default(),
|
|
232
|
+
machine_is_core_created: Default::default(),
|
|
223
233
|
machines_by_event_id: Default::default(),
|
|
224
234
|
id_to_machine: Default::default(),
|
|
225
235
|
commands: Default::default(),
|
|
@@ -315,6 +325,12 @@ impl WorkflowMachines {
|
|
|
315
325
|
/// invalid state.
|
|
316
326
|
#[instrument(level = "debug", skip(self, event), fields(event=%event))]
|
|
317
327
|
fn handle_event(&mut self, event: HistoryEvent, has_next_event: bool) -> Result<()> {
|
|
328
|
+
if event.event_type() == EventType::Unspecified {
|
|
329
|
+
return Err(WFMachinesError::Fatal(format!(
|
|
330
|
+
"Event type is unspecified! This history is invalid. Event detail: {:?}",
|
|
331
|
+
event
|
|
332
|
+
)));
|
|
333
|
+
}
|
|
318
334
|
if event.is_final_wf_execution_event() {
|
|
319
335
|
self.have_seen_terminal_event = true;
|
|
320
336
|
}
|
|
@@ -599,10 +615,7 @@ impl WorkflowMachines {
|
|
|
599
615
|
/// the workflow code, handling them, and preparing them to be sent off to the server.
|
|
600
616
|
pub(crate) async fn iterate_machines(&mut self) -> Result<()> {
|
|
601
617
|
let results = self.drive_me.fetch_workflow_iteration_output().await;
|
|
602
|
-
|
|
603
|
-
for job in jobs {
|
|
604
|
-
self.drive_me.send_job(job);
|
|
605
|
-
}
|
|
618
|
+
self.handle_driven_results(results)?;
|
|
606
619
|
self.prepare_commands()?;
|
|
607
620
|
if self.workflow_is_finished() {
|
|
608
621
|
if let Some(rt) = self.total_runtime() {
|
|
@@ -755,10 +768,21 @@ impl WorkflowMachines {
|
|
|
755
768
|
debug!(responses = %machine_responses.display(), machine_name = %sm.kind(),
|
|
756
769
|
"Machine produced responses");
|
|
757
770
|
}
|
|
771
|
+
self.process_machine_resps_impl(smk, machine_responses)
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
fn process_machine_resps_impl(
|
|
775
|
+
&mut self,
|
|
776
|
+
smk: MachineKey,
|
|
777
|
+
machine_responses: Vec<MachineResponse>,
|
|
778
|
+
) -> Result<()> {
|
|
758
779
|
for response in machine_responses {
|
|
759
780
|
match response {
|
|
760
781
|
MachineResponse::PushWFJob(a) => {
|
|
761
|
-
|
|
782
|
+
// We don't need to notify lang about jobs created by core-internal machines
|
|
783
|
+
if !self.machine_is_core_created.contains_key(smk) {
|
|
784
|
+
self.drive_me.send_job(a);
|
|
785
|
+
}
|
|
762
786
|
}
|
|
763
787
|
MachineResponse::TriggerWFTaskStarted {
|
|
764
788
|
task_started_event_id,
|
|
@@ -782,6 +806,27 @@ impl WorkflowMachines {
|
|
|
782
806
|
machine: smk,
|
|
783
807
|
})
|
|
784
808
|
}
|
|
809
|
+
MachineResponse::NewCoreOriginatedCommand(attrs) => match attrs {
|
|
810
|
+
ProtoCmdAttrs::RequestCancelExternalWorkflowExecutionCommandAttributes(
|
|
811
|
+
attrs,
|
|
812
|
+
) => {
|
|
813
|
+
let we = NamespacedWorkflowExecution {
|
|
814
|
+
namespace: attrs.namespace,
|
|
815
|
+
workflow_id: attrs.workflow_id,
|
|
816
|
+
run_id: attrs.run_id,
|
|
817
|
+
};
|
|
818
|
+
self.add_cmd_to_wf_task(
|
|
819
|
+
new_external_cancel(0, we, attrs.child_workflow_only, attrs.reason),
|
|
820
|
+
CommandIdKind::CoreInternal,
|
|
821
|
+
);
|
|
822
|
+
}
|
|
823
|
+
c => {
|
|
824
|
+
return Err(WFMachinesError::Fatal(format!(
|
|
825
|
+
"A machine requested to create a new command of an unsupported type: {:?}",
|
|
826
|
+
c
|
|
827
|
+
)))
|
|
828
|
+
}
|
|
829
|
+
},
|
|
785
830
|
MachineResponse::IssueFakeLocalActivityMarker(seq) => {
|
|
786
831
|
self.current_wf_task_commands.push_back(CommandAndMachine {
|
|
787
832
|
command: MachineAssociatedCommand::FakeLocalActivityMarker(seq),
|
|
@@ -791,11 +836,44 @@ impl WorkflowMachines {
|
|
|
791
836
|
MachineResponse::QueueLocalActivity(act) => {
|
|
792
837
|
self.local_activity_data.enqueue(act);
|
|
793
838
|
}
|
|
794
|
-
MachineResponse::RequestCancelLocalActivity(
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
839
|
+
MachineResponse::RequestCancelLocalActivity(seq) => {
|
|
840
|
+
// We might already know about the status from a pre-resolution. Apply it if so.
|
|
841
|
+
// We need to do this because otherwise we might need to perform additional
|
|
842
|
+
// activations during replay that didn't happen during execution, just like
|
|
843
|
+
// we sometimes pre-resolve activities when first requested.
|
|
844
|
+
if let Some(preres) = self.local_activity_data.take_preresolution(seq) {
|
|
845
|
+
if let Machines::LocalActivityMachine(lam) = self.machine_mut(smk) {
|
|
846
|
+
let more_responses = lam.try_resolve_with_dat(preres)?;
|
|
847
|
+
self.process_machine_responses(smk, more_responses)?;
|
|
848
|
+
} else {
|
|
849
|
+
panic!("A non local-activity machine returned a request cancel LA response");
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
// If it's in the request queue, just rip it out.
|
|
853
|
+
else if let Some(removed_act) =
|
|
854
|
+
self.local_activity_data.remove_from_queue(seq)
|
|
855
|
+
{
|
|
856
|
+
// We removed it. Notify the machine that the activity cancelled.
|
|
857
|
+
if let Machines::LocalActivityMachine(lam) = self.machine_mut(smk) {
|
|
858
|
+
let more_responses = lam.try_resolve(
|
|
859
|
+
LocalActivityExecutionResult::empty_cancel(),
|
|
860
|
+
Duration::from_secs(0),
|
|
861
|
+
removed_act.attempt,
|
|
862
|
+
None,
|
|
863
|
+
None,
|
|
864
|
+
)?;
|
|
865
|
+
self.process_machine_responses(smk, more_responses)?;
|
|
866
|
+
} else {
|
|
867
|
+
panic!("A non local-activity machine returned a request cancel LA response");
|
|
868
|
+
}
|
|
869
|
+
} else {
|
|
870
|
+
// Finally, if we know about the LA at all, it's currently running, so
|
|
871
|
+
// queue the cancel request to be given to the LA manager.
|
|
872
|
+
self.local_activity_data.enqueue_cancel(ExecutingLAId {
|
|
873
|
+
run_id: self.run_id.clone(),
|
|
874
|
+
seq_num: seq,
|
|
875
|
+
});
|
|
876
|
+
}
|
|
799
877
|
}
|
|
800
878
|
MachineResponse::AbandonLocalActivity(seq) => {
|
|
801
879
|
self.local_activity_data.done_executing(seq);
|
|
@@ -816,26 +894,25 @@ impl WorkflowMachines {
|
|
|
816
894
|
/// as part of command processing. For example some types of activity cancellation need to
|
|
817
895
|
/// immediately unblock lang side without having it to poll for an actual workflow task from the
|
|
818
896
|
/// server.
|
|
819
|
-
fn handle_driven_results(
|
|
820
|
-
&mut self,
|
|
821
|
-
results: Vec<WFCommand>,
|
|
822
|
-
) -> Result<Vec<workflow_activation_job::Variant>> {
|
|
823
|
-
let mut jobs = vec![];
|
|
897
|
+
fn handle_driven_results(&mut self, results: Vec<WFCommand>) -> Result<()> {
|
|
824
898
|
for cmd in results {
|
|
825
899
|
match cmd {
|
|
826
900
|
WFCommand::AddTimer(attrs) => {
|
|
827
901
|
let seq = attrs.seq;
|
|
828
|
-
self.add_cmd_to_wf_task(new_timer(attrs),
|
|
902
|
+
self.add_cmd_to_wf_task(new_timer(attrs), CommandID::Timer(seq).into());
|
|
829
903
|
}
|
|
830
904
|
WFCommand::UpsertSearchAttributes(attrs) => {
|
|
831
|
-
self.add_cmd_to_wf_task(
|
|
905
|
+
self.add_cmd_to_wf_task(
|
|
906
|
+
upsert_search_attrs(attrs),
|
|
907
|
+
CommandIdKind::NeverResolves,
|
|
908
|
+
);
|
|
832
909
|
}
|
|
833
910
|
WFCommand::CancelTimer(attrs) => {
|
|
834
|
-
|
|
911
|
+
self.process_cancellation(CommandID::Timer(attrs.seq))?;
|
|
835
912
|
}
|
|
836
913
|
WFCommand::AddActivity(attrs) => {
|
|
837
914
|
let seq = attrs.seq;
|
|
838
|
-
self.add_cmd_to_wf_task(new_activity(attrs),
|
|
915
|
+
self.add_cmd_to_wf_task(new_activity(attrs), CommandID::Activity(seq).into());
|
|
839
916
|
}
|
|
840
917
|
WFCommand::AddLocalActivity(attrs) => {
|
|
841
918
|
let seq = attrs.seq;
|
|
@@ -863,10 +940,10 @@ impl WorkflowMachines {
|
|
|
863
940
|
self.process_machine_responses(machkey, mach_resp)?;
|
|
864
941
|
}
|
|
865
942
|
WFCommand::RequestCancelActivity(attrs) => {
|
|
866
|
-
|
|
943
|
+
self.process_cancellation(CommandID::Activity(attrs.seq))?;
|
|
867
944
|
}
|
|
868
945
|
WFCommand::RequestCancelLocalActivity(attrs) => {
|
|
869
|
-
|
|
946
|
+
self.process_cancellation(CommandID::LocalActivity(attrs.seq))?;
|
|
870
947
|
}
|
|
871
948
|
WFCommand::CompleteWorkflow(attrs) => {
|
|
872
949
|
self.metrics.wf_completed();
|
|
@@ -878,6 +955,7 @@ impl WorkflowMachines {
|
|
|
878
955
|
}
|
|
879
956
|
WFCommand::ContinueAsNew(attrs) => {
|
|
880
957
|
self.metrics.wf_continued_as_new();
|
|
958
|
+
let attrs = self.augment_continue_as_new_with_current_values(attrs);
|
|
881
959
|
self.add_terminal_command(continue_as_new(attrs));
|
|
882
960
|
}
|
|
883
961
|
WFCommand::CancelWorkflow(attrs) => {
|
|
@@ -892,7 +970,7 @@ impl WorkflowMachines {
|
|
|
892
970
|
{
|
|
893
971
|
self.add_cmd_to_wf_task(
|
|
894
972
|
has_change(attrs.patch_id.clone(), self.replaying, attrs.deprecated),
|
|
895
|
-
|
|
973
|
+
CommandIdKind::NeverResolves,
|
|
896
974
|
);
|
|
897
975
|
|
|
898
976
|
if let Some(ci) = self.encountered_change_markers.get_mut(&attrs.patch_id) {
|
|
@@ -911,12 +989,12 @@ impl WorkflowMachines {
|
|
|
911
989
|
let seq = attrs.seq;
|
|
912
990
|
self.add_cmd_to_wf_task(
|
|
913
991
|
new_child_workflow(attrs),
|
|
914
|
-
|
|
992
|
+
CommandID::ChildWorkflowStart(seq).into(),
|
|
915
993
|
);
|
|
916
994
|
}
|
|
917
|
-
WFCommand::
|
|
995
|
+
WFCommand::CancelChild(attrs) => self.process_cancellation(
|
|
918
996
|
CommandID::ChildWorkflowStart(attrs.child_workflow_seq),
|
|
919
|
-
)
|
|
997
|
+
)?,
|
|
920
998
|
WFCommand::RequestCancelExternalWorkflow(attrs) => {
|
|
921
999
|
let (we, only_child) = match attrs.target {
|
|
922
1000
|
None => {
|
|
@@ -942,18 +1020,18 @@ impl WorkflowMachines {
|
|
|
942
1020
|
only_child,
|
|
943
1021
|
format!("Cancel requested by workflow with run id {}", self.run_id),
|
|
944
1022
|
),
|
|
945
|
-
|
|
1023
|
+
CommandID::CancelExternal(attrs.seq).into(),
|
|
946
1024
|
);
|
|
947
1025
|
}
|
|
948
1026
|
WFCommand::SignalExternalWorkflow(attrs) => {
|
|
949
1027
|
let seq = attrs.seq;
|
|
950
1028
|
self.add_cmd_to_wf_task(
|
|
951
1029
|
new_external_signal(attrs, &self.namespace)?,
|
|
952
|
-
|
|
1030
|
+
CommandID::SignalExternal(seq).into(),
|
|
953
1031
|
);
|
|
954
1032
|
}
|
|
955
1033
|
WFCommand::CancelSignalWorkflow(attrs) => {
|
|
956
|
-
|
|
1034
|
+
self.process_cancellation(CommandID::SignalExternal(attrs.seq))?;
|
|
957
1035
|
}
|
|
958
1036
|
WFCommand::QueryResponse(_) => {
|
|
959
1037
|
// Nothing to do here, queries are handled above the machine level
|
|
@@ -962,80 +1040,18 @@ impl WorkflowMachines {
|
|
|
962
1040
|
WFCommand::NoCommandsFromLang => (),
|
|
963
1041
|
}
|
|
964
1042
|
}
|
|
965
|
-
Ok(
|
|
1043
|
+
Ok(())
|
|
966
1044
|
}
|
|
967
1045
|
|
|
968
1046
|
/// Given a command id to attempt to cancel, try to cancel it and return any jobs that should
|
|
969
1047
|
/// be included in the activation
|
|
970
|
-
fn process_cancellation(&mut self, id: CommandID) -> Result<
|
|
971
|
-
let mut jobs = vec![];
|
|
1048
|
+
fn process_cancellation(&mut self, id: CommandID) -> Result<()> {
|
|
972
1049
|
let m_key = self.get_machine_key(id)?;
|
|
973
|
-
let
|
|
1050
|
+
let mach = self.machine_mut(m_key);
|
|
1051
|
+
let machine_resps = mach.cancel()?;
|
|
974
1052
|
debug!(machine_responses = %machine_resps.display(), cmd_id = ?id,
|
|
975
1053
|
"Cancel request responses");
|
|
976
|
-
|
|
977
|
-
match r {
|
|
978
|
-
MachineResponse::IssueNewCommand(c) => {
|
|
979
|
-
self.current_wf_task_commands.push_back(CommandAndMachine {
|
|
980
|
-
command: MachineAssociatedCommand::Real(Box::new(c)),
|
|
981
|
-
machine: m_key,
|
|
982
|
-
});
|
|
983
|
-
}
|
|
984
|
-
MachineResponse::PushWFJob(j) => {
|
|
985
|
-
jobs.push(j);
|
|
986
|
-
}
|
|
987
|
-
MachineResponse::RequestCancelLocalActivity(seq) => {
|
|
988
|
-
// We might already know about the status from a pre-resolution. Apply it if so.
|
|
989
|
-
// We need to do this because otherwise we might need to perform additional
|
|
990
|
-
// activations during replay that didn't happen during execution, just like
|
|
991
|
-
// we sometimes pre-resolve activities when first requested.
|
|
992
|
-
if let Some(preres) = self.local_activity_data.take_preresolution(seq) {
|
|
993
|
-
if let Machines::LocalActivityMachine(lam) = self.machine_mut(m_key) {
|
|
994
|
-
let more_responses = lam.try_resolve_with_dat(preres)?;
|
|
995
|
-
self.process_machine_responses(m_key, more_responses)?;
|
|
996
|
-
} else {
|
|
997
|
-
panic!("A non local-activity machine returned a request cancel LA response");
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
// If it's in the request queue, just rip it out.
|
|
1001
|
-
else if let Some(removed_act) =
|
|
1002
|
-
self.local_activity_data.remove_from_queue(seq)
|
|
1003
|
-
{
|
|
1004
|
-
// We removed it. Notify the machine that the activity cancelled.
|
|
1005
|
-
if let Machines::LocalActivityMachine(lam) = self.machine_mut(m_key) {
|
|
1006
|
-
let more_responses = lam.try_resolve(
|
|
1007
|
-
LocalActivityExecutionResult::empty_cancel(),
|
|
1008
|
-
Duration::from_secs(0),
|
|
1009
|
-
removed_act.attempt,
|
|
1010
|
-
None,
|
|
1011
|
-
None,
|
|
1012
|
-
)?;
|
|
1013
|
-
self.process_machine_responses(m_key, more_responses)?;
|
|
1014
|
-
} else {
|
|
1015
|
-
panic!("A non local-activity machine returned a request cancel LA response");
|
|
1016
|
-
}
|
|
1017
|
-
} else {
|
|
1018
|
-
// Finally, if we know about the LA at all, it's currently running, so
|
|
1019
|
-
// queue the cancel request to be given to the LA manager.
|
|
1020
|
-
self.local_activity_data.enqueue_cancel(ExecutingLAId {
|
|
1021
|
-
run_id: self.run_id.clone(),
|
|
1022
|
-
seq_num: seq,
|
|
1023
|
-
});
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
1026
|
-
MachineResponse::AbandonLocalActivity(seq) => {
|
|
1027
|
-
self.local_activity_data.done_executing(seq);
|
|
1028
|
-
}
|
|
1029
|
-
MachineResponse::UpdateWFTime(None) => {}
|
|
1030
|
-
v => {
|
|
1031
|
-
return Err(WFMachinesError::Fatal(format!(
|
|
1032
|
-
"Unexpected machine response {:?} when cancelling {:?}",
|
|
1033
|
-
v, id
|
|
1034
|
-
)));
|
|
1035
|
-
}
|
|
1036
|
-
}
|
|
1037
|
-
}
|
|
1038
|
-
Ok(jobs)
|
|
1054
|
+
self.process_machine_resps_impl(m_key, machine_resps)
|
|
1039
1055
|
}
|
|
1040
1056
|
|
|
1041
1057
|
fn get_machine_key(&self, id: CommandID) -> Result<MachineKey> {
|
|
@@ -1051,11 +1067,14 @@ impl WorkflowMachines {
|
|
|
1051
1067
|
}
|
|
1052
1068
|
|
|
1053
1069
|
/// Add a new command/machines for that command to the current workflow task
|
|
1054
|
-
fn add_cmd_to_wf_task(&mut self, machine: NewMachineWithCommand, id:
|
|
1070
|
+
fn add_cmd_to_wf_task(&mut self, machine: NewMachineWithCommand, id: CommandIdKind) {
|
|
1055
1071
|
let mach = self.add_new_command_machine(machine);
|
|
1056
|
-
if let
|
|
1072
|
+
if let CommandIdKind::LangIssued(id) = id {
|
|
1057
1073
|
self.id_to_machine.insert(id, mach.machine);
|
|
1058
1074
|
}
|
|
1075
|
+
if matches!(id, CommandIdKind::CoreInternal) {
|
|
1076
|
+
self.machine_is_core_created.insert(mach.machine, ());
|
|
1077
|
+
}
|
|
1059
1078
|
self.current_wf_task_commands.push_back(mach);
|
|
1060
1079
|
}
|
|
1061
1080
|
|
|
@@ -1080,6 +1099,32 @@ impl WorkflowMachines {
|
|
|
1080
1099
|
.expect("Machine must exist")
|
|
1081
1100
|
.borrow_mut()
|
|
1082
1101
|
}
|
|
1102
|
+
|
|
1103
|
+
fn augment_continue_as_new_with_current_values(
|
|
1104
|
+
&self,
|
|
1105
|
+
mut attrs: ContinueAsNewWorkflowExecution,
|
|
1106
|
+
) -> ContinueAsNewWorkflowExecution {
|
|
1107
|
+
if let Some(started_info) = self.drive_me.get_started_info() {
|
|
1108
|
+
if attrs.memo.is_empty() {
|
|
1109
|
+
attrs.memo = started_info
|
|
1110
|
+
.memo
|
|
1111
|
+
.clone()
|
|
1112
|
+
.map(Into::into)
|
|
1113
|
+
.unwrap_or_default();
|
|
1114
|
+
}
|
|
1115
|
+
if attrs.search_attributes.is_empty() {
|
|
1116
|
+
attrs.search_attributes = started_info
|
|
1117
|
+
.search_attrs
|
|
1118
|
+
.clone()
|
|
1119
|
+
.map(Into::into)
|
|
1120
|
+
.unwrap_or_default();
|
|
1121
|
+
}
|
|
1122
|
+
if attrs.retry_policy.is_none() {
|
|
1123
|
+
attrs.retry_policy = started_info.retry_policy.clone();
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
attrs
|
|
1127
|
+
}
|
|
1083
1128
|
}
|
|
1084
1129
|
|
|
1085
1130
|
fn str_to_randomness_seed(run_id: &str) -> u64 {
|
|
@@ -1127,3 +1172,13 @@ fn change_marker_handling(
|
|
|
1127
1172
|
}
|
|
1128
1173
|
Ok(ChangeMarkerOutcome::Normal)
|
|
1129
1174
|
}
|
|
1175
|
+
|
|
1176
|
+
#[derive(derive_more::From)]
|
|
1177
|
+
enum CommandIdKind {
|
|
1178
|
+
/// A normal command, requested by lang
|
|
1179
|
+
LangIssued(CommandID),
|
|
1180
|
+
/// A command created internally
|
|
1181
|
+
CoreInternal,
|
|
1182
|
+
/// A command which is fire-and-forget (ex: Upsert search attribs)
|
|
1183
|
+
NeverResolves,
|
|
1184
|
+
}
|
|
@@ -499,7 +499,8 @@ enum RunActionOutcome {
|
|
|
499
499
|
AfterHeartbeatTimeout(Option<ActivationOrAuto>),
|
|
500
500
|
}
|
|
501
501
|
|
|
502
|
-
#[derive(
|
|
502
|
+
#[derive(derive_more::DebugCustom)]
|
|
503
|
+
#[debug(fmt = "RunUpdateErr({:?})", source)]
|
|
503
504
|
struct RunUpdateErr {
|
|
504
505
|
source: WFMachinesError,
|
|
505
506
|
complete_resp_chan: Option<oneshot::Sender<ActivationCompleteResult>>,
|