@temporalio/core-bridge 1.5.2 → 1.7.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 +304 -112
- package/lib/index.d.ts +8 -6
- package/lib/index.js.map +1 -1
- package/package.json +9 -4
- 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 +2 -4
- package/sdk-core/.cargo/config.toml +5 -2
- package/sdk-core/.github/workflows/heavy.yml +29 -0
- package/sdk-core/Cargo.toml +1 -1
- package/sdk-core/README.md +20 -10
- package/sdk-core/client/src/lib.rs +215 -39
- package/sdk-core/client/src/metrics.rs +17 -8
- package/sdk-core/client/src/raw.rs +4 -4
- package/sdk-core/client/src/retry.rs +32 -20
- package/sdk-core/core/Cargo.toml +25 -12
- package/sdk-core/core/src/abstractions/take_cell.rs +28 -0
- package/sdk-core/core/src/abstractions.rs +204 -14
- package/sdk-core/core/src/core_tests/activity_tasks.rs +143 -50
- package/sdk-core/core/src/core_tests/child_workflows.rs +6 -5
- package/sdk-core/core/src/core_tests/determinism.rs +165 -2
- package/sdk-core/core/src/core_tests/local_activities.rs +431 -43
- package/sdk-core/core/src/core_tests/queries.rs +34 -16
- package/sdk-core/core/src/core_tests/workers.rs +8 -5
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +588 -55
- package/sdk-core/core/src/ephemeral_server/mod.rs +113 -12
- package/sdk-core/core/src/internal_flags.rs +155 -0
- package/sdk-core/core/src/lib.rs +16 -9
- package/sdk-core/core/src/protosext/mod.rs +1 -1
- package/sdk-core/core/src/replay/mod.rs +16 -27
- package/sdk-core/core/src/telemetry/log_export.rs +1 -1
- package/sdk-core/core/src/telemetry/metrics.rs +69 -35
- package/sdk-core/core/src/telemetry/mod.rs +60 -21
- package/sdk-core/core/src/telemetry/prometheus_server.rs +19 -13
- package/sdk-core/core/src/test_help/mod.rs +73 -14
- 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 +379 -129
- package/sdk-core/core/src/worker/activities.rs +350 -175
- 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 +183 -64
- package/sdk-core/core/src/worker/workflow/bridge.rs +1 -3
- package/sdk-core/core/src/worker/workflow/driven_workflow.rs +3 -5
- package/sdk-core/core/src/worker/workflow/history_update.rs +916 -277
- package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +216 -183
- package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +9 -12
- package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +7 -9
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +160 -87
- package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +13 -14
- package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +7 -9
- package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +14 -17
- package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +242 -110
- package/sdk-core/core/src/worker/workflow/machines/mod.rs +27 -19
- package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +9 -11
- package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +321 -206
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +13 -18
- package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +20 -29
- package/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +2 -2
- package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +257 -51
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +6 -17
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +310 -150
- package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +17 -20
- package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +31 -15
- package/sdk-core/core/src/worker/workflow/managed_run.rs +1052 -380
- package/sdk-core/core/src/worker/workflow/mod.rs +598 -390
- package/sdk-core/core/src/worker/workflow/run_cache.rs +40 -57
- package/sdk-core/core/src/worker/workflow/wft_extraction.rs +137 -0
- package/sdk-core/core/src/worker/workflow/wft_poller.rs +1 -4
- package/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +117 -0
- package/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +24 -0
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +469 -718
- package/sdk-core/core-api/Cargo.toml +2 -1
- package/sdk-core/core-api/src/errors.rs +1 -34
- package/sdk-core/core-api/src/lib.rs +19 -9
- package/sdk-core/core-api/src/telemetry.rs +4 -6
- package/sdk-core/core-api/src/worker.rs +19 -1
- package/sdk-core/etc/deps.svg +115 -140
- package/sdk-core/etc/regen-depgraph.sh +5 -0
- package/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +86 -61
- package/sdk-core/fsm/rustfsm_trait/src/lib.rs +29 -71
- package/sdk-core/histories/ends_empty_wft_complete.bin +0 -0
- package/sdk-core/histories/evict_while_la_running_no_interference-16_history.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 +6 -6
- package/sdk-core/protos/api_upstream/build/go.mod +7 -0
- package/sdk-core/protos/api_upstream/build/go.sum +5 -0
- package/sdk-core/protos/api_upstream/build/tools.go +29 -0
- package/sdk-core/protos/api_upstream/go.mod +6 -0
- package/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +9 -2
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +7 -26
- package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +13 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +3 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +3 -7
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/common.proto +3 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +8 -8
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +25 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/namespace.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/query.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +24 -19
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/filter/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +49 -26
- package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +4 -2
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +5 -2
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/protocol/v1/message.proto +57 -0
- package/sdk-core/protos/api_upstream/temporal/api/query/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +63 -0
- package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +71 -6
- package/sdk-core/protos/api_upstream/temporal/api/version/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +64 -28
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +4 -4
- 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 +67 -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/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +2 -2
- package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +2 -2
- package/sdk-core/sdk/Cargo.toml +5 -4
- package/sdk-core/sdk/src/lib.rs +108 -26
- 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 +16 -15
- package/sdk-core/sdk-core-protos/Cargo.toml +5 -2
- package/sdk-core/sdk-core-protos/build.rs +36 -2
- package/sdk-core/sdk-core-protos/src/history_builder.rs +138 -106
- package/sdk-core/sdk-core-protos/src/history_info.rs +10 -1
- package/sdk-core/sdk-core-protos/src/lib.rs +272 -87
- package/sdk-core/sdk-core-protos/src/task_token.rs +12 -2
- package/sdk-core/test-utils/Cargo.toml +3 -1
- package/sdk-core/test-utils/src/canned_histories.rs +106 -296
- package/sdk-core/test-utils/src/histfetch.rs +1 -1
- package/sdk-core/test-utils/src/lib.rs +82 -23
- package/sdk-core/test-utils/src/wf_input_saver.rs +50 -0
- package/sdk-core/test-utils/src/workflows.rs +29 -0
- package/sdk-core/tests/fuzzy_workflow.rs +130 -0
- package/sdk-core/tests/{load_tests.rs → heavy_tests.rs} +125 -51
- package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +25 -3
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +10 -5
- package/sdk-core/tests/integ_tests/metrics_tests.rs +218 -16
- package/sdk-core/tests/integ_tests/polling_tests.rs +4 -47
- package/sdk-core/tests/integ_tests/queries_tests.rs +5 -128
- package/sdk-core/tests/integ_tests/visibility_tests.rs +83 -25
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +161 -72
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -0
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +6 -13
- 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 +6 -2
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -10
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +94 -200
- package/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +2 -4
- package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +34 -28
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +76 -7
- package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -0
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +18 -14
- package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +6 -20
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +10 -21
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +7 -8
- package/sdk-core/tests/integ_tests/workflow_tests.rs +13 -14
- package/sdk-core/tests/main.rs +3 -13
- package/sdk-core/tests/runner.rs +75 -36
- package/sdk-core/tests/wf_input_replay.rs +32 -0
- package/src/conversions.rs +14 -8
- package/src/runtime.rs +9 -8
- package/ts/index.ts +8 -6
- package/sdk-core/bridge-ffi/Cargo.toml +0 -24
- package/sdk-core/bridge-ffi/LICENSE.txt +0 -23
- package/sdk-core/bridge-ffi/build.rs +0 -25
- package/sdk-core/bridge-ffi/include/sdk-core-bridge.h +0 -224
- package/sdk-core/bridge-ffi/src/lib.rs +0 -746
- package/sdk-core/bridge-ffi/src/wrappers.rs +0 -221
- package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +0 -210
- package/sdk-core/sdk/src/conversions.rs +0 -8
|
@@ -2,7 +2,8 @@ use super::{
|
|
|
2
2
|
workflow_machines::MachineResponse, Cancellable, EventInfo, NewMachineWithCommand,
|
|
3
3
|
OnEventWrapper, WFMachinesAdapter, WFMachinesError,
|
|
4
4
|
};
|
|
5
|
-
use
|
|
5
|
+
use crate::worker::workflow::machines::HistEventData;
|
|
6
|
+
use rustfsm::{fsm, MachineError, StateMachine, TransitionResult};
|
|
6
7
|
use std::convert::TryFrom;
|
|
7
8
|
use temporal_sdk_core_protos::{
|
|
8
9
|
coresdk::{
|
|
@@ -85,10 +86,8 @@ pub(super) fn new_external_signal(
|
|
|
85
86
|
Some(sig_we::Target::WorkflowExecution(we)) => (we, false),
|
|
86
87
|
};
|
|
87
88
|
|
|
88
|
-
let mut s =
|
|
89
|
-
|
|
90
|
-
shared_state: SharedState { seq: attrs.seq },
|
|
91
|
-
};
|
|
89
|
+
let mut s =
|
|
90
|
+
SignalExternalMachine::from_parts(Created {}.into(), SharedState { seq: attrs.seq });
|
|
92
91
|
OnEventWrapper::on_event_mut(&mut s, SignalExternalMachineEvents::Schedule)
|
|
93
92
|
.expect("Scheduling signal external wf command doesn't fail");
|
|
94
93
|
let cmd_attrs = command::Attributes::SignalExternalWorkflowExecutionCommandAttributes(
|
|
@@ -183,10 +182,11 @@ impl TryFrom<CommandType> for SignalExternalMachineEvents {
|
|
|
183
182
|
})
|
|
184
183
|
}
|
|
185
184
|
}
|
|
186
|
-
impl TryFrom<
|
|
185
|
+
impl TryFrom<HistEventData> for SignalExternalMachineEvents {
|
|
187
186
|
type Error = WFMachinesError;
|
|
188
187
|
|
|
189
|
-
fn try_from(e:
|
|
188
|
+
fn try_from(e: HistEventData) -> Result<Self, Self::Error> {
|
|
189
|
+
let e = e.event;
|
|
190
190
|
Ok(match e.event_type() {
|
|
191
191
|
EventType::ExternalWorkflowExecutionSignaled => Self::ExternalWorkflowExecutionSignaled,
|
|
192
192
|
EventType::SignalExternalWorkflowExecutionInitiated => {
|
|
@@ -202,15 +202,13 @@ impl TryFrom<HistoryEvent> for SignalExternalMachineEvents {
|
|
|
202
202
|
Self::SignalExternalWorkflowExecutionFailed(attrs.cause())
|
|
203
203
|
} else {
|
|
204
204
|
return Err(WFMachinesError::Fatal(format!(
|
|
205
|
-
"Signal workflow failed attributes were unset: {}"
|
|
206
|
-
e
|
|
205
|
+
"Signal workflow failed attributes were unset: {e}"
|
|
207
206
|
)));
|
|
208
207
|
}
|
|
209
208
|
}
|
|
210
209
|
_ => {
|
|
211
210
|
return Err(WFMachinesError::Nondeterminism(format!(
|
|
212
|
-
"Signal external WF machine does not handle this event: {}"
|
|
213
|
-
e
|
|
211
|
+
"Signal external WF machine does not handle this event: {e}"
|
|
214
212
|
)))
|
|
215
213
|
}
|
|
216
214
|
})
|
|
@@ -242,7 +240,7 @@ impl WFMachinesAdapter for SignalExternalMachine {
|
|
|
242
240
|
seq: self.shared_state.seq,
|
|
243
241
|
// TODO: Create new failure type upstream for this
|
|
244
242
|
failure: Some(Failure {
|
|
245
|
-
message: format!("Unable to signal external workflow because {}"
|
|
243
|
+
message: format!("Unable to signal external workflow because {reason}"),
|
|
246
244
|
failure_info: Some(FailureInfo::ApplicationFailureInfo(
|
|
247
245
|
ApplicationFailureInfo {
|
|
248
246
|
r#type: f.to_string(),
|
|
@@ -297,7 +295,7 @@ impl Cancellable for SignalExternalMachine {
|
|
|
297
295
|
fn was_cancelled_before_sent_to_server(&self) -> bool {
|
|
298
296
|
// We are only ever in the cancelled state if cancelled before sent to server, there is no
|
|
299
297
|
// after sent cancellation here.
|
|
300
|
-
matches!(self.state, SignalExternalMachineState::Cancelled(_))
|
|
298
|
+
matches!(self.state(), SignalExternalMachineState::Cancelled(_))
|
|
301
299
|
}
|
|
302
300
|
}
|
|
303
301
|
|
|
@@ -427,13 +425,10 @@ mod tests {
|
|
|
427
425
|
SignalExternalMachineState::Cancelled(Cancelled {}),
|
|
428
426
|
Signaled {}.into(),
|
|
429
427
|
] {
|
|
430
|
-
let mut s = SignalExternalMachine
|
|
431
|
-
state: state.clone(),
|
|
432
|
-
shared_state: Default::default(),
|
|
433
|
-
};
|
|
428
|
+
let mut s = SignalExternalMachine::from_parts(state.clone(), Default::default());
|
|
434
429
|
let cmds = s.cancel().unwrap();
|
|
435
430
|
assert_eq!(cmds.len(), 0);
|
|
436
|
-
assert_eq!(discriminant(&state), discriminant(
|
|
431
|
+
assert_eq!(discriminant(&state), discriminant(s.state()));
|
|
437
432
|
}
|
|
438
433
|
}
|
|
439
434
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
#![allow(clippy::large_enum_variant)]
|
|
2
2
|
|
|
3
3
|
use super::{
|
|
4
|
-
workflow_machines::
|
|
5
|
-
|
|
4
|
+
workflow_machines::MachineResponse, Cancellable, EventInfo, NewMachineWithCommand,
|
|
5
|
+
OnEventWrapper, WFMachinesAdapter,
|
|
6
6
|
};
|
|
7
|
+
use crate::worker::workflow::{machines::HistEventData, WFMachinesError};
|
|
7
8
|
use rustfsm::{fsm, MachineError, StateMachine, TransitionResult};
|
|
8
9
|
use std::convert::TryFrom;
|
|
9
10
|
use temporal_sdk_core_protos::{
|
|
@@ -83,20 +84,21 @@ impl TimerMachine {
|
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
fn new(attribs: StartTimer) -> Self {
|
|
86
|
-
Self
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
Self::from_parts(
|
|
88
|
+
Created {}.into(),
|
|
89
|
+
SharedState {
|
|
89
90
|
attrs: attribs,
|
|
90
91
|
cancelled_before_sent: false,
|
|
91
92
|
},
|
|
92
|
-
|
|
93
|
+
)
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
96
|
|
|
96
|
-
impl TryFrom<
|
|
97
|
+
impl TryFrom<HistEventData> for TimerMachineEvents {
|
|
97
98
|
type Error = WFMachinesError;
|
|
98
99
|
|
|
99
|
-
fn try_from(e:
|
|
100
|
+
fn try_from(e: HistEventData) -> Result<Self, Self::Error> {
|
|
101
|
+
let e = e.event;
|
|
100
102
|
Ok(match e.event_type() {
|
|
101
103
|
EventType::TimerStarted => Self::TimerStarted(e.event_id),
|
|
102
104
|
EventType::TimerCanceled => Self::TimerCanceled,
|
|
@@ -107,15 +109,13 @@ impl TryFrom<HistoryEvent> for TimerMachineEvents {
|
|
|
107
109
|
Self::TimerFired(attrs)
|
|
108
110
|
} else {
|
|
109
111
|
return Err(WFMachinesError::Fatal(format!(
|
|
110
|
-
"Timer fired attribs were unset: {}"
|
|
111
|
-
e
|
|
112
|
+
"Timer fired attribs were unset: {e}"
|
|
112
113
|
)));
|
|
113
114
|
}
|
|
114
115
|
}
|
|
115
116
|
_ => {
|
|
116
117
|
return Err(WFMachinesError::Nondeterminism(format!(
|
|
117
|
-
"Timer machine does not handle this event: {}"
|
|
118
|
-
e
|
|
118
|
+
"Timer machine does not handle this event: {e}"
|
|
119
119
|
)))
|
|
120
120
|
}
|
|
121
121
|
})
|
|
@@ -178,15 +178,9 @@ impl StartCommandCreated {
|
|
|
178
178
|
TransitionResult::default()
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
pub(super) fn on_cancel(self, dat: SharedState) -> TimerMachineTransition<Canceled> {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
Canceled::default(),
|
|
185
|
-
SharedState {
|
|
186
|
-
cancelled_before_sent: true,
|
|
187
|
-
..dat
|
|
188
|
-
},
|
|
189
|
-
)
|
|
181
|
+
pub(super) fn on_cancel(self, dat: &mut SharedState) -> TimerMachineTransition<Canceled> {
|
|
182
|
+
dat.cancelled_before_sent = true;
|
|
183
|
+
TransitionResult::default()
|
|
190
184
|
}
|
|
191
185
|
}
|
|
192
186
|
|
|
@@ -196,7 +190,7 @@ pub(super) struct StartCommandRecorded {}
|
|
|
196
190
|
impl StartCommandRecorded {
|
|
197
191
|
pub(super) fn on_timer_fired(
|
|
198
192
|
self,
|
|
199
|
-
dat: SharedState,
|
|
193
|
+
dat: &mut SharedState,
|
|
200
194
|
attrs: TimerFiredEventAttributes,
|
|
201
195
|
) -> TimerMachineTransition<Fired> {
|
|
202
196
|
if dat.attrs.seq.to_string() == attrs.timer_id {
|
|
@@ -211,7 +205,7 @@ impl StartCommandRecorded {
|
|
|
211
205
|
|
|
212
206
|
pub(super) fn on_cancel(
|
|
213
207
|
self,
|
|
214
|
-
dat: SharedState,
|
|
208
|
+
dat: &mut SharedState,
|
|
215
209
|
) -> TimerMachineTransition<CancelTimerCommandCreated> {
|
|
216
210
|
let cmd = Command {
|
|
217
211
|
command_type: CommandType::CancelTimer as i32,
|
|
@@ -256,7 +250,7 @@ impl Cancellable for TimerMachine {
|
|
|
256
250
|
vec![MachineResponse::IssueNewCommand(cmd)]
|
|
257
251
|
}
|
|
258
252
|
None => vec![],
|
|
259
|
-
x => panic!("Invalid cancel event response {:?}"
|
|
253
|
+
x => panic!("Invalid cancel event response {x:?}"),
|
|
260
254
|
},
|
|
261
255
|
)
|
|
262
256
|
}
|
|
@@ -423,13 +417,10 @@ mod test {
|
|
|
423
417
|
#[test]
|
|
424
418
|
fn cancels_ignored_terminal() {
|
|
425
419
|
for state in [TimerMachineState::Canceled(Canceled {}), Fired {}.into()] {
|
|
426
|
-
let mut s = TimerMachine
|
|
427
|
-
state: state.clone(),
|
|
428
|
-
shared_state: Default::default(),
|
|
429
|
-
};
|
|
420
|
+
let mut s = TimerMachine::from_parts(state.clone(), Default::default());
|
|
430
421
|
let cmds = s.cancel().unwrap();
|
|
431
422
|
assert_eq!(cmds.len(), 0);
|
|
432
|
-
assert_eq!(discriminant(&state), discriminant(
|
|
423
|
+
assert_eq!(discriminant(&state), discriminant(s.state()));
|
|
433
424
|
}
|
|
434
425
|
}
|
|
435
426
|
}
|
|
@@ -144,7 +144,7 @@ mod machine_coverage_report {
|
|
|
144
144
|
m @ "ModifyWorkflowPropertiesMachine" => {
|
|
145
145
|
cover_transitions(m, &mut modify_wf_props, coverage)
|
|
146
146
|
}
|
|
147
|
-
m => panic!("Unknown machine {}"
|
|
147
|
+
m => panic!("Unknown machine {m}"),
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
150
|
}
|
|
@@ -168,7 +168,7 @@ mod machine_coverage_report {
|
|
|
168
168
|
let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
|
169
169
|
d.push("machine_coverage");
|
|
170
170
|
std::fs::create_dir_all(&d).unwrap();
|
|
171
|
-
d.push(format!("{}_Coverage.puml"
|
|
171
|
+
d.push(format!("{machine}_Coverage.puml"));
|
|
172
172
|
let mut file = File::create(d).unwrap();
|
|
173
173
|
file.write_all(viz.as_bytes()).unwrap();
|
|
174
174
|
}
|
package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs
CHANGED
|
@@ -1,18 +1,28 @@
|
|
|
1
|
-
use super::{
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
use super::{workflow_machines::MachineResponse, NewMachineWithCommand};
|
|
2
|
+
use crate::{
|
|
3
|
+
internal_flags::CoreInternalFlags,
|
|
4
|
+
worker::workflow::{
|
|
5
|
+
machines::{
|
|
6
|
+
patch_state_machine::VERSION_SEARCH_ATTR_KEY, Cancellable, EventInfo, HistEventData,
|
|
7
|
+
WFMachinesAdapter,
|
|
8
|
+
},
|
|
9
|
+
InternalFlagsRef, WFMachinesError,
|
|
10
|
+
},
|
|
4
11
|
};
|
|
5
|
-
use
|
|
6
|
-
use rustfsm::{fsm, TransitionResult};
|
|
12
|
+
use rustfsm::{fsm, StateMachine, TransitionResult};
|
|
7
13
|
use temporal_sdk_core_protos::{
|
|
8
14
|
coresdk::workflow_commands::UpsertWorkflowSearchAttributes,
|
|
9
15
|
temporal::api::{
|
|
10
|
-
command::v1::Command,
|
|
16
|
+
command::v1::{command, Command, UpsertWorkflowSearchAttributesCommandAttributes},
|
|
17
|
+
common::v1::SearchAttributes,
|
|
11
18
|
enums::v1::{CommandType, EventType},
|
|
12
|
-
history::v1::HistoryEvent,
|
|
19
|
+
history::v1::{history_event, HistoryEvent},
|
|
13
20
|
},
|
|
14
21
|
};
|
|
15
22
|
|
|
23
|
+
/// By default the server permits SA values under 2k.
|
|
24
|
+
pub(crate) const MAX_SEARCH_ATTR_PAYLOAD_SIZE: usize = 2048;
|
|
25
|
+
|
|
16
26
|
fsm! {
|
|
17
27
|
pub(super) name UpsertSearchAttributesMachine;
|
|
18
28
|
command UpsertSearchAttributesMachineCommand;
|
|
@@ -28,18 +38,70 @@ fsm! {
|
|
|
28
38
|
// upon observing a history event indicating that the command has been recorded. Note that this
|
|
29
39
|
// does not imply that the command has been _executed_, only that it _will be_ executed at some
|
|
30
40
|
// point in the future.
|
|
31
|
-
CommandIssued --(CommandRecorded) --> Done;
|
|
41
|
+
CommandIssued --(CommandRecorded(CmdRecDat), shared on_command_recorded) --> Done;
|
|
32
42
|
}
|
|
33
43
|
|
|
34
44
|
/// Instantiates an UpsertSearchAttributesMachine and packs it together with an initial command
|
|
35
45
|
/// to apply the provided search attribute update.
|
|
36
46
|
pub(super) fn upsert_search_attrs(
|
|
37
47
|
attribs: UpsertWorkflowSearchAttributes,
|
|
48
|
+
internal_flags: InternalFlagsRef,
|
|
49
|
+
replaying: bool,
|
|
50
|
+
) -> NewMachineWithCommand {
|
|
51
|
+
let has_flag = internal_flags
|
|
52
|
+
.borrow_mut()
|
|
53
|
+
.try_use(CoreInternalFlags::UpsertSearchAttributeOnPatch, !replaying);
|
|
54
|
+
if has_flag
|
|
55
|
+
&& attribs
|
|
56
|
+
.search_attributes
|
|
57
|
+
.contains_key(VERSION_SEARCH_ATTR_KEY)
|
|
58
|
+
{
|
|
59
|
+
warn!(
|
|
60
|
+
"Upserting the {VERSION_SEARCH_ATTR_KEY} search attribute directly from workflow code \
|
|
61
|
+
is not permitted and has no effect!"
|
|
62
|
+
);
|
|
63
|
+
// We must still create the command to preserve compatability with anyone previously doing
|
|
64
|
+
// this.
|
|
65
|
+
create_new(Default::default(), true, internal_flags)
|
|
66
|
+
} else {
|
|
67
|
+
create_new(attribs.search_attributes.into(), false, internal_flags)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/// May be used by other state machines / internal needs which desire upserting search attributes.
|
|
72
|
+
pub(super) fn upsert_search_attrs_internal(
|
|
73
|
+
attribs: UpsertWorkflowSearchAttributesCommandAttributes,
|
|
74
|
+
internal_flags: InternalFlagsRef,
|
|
38
75
|
) -> NewMachineWithCommand {
|
|
39
|
-
|
|
76
|
+
create_new(
|
|
77
|
+
attribs.search_attributes.unwrap_or_default(),
|
|
78
|
+
true,
|
|
79
|
+
internal_flags,
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
fn create_new(
|
|
84
|
+
sa_map: SearchAttributes,
|
|
85
|
+
should_skip_determinism: bool,
|
|
86
|
+
internal_flags: InternalFlagsRef,
|
|
87
|
+
) -> NewMachineWithCommand {
|
|
88
|
+
let sm = UpsertSearchAttributesMachine::from_parts(
|
|
89
|
+
Created {}.into(),
|
|
90
|
+
SharedState {
|
|
91
|
+
sa_map: sa_map.clone(),
|
|
92
|
+
should_skip_determinism,
|
|
93
|
+
internal_flags,
|
|
94
|
+
},
|
|
95
|
+
);
|
|
40
96
|
let cmd = Command {
|
|
41
97
|
command_type: CommandType::UpsertWorkflowSearchAttributes as i32,
|
|
42
|
-
attributes: Some(
|
|
98
|
+
attributes: Some(
|
|
99
|
+
command::Attributes::UpsertWorkflowSearchAttributesCommandAttributes(
|
|
100
|
+
UpsertWorkflowSearchAttributesCommandAttributes {
|
|
101
|
+
search_attributes: Some(sa_map),
|
|
102
|
+
},
|
|
103
|
+
),
|
|
104
|
+
),
|
|
43
105
|
};
|
|
44
106
|
NewMachineWithCommand {
|
|
45
107
|
command: cmd,
|
|
@@ -47,8 +109,12 @@ pub(super) fn upsert_search_attrs(
|
|
|
47
109
|
}
|
|
48
110
|
}
|
|
49
111
|
|
|
50
|
-
|
|
51
|
-
|
|
112
|
+
#[derive(Clone)]
|
|
113
|
+
pub(super) struct SharedState {
|
|
114
|
+
should_skip_determinism: bool,
|
|
115
|
+
sa_map: SearchAttributes,
|
|
116
|
+
internal_flags: InternalFlagsRef,
|
|
117
|
+
}
|
|
52
118
|
|
|
53
119
|
/// The state-machine-specific set of commands that are the results of state transition in the
|
|
54
120
|
/// UpsertSearchAttributesMachine. There are none of these because this state machine emits the
|
|
@@ -65,21 +131,39 @@ pub(super) struct Created {}
|
|
|
65
131
|
/// higher-level machinery, it transitions into this state.
|
|
66
132
|
#[derive(Debug, Default, Clone, derive_more::Display)]
|
|
67
133
|
pub(super) struct CommandIssued {}
|
|
134
|
+
pub(super) struct CmdRecDat {
|
|
135
|
+
sa_map: Option<SearchAttributes>,
|
|
136
|
+
replaying: bool,
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
impl CommandIssued {
|
|
140
|
+
pub(super) fn on_command_recorded(
|
|
141
|
+
self,
|
|
142
|
+
shared: &mut SharedState,
|
|
143
|
+
dat: CmdRecDat,
|
|
144
|
+
) -> UpsertSearchAttributesMachineTransition<Done> {
|
|
145
|
+
if shared.internal_flags.borrow_mut().try_use(
|
|
146
|
+
CoreInternalFlags::UpsertSearchAttributeOnPatch,
|
|
147
|
+
!dat.replaying,
|
|
148
|
+
) {
|
|
149
|
+
let sa = dat.sa_map.unwrap_or_default();
|
|
150
|
+
if !shared.should_skip_determinism && shared.sa_map != sa {
|
|
151
|
+
return TransitionResult::Err(WFMachinesError::Nondeterminism(format!(
|
|
152
|
+
"Search attribute upsert calls must remain deterministic, but {:?} does not \
|
|
153
|
+
match the attributes from history: {:?}",
|
|
154
|
+
shared.sa_map, sa
|
|
155
|
+
)));
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
TransitionResult::default()
|
|
159
|
+
}
|
|
160
|
+
}
|
|
68
161
|
|
|
69
162
|
/// Once the server has recorded its receipt of the search attribute update, the
|
|
70
163
|
/// UpsertSearchAttributesMachine transitions into this terminal state.
|
|
71
164
|
#[derive(Debug, Default, Clone, derive_more::Display)]
|
|
72
165
|
pub(super) struct Done {}
|
|
73
166
|
|
|
74
|
-
impl UpsertSearchAttributesMachine {
|
|
75
|
-
fn new() -> Self {
|
|
76
|
-
Self {
|
|
77
|
-
state: Created {}.into(),
|
|
78
|
-
shared_state: (),
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
167
|
impl WFMachinesAdapter for UpsertSearchAttributesMachine {
|
|
84
168
|
/// Transforms an UpsertSearchAttributesMachine-specific command (i.e. an instance of the type
|
|
85
169
|
/// UpsertSearchAttributesMachineCommand) to a more generic form supported by the abstract
|
|
@@ -109,14 +193,19 @@ impl Cancellable for UpsertSearchAttributesMachine {}
|
|
|
109
193
|
// Converts the generic history event with type EventType::UpsertWorkflowSearchAttributes into the
|
|
110
194
|
// UpsertSearchAttributesMachine-specific event type
|
|
111
195
|
// UpsertSearchAttributesMachineEvents::CommandRecorded.
|
|
112
|
-
impl TryFrom<
|
|
196
|
+
impl TryFrom<HistEventData> for UpsertSearchAttributesMachineEvents {
|
|
113
197
|
type Error = WFMachinesError;
|
|
114
198
|
|
|
115
|
-
fn try_from(e:
|
|
116
|
-
match e.
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
199
|
+
fn try_from(e: HistEventData) -> Result<Self, Self::Error> {
|
|
200
|
+
match e.event.attributes {
|
|
201
|
+
Some(history_event::Attributes::UpsertWorkflowSearchAttributesEventAttributes(
|
|
202
|
+
attrs,
|
|
203
|
+
)) => Ok(UpsertSearchAttributesMachineEvents::CommandRecorded(
|
|
204
|
+
CmdRecDat {
|
|
205
|
+
sa_map: attrs.search_attributes,
|
|
206
|
+
replaying: e.replaying,
|
|
207
|
+
},
|
|
208
|
+
)),
|
|
120
209
|
_ => Err(Self::Error::Nondeterminism(format!(
|
|
121
210
|
"UpsertWorkflowSearchAttributesMachine does not handle {e}"
|
|
122
211
|
))),
|
|
@@ -141,13 +230,6 @@ impl TryFrom<CommandType> for UpsertSearchAttributesMachineEvents {
|
|
|
141
230
|
}
|
|
142
231
|
}
|
|
143
232
|
|
|
144
|
-
// There is no Command/Response associated with this transition
|
|
145
|
-
impl From<CommandIssued> for Done {
|
|
146
|
-
fn from(_: CommandIssued) -> Self {
|
|
147
|
-
Self {}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
233
|
// There is no Command/Response associated with this transition
|
|
152
234
|
impl From<Created> for CommandIssued {
|
|
153
235
|
fn from(_: Created) -> Self {
|
|
@@ -158,12 +240,30 @@ impl From<Created> for CommandIssued {
|
|
|
158
240
|
#[cfg(test)]
|
|
159
241
|
mod tests {
|
|
160
242
|
use super::{super::OnEventWrapper, *};
|
|
161
|
-
use crate::{
|
|
162
|
-
|
|
243
|
+
use crate::{
|
|
244
|
+
internal_flags::InternalFlags,
|
|
245
|
+
replay::TestHistoryBuilder,
|
|
246
|
+
test_help::{build_mock_pollers, mock_worker, MockPollCfg, ResponseType},
|
|
247
|
+
worker::{
|
|
248
|
+
client::mocks::mock_workflow_client,
|
|
249
|
+
workflow::{machines::patch_state_machine::VERSION_SEARCH_ATTR_KEY, ManagedWFFunc},
|
|
250
|
+
},
|
|
251
|
+
};
|
|
252
|
+
use rustfsm::{MachineError, StateMachine};
|
|
253
|
+
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
|
163
254
|
use temporal_sdk::{WfContext, WorkflowFunction};
|
|
164
|
-
use
|
|
165
|
-
|
|
255
|
+
use temporal_sdk_core_api::Worker;
|
|
256
|
+
use temporal_sdk_core_protos::{
|
|
257
|
+
coresdk::{
|
|
258
|
+
workflow_commands::SetPatchMarker, workflow_completion::WorkflowActivationCompletion,
|
|
259
|
+
AsJsonPayloadExt,
|
|
260
|
+
},
|
|
261
|
+
temporal::api::{
|
|
262
|
+
command::v1::command::Attributes, common::v1::Payload,
|
|
263
|
+
history::v1::UpsertWorkflowSearchAttributesEventAttributes,
|
|
264
|
+
},
|
|
166
265
|
};
|
|
266
|
+
use temporal_sdk_core_test_utils::WorkerTestHelpers;
|
|
167
267
|
|
|
168
268
|
#[tokio::test]
|
|
169
269
|
async fn upsert_search_attrs_from_workflow() {
|
|
@@ -216,27 +316,133 @@ mod tests {
|
|
|
216
316
|
wfm.shutdown().await.unwrap();
|
|
217
317
|
}
|
|
218
318
|
|
|
219
|
-
#[
|
|
220
|
-
|
|
221
|
-
let mut sm = UpsertSearchAttributesMachine::
|
|
222
|
-
|
|
319
|
+
#[rstest::rstest]
|
|
320
|
+
fn upsert_search_attrs_sm(#[values(true, false)] nondetermistic: bool) {
|
|
321
|
+
let mut sm = UpsertSearchAttributesMachine::from_parts(
|
|
322
|
+
Created {}.into(),
|
|
323
|
+
SharedState {
|
|
324
|
+
sa_map: Default::default(),
|
|
325
|
+
should_skip_determinism: false,
|
|
326
|
+
internal_flags: Rc::new(RefCell::new(InternalFlags::all_core_enabled())),
|
|
327
|
+
},
|
|
328
|
+
);
|
|
223
329
|
|
|
224
|
-
let
|
|
225
|
-
|
|
226
|
-
|
|
330
|
+
let sa_attribs = if nondetermistic {
|
|
331
|
+
UpsertWorkflowSearchAttributesEventAttributes {
|
|
332
|
+
workflow_task_completed_event_id: 0,
|
|
333
|
+
search_attributes: Some(SearchAttributes {
|
|
334
|
+
indexed_fields: HashMap::from([("Yo".to_string(), Payload::default())]),
|
|
335
|
+
}),
|
|
336
|
+
}
|
|
337
|
+
} else {
|
|
338
|
+
Default::default()
|
|
339
|
+
};
|
|
227
340
|
let recorded_history_event = HistoryEvent {
|
|
228
341
|
event_type: EventType::UpsertWorkflowSearchAttributes as i32,
|
|
342
|
+
attributes: Some(
|
|
343
|
+
history_event::Attributes::UpsertWorkflowSearchAttributesEventAttributes(
|
|
344
|
+
sa_attribs,
|
|
345
|
+
),
|
|
346
|
+
),
|
|
229
347
|
..Default::default()
|
|
230
348
|
};
|
|
231
349
|
assert!(sm.matches_event(&recorded_history_event));
|
|
232
|
-
let cmd_recorded_sm_event =
|
|
350
|
+
let cmd_recorded_sm_event = HistEventData {
|
|
351
|
+
event: recorded_history_event,
|
|
352
|
+
replaying: false,
|
|
353
|
+
current_task_is_last_in_history: true,
|
|
354
|
+
}
|
|
355
|
+
.try_into()
|
|
356
|
+
.unwrap();
|
|
233
357
|
|
|
234
|
-
OnEventWrapper::on_event_mut(
|
|
235
|
-
|
|
358
|
+
OnEventWrapper::on_event_mut(
|
|
359
|
+
&mut sm,
|
|
360
|
+
CommandType::UpsertWorkflowSearchAttributes
|
|
361
|
+
.try_into()
|
|
362
|
+
.unwrap(),
|
|
363
|
+
)
|
|
364
|
+
.expect("CommandScheduled should transition Created -> CommandIssued");
|
|
236
365
|
assert_eq!(CommandIssued {}.to_string(), sm.state().to_string());
|
|
237
366
|
|
|
238
|
-
OnEventWrapper::on_event_mut(&mut sm, cmd_recorded_sm_event)
|
|
239
|
-
|
|
240
|
-
|
|
367
|
+
let recorded_res = OnEventWrapper::on_event_mut(&mut sm, cmd_recorded_sm_event);
|
|
368
|
+
if nondetermistic {
|
|
369
|
+
assert_matches!(
|
|
370
|
+
recorded_res.unwrap_err(),
|
|
371
|
+
MachineError::Underlying(WFMachinesError::Nondeterminism(_))
|
|
372
|
+
);
|
|
373
|
+
} else {
|
|
374
|
+
recorded_res.expect("CommandRecorded should transition CommandIssued -> Done");
|
|
375
|
+
assert_eq!(Done {}.to_string(), sm.state().to_string());
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
#[rstest::rstest]
|
|
380
|
+
#[tokio::test]
|
|
381
|
+
async fn upserting_change_version_directly(
|
|
382
|
+
#[values(true, false)] flag_in_history: bool,
|
|
383
|
+
#[values(true, false)] with_patched_cmd: bool,
|
|
384
|
+
) {
|
|
385
|
+
let patch_id = "whatever".to_string();
|
|
386
|
+
let mut t = TestHistoryBuilder::default();
|
|
387
|
+
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
388
|
+
t.add_full_wf_task();
|
|
389
|
+
if flag_in_history {
|
|
390
|
+
t.set_flags_first_wft(
|
|
391
|
+
&[CoreInternalFlags::UpsertSearchAttributeOnPatch as u32],
|
|
392
|
+
&[],
|
|
393
|
+
);
|
|
394
|
+
}
|
|
395
|
+
if with_patched_cmd {
|
|
396
|
+
t.add_has_change_marker(&patch_id, false);
|
|
397
|
+
}
|
|
398
|
+
t.add_upsert_search_attrs_for_patch(&[patch_id.clone()]);
|
|
399
|
+
t.add_full_wf_task();
|
|
400
|
+
t.add_workflow_execution_completed();
|
|
401
|
+
|
|
402
|
+
let mut mp = MockPollCfg::from_resp_batches(
|
|
403
|
+
"fakeid",
|
|
404
|
+
t,
|
|
405
|
+
[ResponseType::ToTaskNum(1), ResponseType::AllHistory],
|
|
406
|
+
mock_workflow_client(),
|
|
407
|
+
);
|
|
408
|
+
// Ensure the upsert command has an empty map when not using the patched command
|
|
409
|
+
if !with_patched_cmd {
|
|
410
|
+
mp.completion_asserts = Some(Box::new(|wftc| {
|
|
411
|
+
assert_matches!(wftc.commands.get(0).and_then(|c| c.attributes.as_ref()).unwrap(),
|
|
412
|
+
Attributes::UpsertWorkflowSearchAttributesCommandAttributes(attrs)
|
|
413
|
+
if attrs.search_attributes.as_ref().unwrap().indexed_fields.is_empty())
|
|
414
|
+
}));
|
|
415
|
+
}
|
|
416
|
+
let core = mock_worker(build_mock_pollers(mp));
|
|
417
|
+
|
|
418
|
+
let mut ver_upsert = HashMap::new();
|
|
419
|
+
ver_upsert.insert(
|
|
420
|
+
VERSION_SEARCH_ATTR_KEY.to_string(),
|
|
421
|
+
"hi".as_json_payload().unwrap(),
|
|
422
|
+
);
|
|
423
|
+
let act = core.poll_workflow_activation().await.unwrap();
|
|
424
|
+
let mut cmds = if with_patched_cmd {
|
|
425
|
+
vec![SetPatchMarker {
|
|
426
|
+
patch_id,
|
|
427
|
+
deprecated: false,
|
|
428
|
+
}
|
|
429
|
+
.into()]
|
|
430
|
+
} else {
|
|
431
|
+
vec![]
|
|
432
|
+
};
|
|
433
|
+
cmds.push(
|
|
434
|
+
UpsertWorkflowSearchAttributes {
|
|
435
|
+
search_attributes: ver_upsert,
|
|
436
|
+
}
|
|
437
|
+
.into(),
|
|
438
|
+
);
|
|
439
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
440
|
+
act.run_id, cmds,
|
|
441
|
+
))
|
|
442
|
+
.await
|
|
443
|
+
.unwrap();
|
|
444
|
+
// Now ensure that encountering the upsert in history works fine
|
|
445
|
+
let act = core.poll_workflow_activation().await.unwrap();
|
|
446
|
+
core.complete_execution(&act.run_id).await;
|
|
241
447
|
}
|
|
242
448
|
}
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
use super::super::
|
|
1
|
+
use super::super::local_activity_state_machine::ResolveDat;
|
|
2
2
|
use crate::{
|
|
3
|
-
protosext::{
|
|
3
|
+
protosext::{CompleteLocalActivityData, ValidScheduleLA},
|
|
4
4
|
worker::{ExecutingLAId, LocalActRequest, NewLocalAct},
|
|
5
5
|
};
|
|
6
6
|
use std::{
|
|
7
7
|
collections::{HashMap, HashSet},
|
|
8
8
|
time::SystemTime,
|
|
9
9
|
};
|
|
10
|
-
use temporal_sdk_core_protos::temporal::api::
|
|
11
|
-
common::v1::WorkflowExecution, history::v1::HistoryEvent,
|
|
12
|
-
};
|
|
10
|
+
use temporal_sdk_core_protos::temporal::api::common::v1::WorkflowExecution;
|
|
13
11
|
|
|
14
12
|
#[derive(Default)]
|
|
15
13
|
pub(super) struct LocalActivityData {
|
|
@@ -53,7 +51,7 @@ impl LocalActivityData {
|
|
|
53
51
|
.chain(self.new_requests.drain(..).map(|sa| {
|
|
54
52
|
self.executing.insert(sa.seq);
|
|
55
53
|
LocalActRequest::New(NewLocalAct {
|
|
56
|
-
schedule_time:
|
|
54
|
+
schedule_time: SystemTime::now(),
|
|
57
55
|
schedule_cmd: sa,
|
|
58
56
|
workflow_type: wf_type.to_string(),
|
|
59
57
|
workflow_exec_info: WorkflowExecution {
|
|
@@ -70,17 +68,8 @@ impl LocalActivityData {
|
|
|
70
68
|
self.executing.len() + self.new_requests.len()
|
|
71
69
|
}
|
|
72
70
|
|
|
73
|
-
pub(super) fn
|
|
74
|
-
|
|
75
|
-
self.preresolutions
|
|
76
|
-
.insert(la_dat.marker_dat.seq, la_dat.into());
|
|
77
|
-
} else {
|
|
78
|
-
return Err(WFMachinesError::Fatal(format!(
|
|
79
|
-
"Local activity marker was unparsable: {:?}",
|
|
80
|
-
e
|
|
81
|
-
)));
|
|
82
|
-
}
|
|
83
|
-
Ok(())
|
|
71
|
+
pub(super) fn insert_peeked_marker(&mut self, dat: CompleteLocalActivityData) {
|
|
72
|
+
self.preresolutions.insert(dat.marker_dat.seq, dat.into());
|
|
84
73
|
}
|
|
85
74
|
|
|
86
75
|
pub(super) fn take_preresolution(&mut self, seq: u32) -> Option<ResolveDat> {
|