@temporalio/core-bridge 1.6.0 → 1.7.1
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 +520 -456
- package/lib/index.d.ts +8 -6
- package/lib/index.js.map +1 -1
- package/package.json +8 -3
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/releases/x86_64-apple-darwin/index.node +0 -0
- package/releases/x86_64-pc-windows-msvc/index.node +0 -0
- package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
- package/sdk-core/.buildkite/docker/Dockerfile +2 -2
- package/sdk-core/.buildkite/docker/docker-compose.yaml +1 -1
- package/sdk-core/.buildkite/pipeline.yml +1 -1
- package/sdk-core/.github/workflows/heavy.yml +1 -0
- package/sdk-core/README.md +13 -7
- package/sdk-core/client/src/lib.rs +27 -9
- package/sdk-core/client/src/metrics.rs +17 -8
- package/sdk-core/client/src/raw.rs +3 -3
- package/sdk-core/core/Cargo.toml +3 -4
- package/sdk-core/core/src/abstractions/take_cell.rs +28 -0
- package/sdk-core/core/src/abstractions.rs +197 -18
- package/sdk-core/core/src/core_tests/activity_tasks.rs +137 -45
- package/sdk-core/core/src/core_tests/child_workflows.rs +6 -5
- package/sdk-core/core/src/core_tests/determinism.rs +212 -2
- package/sdk-core/core/src/core_tests/local_activities.rs +183 -36
- package/sdk-core/core/src/core_tests/queries.rs +32 -14
- package/sdk-core/core/src/core_tests/workers.rs +8 -5
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +340 -51
- package/sdk-core/core/src/ephemeral_server/mod.rs +110 -8
- package/sdk-core/core/src/internal_flags.rs +141 -0
- package/sdk-core/core/src/lib.rs +14 -9
- package/sdk-core/core/src/replay/mod.rs +16 -27
- package/sdk-core/core/src/telemetry/metrics.rs +69 -35
- package/sdk-core/core/src/telemetry/mod.rs +38 -14
- package/sdk-core/core/src/telemetry/prometheus_server.rs +19 -13
- package/sdk-core/core/src/test_help/mod.rs +65 -13
- package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +119 -160
- package/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +89 -0
- package/sdk-core/core/src/worker/activities/local_activities.rs +122 -6
- package/sdk-core/core/src/worker/activities.rs +347 -173
- package/sdk-core/core/src/worker/client/mocks.rs +22 -2
- package/sdk-core/core/src/worker/client.rs +18 -2
- package/sdk-core/core/src/worker/mod.rs +137 -44
- package/sdk-core/core/src/worker/workflow/history_update.rs +132 -51
- package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +207 -166
- package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +6 -7
- package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +6 -7
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +157 -82
- package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +12 -12
- package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +6 -7
- package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +13 -15
- package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +170 -60
- package/sdk-core/core/src/worker/workflow/machines/mod.rs +24 -16
- package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +6 -8
- package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +320 -204
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +10 -13
- package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +15 -23
- package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +187 -46
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +237 -111
- package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +13 -13
- package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +10 -6
- package/sdk-core/core/src/worker/workflow/managed_run.rs +81 -62
- package/sdk-core/core/src/worker/workflow/mod.rs +341 -79
- package/sdk-core/core/src/worker/workflow/run_cache.rs +18 -11
- package/sdk-core/core/src/worker/workflow/wft_extraction.rs +15 -3
- package/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +2 -0
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +75 -52
- package/sdk-core/core-api/Cargo.toml +0 -1
- package/sdk-core/core-api/src/lib.rs +13 -7
- package/sdk-core/core-api/src/telemetry.rs +4 -6
- package/sdk-core/core-api/src/worker.rs +5 -0
- package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +80 -55
- package/sdk-core/fsm/rustfsm_trait/src/lib.rs +22 -68
- package/sdk-core/histories/ends_empty_wft_complete.bin +0 -0
- package/sdk-core/histories/old_change_marker_format.bin +0 -0
- package/sdk-core/protos/api_upstream/.github/CODEOWNERS +2 -1
- package/sdk-core/protos/api_upstream/Makefile +1 -1
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +5 -17
- package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +11 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +1 -6
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +6 -6
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +5 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +22 -6
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +48 -19
- package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +2 -0
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +3 -0
- package/sdk-core/protos/api_upstream/temporal/api/{enums/v1/interaction_type.proto → protocol/v1/message.proto} +29 -11
- package/sdk-core/protos/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +63 -0
- package/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +111 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +59 -28
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +2 -2
- package/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +7 -8
- package/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +10 -7
- package/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +19 -30
- package/sdk-core/protos/local/temporal/sdk/core/common/common.proto +1 -0
- package/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +1 -0
- package/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +8 -0
- package/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +65 -60
- package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +85 -84
- package/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +9 -3
- package/sdk-core/sdk/Cargo.toml +1 -1
- package/sdk-core/sdk/src/lib.rs +21 -5
- package/sdk-core/sdk/src/workflow_context/options.rs +7 -1
- package/sdk-core/sdk/src/workflow_context.rs +24 -17
- package/sdk-core/sdk/src/workflow_future.rs +9 -3
- package/sdk-core/sdk-core-protos/src/history_builder.rs +114 -89
- package/sdk-core/sdk-core-protos/src/history_info.rs +6 -1
- package/sdk-core/sdk-core-protos/src/lib.rs +205 -64
- package/sdk-core/test-utils/src/canned_histories.rs +106 -296
- package/sdk-core/test-utils/src/lib.rs +32 -5
- package/sdk-core/tests/heavy_tests.rs +10 -43
- package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +25 -3
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +5 -3
- package/sdk-core/tests/integ_tests/metrics_tests.rs +218 -16
- package/sdk-core/tests/integ_tests/polling_tests.rs +3 -8
- package/sdk-core/tests/integ_tests/queries_tests.rs +4 -2
- package/sdk-core/tests/integ_tests/visibility_tests.rs +34 -23
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +97 -81
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -0
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -0
- package/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +80 -3
- package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +5 -1
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +1 -0
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +25 -3
- package/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +2 -4
- package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +30 -0
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +64 -0
- package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -0
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +4 -0
- package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +3 -1
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +7 -2
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +6 -7
- package/sdk-core/tests/integ_tests/workflow_tests.rs +8 -8
- package/sdk-core/tests/main.rs +16 -25
- package/sdk-core/tests/runner.rs +11 -9
- package/src/conversions.rs +14 -8
- package/src/runtime.rs +9 -8
- package/ts/index.ts +8 -6
- package/sdk-core/protos/api_upstream/temporal/api/interaction/v1/message.proto +0 -87
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
mod local_acts;
|
|
2
2
|
|
|
3
3
|
use super::{
|
|
4
|
-
|
|
4
|
+
cancel_external_state_machine::new_external_cancel,
|
|
5
5
|
cancel_workflow_state_machine::cancel_workflow,
|
|
6
|
-
child_workflow_state_machine::new_child_workflow,
|
|
7
6
|
complete_workflow_state_machine::complete_workflow,
|
|
8
7
|
continue_as_new_workflow_state_machine::continue_as_new,
|
|
9
8
|
fail_workflow_state_machine::fail_workflow, local_activity_state_machine::new_local_activity,
|
|
@@ -14,14 +13,23 @@ use super::{
|
|
|
14
13
|
TemporalStateMachine,
|
|
15
14
|
};
|
|
16
15
|
use crate::{
|
|
16
|
+
internal_flags::InternalFlags,
|
|
17
17
|
protosext::{HistoryEventExt, ValidScheduleLA},
|
|
18
18
|
telemetry::{metrics::MetricsContext, VecDisplayer},
|
|
19
19
|
worker::{
|
|
20
20
|
workflow::{
|
|
21
21
|
history_update::NextWFT,
|
|
22
|
-
machines::
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
machines::{
|
|
23
|
+
activity_state_machine::ActivityMachine,
|
|
24
|
+
child_workflow_state_machine::ChildWorkflowMachine,
|
|
25
|
+
modify_workflow_properties_state_machine::modify_workflow_properties,
|
|
26
|
+
patch_state_machine::VERSION_SEARCH_ATTR_KEY,
|
|
27
|
+
upsert_search_attributes_state_machine::upsert_search_attrs_internal,
|
|
28
|
+
HistEventData,
|
|
29
|
+
},
|
|
30
|
+
CommandID, DrivenWorkflow, HistoryUpdate, InternalFlagsRef, LocalResolution,
|
|
31
|
+
OutgoingJob, RunBasics, WFCommand, WFMachinesError, WorkflowFetcher,
|
|
32
|
+
WorkflowStartedInfo,
|
|
25
33
|
},
|
|
26
34
|
ExecutingLAId, LocalActRequest, LocalActivityExecutionResult, LocalActivityResolution,
|
|
27
35
|
},
|
|
@@ -30,9 +38,11 @@ use siphasher::sip::SipHasher13;
|
|
|
30
38
|
use slotmap::{SlotMap, SparseSecondaryMap};
|
|
31
39
|
use std::{
|
|
32
40
|
borrow::{Borrow, BorrowMut},
|
|
41
|
+
cell::RefCell,
|
|
33
42
|
collections::{HashMap, VecDeque},
|
|
34
43
|
convert::TryInto,
|
|
35
44
|
hash::{Hash, Hasher},
|
|
45
|
+
rc::Rc,
|
|
36
46
|
time::{Duration, Instant, SystemTime},
|
|
37
47
|
};
|
|
38
48
|
use temporal_sdk_core_protos::{
|
|
@@ -49,7 +59,8 @@ use temporal_sdk_core_protos::{
|
|
|
49
59
|
temporal::api::{
|
|
50
60
|
command::v1::{command::Attributes as ProtoCmdAttrs, Command as ProtoCommand},
|
|
51
61
|
enums::v1::EventType,
|
|
52
|
-
history::v1::{history_event, HistoryEvent},
|
|
62
|
+
history::v1::{history_event, history_event::Attributes, HistoryEvent},
|
|
63
|
+
sdk::v1::WorkflowTaskCompletedMetadata,
|
|
53
64
|
},
|
|
54
65
|
};
|
|
55
66
|
|
|
@@ -94,6 +105,9 @@ pub(crate) struct WorkflowMachines {
|
|
|
94
105
|
/// The current workflow time if it has been established. This may differ from the WFT start
|
|
95
106
|
/// time since local activities may advance the clock
|
|
96
107
|
current_wf_time: Option<SystemTime>,
|
|
108
|
+
/// The internal flags which have been seen so far during this run's execution and thus are
|
|
109
|
+
/// usable during replay.
|
|
110
|
+
observed_internal_flags: InternalFlagsRef,
|
|
97
111
|
|
|
98
112
|
all_machines: SlotMap<MachineKey, Machines>,
|
|
99
113
|
/// If a machine key is in this map, that machine was created internally by core, not as a
|
|
@@ -202,25 +216,22 @@ where
|
|
|
202
216
|
}
|
|
203
217
|
|
|
204
218
|
impl WorkflowMachines {
|
|
205
|
-
pub(crate) fn new(
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
metrics: MetricsContext,
|
|
213
|
-
) -> Self {
|
|
214
|
-
let replaying = history.previous_wft_started_id > 0;
|
|
219
|
+
pub(crate) fn new(basics: RunBasics, driven_wf: DrivenWorkflow) -> Self {
|
|
220
|
+
let replaying = basics.history.previous_wft_started_id > 0;
|
|
221
|
+
let mut observed_internal_flags = InternalFlags::new(basics.capabilities);
|
|
222
|
+
// Peek ahead to determine used patches in the first WFT.
|
|
223
|
+
if let Some(attrs) = basics.history.peek_next_wft_completed(0) {
|
|
224
|
+
observed_internal_flags.add_from_complete(attrs);
|
|
225
|
+
};
|
|
215
226
|
Self {
|
|
216
|
-
last_history_from_server: history,
|
|
217
|
-
namespace,
|
|
218
|
-
workflow_id,
|
|
219
|
-
workflow_type,
|
|
220
|
-
run_id,
|
|
227
|
+
last_history_from_server: basics.history,
|
|
228
|
+
namespace: basics.namespace,
|
|
229
|
+
workflow_id: basics.workflow_id,
|
|
230
|
+
workflow_type: basics.workflow_type,
|
|
231
|
+
run_id: basics.run_id,
|
|
221
232
|
drive_me: driven_wf,
|
|
222
233
|
replaying,
|
|
223
|
-
metrics,
|
|
234
|
+
metrics: basics.metrics,
|
|
224
235
|
// In an ideal world one could say ..Default::default() here and it'd still work.
|
|
225
236
|
current_started_event_id: 0,
|
|
226
237
|
next_started_event_id: 0,
|
|
@@ -229,6 +240,7 @@ impl WorkflowMachines {
|
|
|
229
240
|
workflow_end_time: None,
|
|
230
241
|
wft_start_time: None,
|
|
231
242
|
current_wf_time: None,
|
|
243
|
+
observed_internal_flags: Rc::new(RefCell::new(observed_internal_flags)),
|
|
232
244
|
all_machines: Default::default(),
|
|
233
245
|
machine_is_core_created: Default::default(),
|
|
234
246
|
machines_by_event_id: Default::default(),
|
|
@@ -348,6 +360,12 @@ impl WorkflowMachines {
|
|
|
348
360
|
run_id: self.run_id.clone(),
|
|
349
361
|
history_length: self.last_processed_event as u32,
|
|
350
362
|
jobs,
|
|
363
|
+
available_internal_flags: (*self.observed_internal_flags)
|
|
364
|
+
.borrow()
|
|
365
|
+
.all_lang()
|
|
366
|
+
.iter()
|
|
367
|
+
.copied()
|
|
368
|
+
.collect(),
|
|
351
369
|
}
|
|
352
370
|
}
|
|
353
371
|
|
|
@@ -362,6 +380,18 @@ impl WorkflowMachines {
|
|
|
362
380
|
.any(|v| v.is_la_resolution)
|
|
363
381
|
}
|
|
364
382
|
|
|
383
|
+
pub(crate) fn get_metadata_for_wft_complete(&self) -> WorkflowTaskCompletedMetadata {
|
|
384
|
+
(*self.observed_internal_flags)
|
|
385
|
+
.borrow_mut()
|
|
386
|
+
.gather_for_wft_complete()
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
pub(crate) fn add_lang_used_flags(&self, flags: Vec<u32>) {
|
|
390
|
+
(*self.observed_internal_flags)
|
|
391
|
+
.borrow_mut()
|
|
392
|
+
.add_lang_used(flags);
|
|
393
|
+
}
|
|
394
|
+
|
|
365
395
|
/// Iterate the state machines, which consists of grabbing any pending outgoing commands from
|
|
366
396
|
/// the workflow code, handling them, and preparing them to be sent off to the server.
|
|
367
397
|
pub(crate) fn iterate_machines(&mut self) -> Result<()> {
|
|
@@ -390,29 +420,47 @@ impl WorkflowMachines {
|
|
|
390
420
|
// then we don't need to do anything here, and in fact we need to avoid re-applying the
|
|
391
421
|
// final WFT.
|
|
392
422
|
if self.have_seen_terminal_event {
|
|
423
|
+
// Replay clearly counts as done now, since we return here and never do anything else.
|
|
424
|
+
self.replaying = false;
|
|
393
425
|
return Ok(0);
|
|
394
426
|
}
|
|
395
427
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
428
|
+
fn update_internal_flags(me: &mut WorkflowMachines) {
|
|
429
|
+
// Update observed patches with any that were used in the task
|
|
430
|
+
if let Some(next_complete) = me
|
|
399
431
|
.last_history_from_server
|
|
400
|
-
.
|
|
432
|
+
.peek_next_wft_completed(me.last_processed_event)
|
|
401
433
|
{
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
434
|
+
(*me.observed_internal_flags)
|
|
435
|
+
.borrow_mut()
|
|
436
|
+
.add_from_complete(next_complete);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// We update the internal flags before applying the current task (peeking to the completion
|
|
441
|
+
// of this task), and also at the end (peeking to the completion of the task that lang is
|
|
442
|
+
// about to generate commands for, and for which we will want those flags active).
|
|
443
|
+
update_internal_flags(self);
|
|
444
|
+
|
|
445
|
+
let last_handled_wft_started_id = self.current_started_event_id;
|
|
446
|
+
let (events, has_final_event) = match self
|
|
447
|
+
.last_history_from_server
|
|
448
|
+
.take_next_wft_sequence(last_handled_wft_started_id)
|
|
449
|
+
{
|
|
450
|
+
NextWFT::ReplayOver => (vec![], true),
|
|
451
|
+
NextWFT::WFT(mut evts, has_final_event) => {
|
|
452
|
+
// Do not re-process events we have already processed
|
|
453
|
+
evts.retain(|e| e.event_id > self.last_processed_event);
|
|
454
|
+
(evts, has_final_event)
|
|
455
|
+
}
|
|
456
|
+
NextWFT::NeedFetch => {
|
|
457
|
+
return Err(WFMachinesError::Fatal(
|
|
411
458
|
"Need to fetch history events to continue applying workflow task, but this \
|
|
412
459
|
should be prevented ahead of time! This is a Core SDK bug."
|
|
413
460
|
.to_string(),
|
|
414
|
-
))
|
|
415
|
-
}
|
|
461
|
+
));
|
|
462
|
+
}
|
|
463
|
+
};
|
|
416
464
|
let num_events_to_process = events.len();
|
|
417
465
|
|
|
418
466
|
// We're caught up on reply if there are no new events to process
|
|
@@ -427,6 +475,8 @@ impl WorkflowMachines {
|
|
|
427
475
|
}
|
|
428
476
|
}
|
|
429
477
|
|
|
478
|
+
let mut saw_completed = false;
|
|
479
|
+
let mut do_handle_event = true;
|
|
430
480
|
let mut history = events.into_iter().peekable();
|
|
431
481
|
while let Some(event) = history.next() {
|
|
432
482
|
if event.event_id != self.last_processed_event + 1 {
|
|
@@ -437,12 +487,43 @@ impl WorkflowMachines {
|
|
|
437
487
|
}
|
|
438
488
|
let next_event = history.peek();
|
|
439
489
|
let eid = event.event_id;
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
490
|
+
|
|
491
|
+
// This definition of replaying here is that we are no longer replaying as soon as we
|
|
492
|
+
// see new events that have never been seen or produced by the SDK.
|
|
493
|
+
//
|
|
494
|
+
// Specifically, replay ends once we have seen the last command-event which was produced
|
|
495
|
+
// as a result of the last completed WFT. Thus, replay would be false for things like
|
|
496
|
+
// signals which were received and after the last completion, and thus generated the
|
|
497
|
+
// current WFT being handled.
|
|
498
|
+
if self.replaying && has_final_event && saw_completed && !event.is_command_event() {
|
|
499
|
+
// Replay is finished
|
|
500
|
+
self.replaying = false;
|
|
445
501
|
}
|
|
502
|
+
if event.event_type() == EventType::WorkflowTaskCompleted {
|
|
503
|
+
saw_completed = true;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
if do_handle_event {
|
|
507
|
+
let eho = self.handle_event(
|
|
508
|
+
HistEventData {
|
|
509
|
+
event,
|
|
510
|
+
replaying: self.replaying,
|
|
511
|
+
current_task_is_last_in_history: has_final_event,
|
|
512
|
+
},
|
|
513
|
+
next_event,
|
|
514
|
+
)?;
|
|
515
|
+
if matches!(
|
|
516
|
+
eho,
|
|
517
|
+
EventHandlingOutcome::SkipEvent {
|
|
518
|
+
skip_next_event: true
|
|
519
|
+
}
|
|
520
|
+
) {
|
|
521
|
+
do_handle_event = false;
|
|
522
|
+
}
|
|
523
|
+
} else {
|
|
524
|
+
do_handle_event = true;
|
|
525
|
+
}
|
|
526
|
+
self.last_processed_event = eid;
|
|
446
527
|
}
|
|
447
528
|
|
|
448
529
|
// Scan through to the next WFT, searching for any patch / la markers, so that we can
|
|
@@ -492,6 +573,8 @@ impl WorkflowMachines {
|
|
|
492
573
|
}
|
|
493
574
|
}
|
|
494
575
|
|
|
576
|
+
update_internal_flags(self);
|
|
577
|
+
|
|
495
578
|
if !self.replaying {
|
|
496
579
|
self.metrics.wf_task_replay_latency(replay_start.elapsed());
|
|
497
580
|
}
|
|
@@ -499,16 +582,20 @@ impl WorkflowMachines {
|
|
|
499
582
|
Ok(num_events_to_process)
|
|
500
583
|
}
|
|
501
584
|
|
|
502
|
-
/// Handle a single event from the workflow history.
|
|
503
|
-
/// is the last event in the history.
|
|
585
|
+
/// Handle a single event from the workflow history.
|
|
504
586
|
///
|
|
505
587
|
/// This function will attempt to apply the event to the workflow state machines. If there is
|
|
506
588
|
/// not a matching machine for the event, a nondeterminism error is returned. Otherwise, the
|
|
507
589
|
/// event is applied to the machine, which may also return a nondeterminism error if the machine
|
|
508
590
|
/// does not match the expected type. A fatal error may be returned if the machine is in an
|
|
509
591
|
/// invalid state.
|
|
510
|
-
#[instrument(skip(self,
|
|
511
|
-
fn handle_event(
|
|
592
|
+
#[instrument(skip(self, event_dat), fields(event=%event_dat))]
|
|
593
|
+
fn handle_event(
|
|
594
|
+
&mut self,
|
|
595
|
+
event_dat: HistEventData,
|
|
596
|
+
next_event: Option<&HistoryEvent>,
|
|
597
|
+
) -> Result<EventHandlingOutcome> {
|
|
598
|
+
let event = &event_dat.event;
|
|
512
599
|
if event.is_final_wf_execution_event() {
|
|
513
600
|
self.have_seen_terminal_event = true;
|
|
514
601
|
}
|
|
@@ -516,24 +603,18 @@ impl WorkflowMachines {
|
|
|
516
603
|
event.event_type(),
|
|
517
604
|
EventType::WorkflowExecutionTerminated | EventType::WorkflowExecutionTimedOut
|
|
518
605
|
) {
|
|
519
|
-
|
|
606
|
+
let are_more_events =
|
|
607
|
+
next_event.is_some() || !event_dat.current_task_is_last_in_history;
|
|
608
|
+
return if are_more_events {
|
|
520
609
|
Err(WFMachinesError::Fatal(
|
|
521
610
|
"Machines were fed a history which has an event after workflow execution was \
|
|
522
611
|
terminated!"
|
|
523
612
|
.to_string(),
|
|
524
613
|
))
|
|
525
614
|
} else {
|
|
526
|
-
Ok(
|
|
615
|
+
Ok(EventHandlingOutcome::Normal)
|
|
527
616
|
};
|
|
528
617
|
}
|
|
529
|
-
if self.replaying
|
|
530
|
-
&& self.current_started_event_id
|
|
531
|
-
>= self.last_history_from_server.previous_wft_started_id
|
|
532
|
-
&& event.event_type() != EventType::WorkflowTaskCompleted
|
|
533
|
-
{
|
|
534
|
-
// Replay is finished
|
|
535
|
-
self.replaying = false;
|
|
536
|
-
}
|
|
537
618
|
if event.event_type() == EventType::Unspecified || event.attributes.is_none() {
|
|
538
619
|
return if !event.worker_may_ignore {
|
|
539
620
|
Err(WFMachinesError::Fatal(format!(
|
|
@@ -541,13 +622,14 @@ impl WorkflowMachines {
|
|
|
541
622
|
)))
|
|
542
623
|
} else {
|
|
543
624
|
debug!("Event is ignorable");
|
|
544
|
-
Ok(
|
|
625
|
+
Ok(EventHandlingOutcome::SkipEvent {
|
|
626
|
+
skip_next_event: false,
|
|
627
|
+
})
|
|
545
628
|
};
|
|
546
629
|
}
|
|
547
630
|
|
|
548
631
|
if event.is_command_event() {
|
|
549
|
-
self.handle_command_event(
|
|
550
|
-
return Ok(());
|
|
632
|
+
return self.handle_command_event(event_dat, next_event);
|
|
551
633
|
}
|
|
552
634
|
|
|
553
635
|
if let Some(initial_cmd_id) = event.get_initial_command_event_id() {
|
|
@@ -556,7 +638,7 @@ impl WorkflowMachines {
|
|
|
556
638
|
let maybe_machine = self.machines_by_event_id.remove(&initial_cmd_id);
|
|
557
639
|
match maybe_machine {
|
|
558
640
|
Some(sm) => {
|
|
559
|
-
self.submachine_handle_event(sm,
|
|
641
|
+
self.submachine_handle_event(sm, event_dat)?;
|
|
560
642
|
// Restore machine if not in it's final state
|
|
561
643
|
if !self.machine(sm).is_final_state() {
|
|
562
644
|
self.machines_by_event_id.insert(initial_cmd_id, sm);
|
|
@@ -570,10 +652,10 @@ impl WorkflowMachines {
|
|
|
570
652
|
}
|
|
571
653
|
}
|
|
572
654
|
} else {
|
|
573
|
-
self.handle_non_stateful_event(
|
|
655
|
+
self.handle_non_stateful_event(event_dat)?;
|
|
574
656
|
}
|
|
575
657
|
|
|
576
|
-
Ok(
|
|
658
|
+
Ok(EventHandlingOutcome::Normal)
|
|
577
659
|
}
|
|
578
660
|
|
|
579
661
|
/// A command event is an event which is generated from a command emitted as a result of
|
|
@@ -585,7 +667,13 @@ impl WorkflowMachines {
|
|
|
585
667
|
/// The handling consists of verifying that the next command in the commands queue is associated
|
|
586
668
|
/// with a state machine, which is then notified about the event and the command is removed from
|
|
587
669
|
/// the commands queue.
|
|
588
|
-
fn handle_command_event(
|
|
670
|
+
fn handle_command_event(
|
|
671
|
+
&mut self,
|
|
672
|
+
event_dat: HistEventData,
|
|
673
|
+
next_event: Option<&HistoryEvent>,
|
|
674
|
+
) -> Result<EventHandlingOutcome> {
|
|
675
|
+
let event = &event_dat.event;
|
|
676
|
+
|
|
589
677
|
if event.is_local_activity_marker() {
|
|
590
678
|
let deets = event.extract_local_activity_marker_data().ok_or_else(|| {
|
|
591
679
|
WFMachinesError::Fatal(format!("Local activity marker was unparsable: {event:?}"))
|
|
@@ -594,8 +682,8 @@ impl WorkflowMachines {
|
|
|
594
682
|
let mkey = self.get_machine_key(cmdid)?;
|
|
595
683
|
if let Machines::LocalActivityMachine(lam) = self.machine(mkey) {
|
|
596
684
|
if lam.marker_should_get_special_handling()? {
|
|
597
|
-
self.submachine_handle_event(mkey,
|
|
598
|
-
return Ok(
|
|
685
|
+
self.submachine_handle_event(mkey, event_dat)?;
|
|
686
|
+
return Ok(EventHandlingOutcome::Normal);
|
|
599
687
|
}
|
|
600
688
|
} else {
|
|
601
689
|
return Err(WFMachinesError::Fatal(format!(
|
|
@@ -610,13 +698,13 @@ impl WorkflowMachines {
|
|
|
610
698
|
let consumed_cmd = loop {
|
|
611
699
|
if let Some(peek_machine) = self.commands.front() {
|
|
612
700
|
let mach = self.machine(peek_machine.machine);
|
|
613
|
-
match change_marker_handling(
|
|
614
|
-
|
|
615
|
-
ChangeMarkerOutcome::SkipCommand => {
|
|
701
|
+
match change_marker_handling(event, mach, next_event)? {
|
|
702
|
+
EventHandlingOutcome::SkipCommand => {
|
|
616
703
|
self.commands.pop_front();
|
|
617
704
|
continue;
|
|
618
705
|
}
|
|
619
|
-
|
|
706
|
+
eho @ EventHandlingOutcome::SkipEvent { .. } => return Ok(eho),
|
|
707
|
+
EventHandlingOutcome::Normal => {}
|
|
620
708
|
}
|
|
621
709
|
}
|
|
622
710
|
|
|
@@ -635,7 +723,7 @@ impl WorkflowMachines {
|
|
|
635
723
|
|
|
636
724
|
if !canceled_before_sent {
|
|
637
725
|
// Feed the machine the event
|
|
638
|
-
self.submachine_handle_event(command.machine,
|
|
726
|
+
self.submachine_handle_event(command.machine, event_dat)?;
|
|
639
727
|
break command;
|
|
640
728
|
}
|
|
641
729
|
};
|
|
@@ -645,26 +733,22 @@ impl WorkflowMachines {
|
|
|
645
733
|
.insert(event_id, consumed_cmd.machine);
|
|
646
734
|
}
|
|
647
735
|
|
|
648
|
-
Ok(
|
|
736
|
+
Ok(EventHandlingOutcome::Normal)
|
|
649
737
|
}
|
|
650
738
|
|
|
651
|
-
fn handle_non_stateful_event(
|
|
652
|
-
&mut self,
|
|
653
|
-
event: HistoryEvent,
|
|
654
|
-
has_next_event: bool,
|
|
655
|
-
) -> Result<()> {
|
|
739
|
+
fn handle_non_stateful_event(&mut self, event_dat: HistEventData) -> Result<()> {
|
|
656
740
|
trace!(
|
|
657
|
-
event = %event,
|
|
741
|
+
event = %event_dat.event,
|
|
658
742
|
"handling non-stateful event"
|
|
659
743
|
);
|
|
660
|
-
let event_id = event.event_id;
|
|
661
|
-
match EventType::from_i32(event.event_type) {
|
|
744
|
+
let event_id = event_dat.event.event_id;
|
|
745
|
+
match EventType::from_i32(event_dat.event.event_type) {
|
|
662
746
|
Some(EventType::WorkflowExecutionStarted) => {
|
|
663
747
|
if let Some(history_event::Attributes::WorkflowExecutionStartedEventAttributes(
|
|
664
748
|
attrs,
|
|
665
|
-
)) = event.attributes
|
|
749
|
+
)) = event_dat.event.attributes
|
|
666
750
|
{
|
|
667
|
-
if let Some(st) = event.event_time.clone() {
|
|
751
|
+
if let Some(st) = event_dat.event.event_time.clone() {
|
|
668
752
|
let as_systime: SystemTime = st.try_into()?;
|
|
669
753
|
self.workflow_start_time = Some(as_systime);
|
|
670
754
|
// Set the workflow time to be the event time of the first event, so that
|
|
@@ -676,25 +760,25 @@ impl WorkflowMachines {
|
|
|
676
760
|
self.drive_me.start(
|
|
677
761
|
self.workflow_id.clone(),
|
|
678
762
|
str_to_randomness_seed(&attrs.original_execution_run_id),
|
|
679
|
-
event.event_time.unwrap_or_default(),
|
|
763
|
+
event_dat.event.event_time.unwrap_or_default(),
|
|
680
764
|
attrs,
|
|
681
765
|
);
|
|
682
766
|
} else {
|
|
683
767
|
return Err(WFMachinesError::Fatal(format!(
|
|
684
|
-
"WorkflowExecutionStarted event did not have appropriate attributes: {
|
|
768
|
+
"WorkflowExecutionStarted event did not have appropriate attributes: {event_dat}"
|
|
685
769
|
)));
|
|
686
770
|
}
|
|
687
771
|
}
|
|
688
772
|
Some(EventType::WorkflowTaskScheduled) => {
|
|
689
773
|
let wf_task_sm = WorkflowTaskMachine::new(self.next_started_event_id);
|
|
690
774
|
let key = self.all_machines.insert(wf_task_sm.into());
|
|
691
|
-
self.submachine_handle_event(key,
|
|
775
|
+
self.submachine_handle_event(key, event_dat)?;
|
|
692
776
|
self.machines_by_event_id.insert(event_id, key);
|
|
693
777
|
}
|
|
694
778
|
Some(EventType::WorkflowExecutionSignaled) => {
|
|
695
779
|
if let Some(history_event::Attributes::WorkflowExecutionSignaledEventAttributes(
|
|
696
780
|
attrs,
|
|
697
|
-
)) = event.attributes
|
|
781
|
+
)) = event_dat.event.attributes
|
|
698
782
|
{
|
|
699
783
|
self.drive_me
|
|
700
784
|
.send_job(workflow_activation::SignalWorkflow::from(attrs).into());
|
|
@@ -707,7 +791,7 @@ impl WorkflowMachines {
|
|
|
707
791
|
history_event::Attributes::WorkflowExecutionCancelRequestedEventAttributes(
|
|
708
792
|
attrs,
|
|
709
793
|
),
|
|
710
|
-
) = event.attributes
|
|
794
|
+
) = event_dat.event.attributes
|
|
711
795
|
{
|
|
712
796
|
self.drive_me
|
|
713
797
|
.send_job(workflow_activation::CancelWorkflow::from(attrs).into());
|
|
@@ -717,7 +801,7 @@ impl WorkflowMachines {
|
|
|
717
801
|
}
|
|
718
802
|
_ => {
|
|
719
803
|
return Err(WFMachinesError::Fatal(format!(
|
|
720
|
-
"The event is not a non-stateful event, but we tried to handle it as one: {
|
|
804
|
+
"The event is not a non-stateful event, but we tried to handle it as one: {event_dat}"
|
|
721
805
|
)));
|
|
722
806
|
}
|
|
723
807
|
}
|
|
@@ -734,13 +818,8 @@ impl WorkflowMachines {
|
|
|
734
818
|
|
|
735
819
|
/// Wrapper for calling [TemporalStateMachine::handle_event] which appropriately takes action
|
|
736
820
|
/// on the returned machine responses
|
|
737
|
-
fn submachine_handle_event(
|
|
738
|
-
|
|
739
|
-
sm: MachineKey,
|
|
740
|
-
event: HistoryEvent,
|
|
741
|
-
has_next_event: bool,
|
|
742
|
-
) -> Result<()> {
|
|
743
|
-
let machine_responses = self.machine_mut(sm).handle_event(event, has_next_event)?;
|
|
821
|
+
fn submachine_handle_event(&mut self, sm: MachineKey, event: HistEventData) -> Result<()> {
|
|
822
|
+
let machine_responses = self.machine_mut(sm).handle_event(event)?;
|
|
744
823
|
self.process_machine_responses(sm, machine_responses)?;
|
|
745
824
|
Ok(())
|
|
746
825
|
}
|
|
@@ -843,6 +922,12 @@ impl WorkflowMachines {
|
|
|
843
922
|
CommandIdKind::CoreInternal,
|
|
844
923
|
);
|
|
845
924
|
}
|
|
925
|
+
ProtoCmdAttrs::UpsertWorkflowSearchAttributesCommandAttributes(attrs) => {
|
|
926
|
+
self.add_cmd_to_wf_task(
|
|
927
|
+
upsert_search_attrs_internal(attrs),
|
|
928
|
+
CommandIdKind::NeverResolves,
|
|
929
|
+
);
|
|
930
|
+
}
|
|
846
931
|
c => {
|
|
847
932
|
return Err(WFMachinesError::Fatal(format!(
|
|
848
933
|
"A machine requested to create a new command of an unsupported type: {c:?}"
|
|
@@ -949,7 +1034,11 @@ impl WorkflowMachines {
|
|
|
949
1034
|
}
|
|
950
1035
|
WFCommand::UpsertSearchAttributes(attrs) => {
|
|
951
1036
|
self.add_cmd_to_wf_task(
|
|
952
|
-
upsert_search_attrs(
|
|
1037
|
+
upsert_search_attrs(
|
|
1038
|
+
attrs,
|
|
1039
|
+
self.observed_internal_flags.clone(),
|
|
1040
|
+
self.replaying,
|
|
1041
|
+
),
|
|
953
1042
|
CommandIdKind::NeverResolves,
|
|
954
1043
|
);
|
|
955
1044
|
}
|
|
@@ -958,7 +1047,10 @@ impl WorkflowMachines {
|
|
|
958
1047
|
}
|
|
959
1048
|
WFCommand::AddActivity(attrs) => {
|
|
960
1049
|
let seq = attrs.seq;
|
|
961
|
-
self.add_cmd_to_wf_task(
|
|
1050
|
+
self.add_cmd_to_wf_task(
|
|
1051
|
+
ActivityMachine::new_scheduled(attrs, self.observed_internal_flags.clone()),
|
|
1052
|
+
CommandID::Activity(seq).into(),
|
|
1053
|
+
);
|
|
962
1054
|
}
|
|
963
1055
|
WFCommand::AddLocalActivity(attrs) => {
|
|
964
1056
|
let seq = attrs.seq;
|
|
@@ -978,6 +1070,7 @@ impl WorkflowMachines {
|
|
|
978
1070
|
self.replaying,
|
|
979
1071
|
self.local_activity_data.take_preresolution(seq),
|
|
980
1072
|
self.current_wf_time,
|
|
1073
|
+
self.observed_internal_flags.clone(),
|
|
981
1074
|
)?;
|
|
982
1075
|
let machkey = self.all_machines.insert(la.into());
|
|
983
1076
|
self.id_to_machine
|
|
@@ -1010,13 +1103,21 @@ impl WorkflowMachines {
|
|
|
1010
1103
|
WFCommand::SetPatchMarker(attrs) => {
|
|
1011
1104
|
// Do not create commands for change IDs that we have already created commands
|
|
1012
1105
|
// for.
|
|
1013
|
-
|
|
1106
|
+
let encountered_entry = self.encountered_change_markers.get(&attrs.patch_id);
|
|
1107
|
+
if !matches!(encountered_entry,
|
|
1014
1108
|
Some(ChangeInfo {created_command}) if *created_command)
|
|
1015
1109
|
{
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1110
|
+
let (patch_machine, other_cmds) = has_change(
|
|
1111
|
+
attrs.patch_id.clone(),
|
|
1112
|
+
self.replaying,
|
|
1113
|
+
attrs.deprecated,
|
|
1114
|
+
encountered_entry.is_some(),
|
|
1115
|
+
self.encountered_change_markers.keys().map(|s| s.as_str()),
|
|
1116
|
+
self.observed_internal_flags.clone(),
|
|
1117
|
+
)?;
|
|
1118
|
+
let mkey =
|
|
1119
|
+
self.add_cmd_to_wf_task(patch_machine, CommandIdKind::NeverResolves);
|
|
1120
|
+
self.process_machine_responses(mkey, other_cmds)?;
|
|
1020
1121
|
|
|
1021
1122
|
if let Some(ci) = self.encountered_change_markers.get_mut(&attrs.patch_id) {
|
|
1022
1123
|
ci.created_command = true;
|
|
@@ -1033,7 +1134,10 @@ impl WorkflowMachines {
|
|
|
1033
1134
|
WFCommand::AddChildWorkflow(attrs) => {
|
|
1034
1135
|
let seq = attrs.seq;
|
|
1035
1136
|
self.add_cmd_to_wf_task(
|
|
1036
|
-
|
|
1137
|
+
ChildWorkflowMachine::new_scheduled(
|
|
1138
|
+
attrs,
|
|
1139
|
+
self.observed_internal_flags.clone(),
|
|
1140
|
+
),
|
|
1037
1141
|
CommandID::ChildWorkflowStart(seq).into(),
|
|
1038
1142
|
);
|
|
1039
1143
|
}
|
|
@@ -1118,15 +1222,21 @@ impl WorkflowMachines {
|
|
|
1118
1222
|
}
|
|
1119
1223
|
|
|
1120
1224
|
/// Add a new command/machines for that command to the current workflow task
|
|
1121
|
-
fn add_cmd_to_wf_task(
|
|
1225
|
+
fn add_cmd_to_wf_task(
|
|
1226
|
+
&mut self,
|
|
1227
|
+
machine: NewMachineWithCommand,
|
|
1228
|
+
id: CommandIdKind,
|
|
1229
|
+
) -> MachineKey {
|
|
1122
1230
|
let mach = self.add_new_command_machine(machine);
|
|
1231
|
+
let key = mach.machine;
|
|
1123
1232
|
if let CommandIdKind::LangIssued(id) = id {
|
|
1124
|
-
self.id_to_machine.insert(id,
|
|
1233
|
+
self.id_to_machine.insert(id, key);
|
|
1125
1234
|
}
|
|
1126
1235
|
if matches!(id, CommandIdKind::CoreInternal) {
|
|
1127
|
-
self.machine_is_core_created.insert(
|
|
1236
|
+
self.machine_is_core_created.insert(key, ());
|
|
1128
1237
|
}
|
|
1129
1238
|
self.current_wf_task_commands.push_back(mach);
|
|
1239
|
+
key
|
|
1130
1240
|
}
|
|
1131
1241
|
|
|
1132
1242
|
fn add_new_command_machine(&mut self, machine: NewMachineWithCommand) -> CommandAndMachine {
|
|
@@ -1186,15 +1296,20 @@ fn str_to_randomness_seed(run_id: &str) -> u64 {
|
|
|
1186
1296
|
s.finish()
|
|
1187
1297
|
}
|
|
1188
1298
|
|
|
1189
|
-
|
|
1190
|
-
|
|
1299
|
+
#[must_use]
|
|
1300
|
+
enum EventHandlingOutcome {
|
|
1301
|
+
SkipEvent { skip_next_event: bool },
|
|
1191
1302
|
SkipCommand,
|
|
1192
1303
|
Normal,
|
|
1193
1304
|
}
|
|
1194
1305
|
|
|
1195
1306
|
/// Special handling for patch markers, when handling command events as in
|
|
1196
1307
|
/// [WorkflowMachines::handle_command_event]
|
|
1197
|
-
fn change_marker_handling(
|
|
1308
|
+
fn change_marker_handling(
|
|
1309
|
+
event: &HistoryEvent,
|
|
1310
|
+
mach: &Machines,
|
|
1311
|
+
next_event: Option<&HistoryEvent>,
|
|
1312
|
+
) -> Result<EventHandlingOutcome> {
|
|
1198
1313
|
if !mach.matches_event(event) {
|
|
1199
1314
|
// Version markers can be skipped in the event they are deprecated
|
|
1200
1315
|
if let Some((patch_name, deprecated)) = event.get_patch_marker_details() {
|
|
@@ -1202,7 +1317,18 @@ fn change_marker_handling(event: &HistoryEvent, mach: &Machines) -> Result<Chang
|
|
|
1202
1317
|
// markers are allowed without matching changed calls.
|
|
1203
1318
|
if deprecated {
|
|
1204
1319
|
debug!("Deprecated patch marker tried against wrong machine, skipping.");
|
|
1205
|
-
|
|
1320
|
+
|
|
1321
|
+
// Also ignore the subsequent upsert event if present
|
|
1322
|
+
let mut skip_next_event = false;
|
|
1323
|
+
if let Some(Attributes::UpsertWorkflowSearchAttributesEventAttributes(atts)) =
|
|
1324
|
+
next_event.and_then(|ne| ne.attributes.as_ref())
|
|
1325
|
+
{
|
|
1326
|
+
if let Some(ref sa) = atts.search_attributes {
|
|
1327
|
+
skip_next_event = sa.indexed_fields.contains_key(VERSION_SEARCH_ATTR_KEY);
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
return Ok(EventHandlingOutcome::SkipEvent { skip_next_event });
|
|
1206
1332
|
}
|
|
1207
1333
|
return Err(WFMachinesError::Nondeterminism(format!(
|
|
1208
1334
|
"Non-deprecated patch marker encountered for change {patch_name}, \
|
|
@@ -1214,10 +1340,10 @@ fn change_marker_handling(event: &HistoryEvent, mach: &Machines) -> Result<Chang
|
|
|
1214
1340
|
// worker.
|
|
1215
1341
|
if matches!(mach, Machines::PatchMachine(_)) {
|
|
1216
1342
|
debug!("Skipping non-matching event against patch machine");
|
|
1217
|
-
return Ok(
|
|
1343
|
+
return Ok(EventHandlingOutcome::SkipCommand);
|
|
1218
1344
|
}
|
|
1219
1345
|
}
|
|
1220
|
-
Ok(
|
|
1346
|
+
Ok(EventHandlingOutcome::Normal)
|
|
1221
1347
|
}
|
|
1222
1348
|
|
|
1223
1349
|
#[derive(derive_more::From)]
|