@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
|
@@ -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 => {
|
|
@@ -295,7 +295,7 @@ impl Cancellable for SignalExternalMachine {
|
|
|
295
295
|
fn was_cancelled_before_sent_to_server(&self) -> bool {
|
|
296
296
|
// We are only ever in the cancelled state if cancelled before sent to server, there is no
|
|
297
297
|
// after sent cancellation here.
|
|
298
|
-
matches!(self.state, SignalExternalMachineState::Cancelled(_))
|
|
298
|
+
matches!(self.state(), SignalExternalMachineState::Cancelled(_))
|
|
299
299
|
}
|
|
300
300
|
}
|
|
301
301
|
|
|
@@ -425,13 +425,10 @@ mod tests {
|
|
|
425
425
|
SignalExternalMachineState::Cancelled(Cancelled {}),
|
|
426
426
|
Signaled {}.into(),
|
|
427
427
|
] {
|
|
428
|
-
let mut s = SignalExternalMachine
|
|
429
|
-
state: state.clone(),
|
|
430
|
-
shared_state: Default::default(),
|
|
431
|
-
};
|
|
428
|
+
let mut s = SignalExternalMachine::from_parts(state.clone(), Default::default());
|
|
432
429
|
let cmds = s.cancel().unwrap();
|
|
433
430
|
assert_eq!(cmds.len(), 0);
|
|
434
|
-
assert_eq!(discriminant(&state), discriminant(
|
|
431
|
+
assert_eq!(discriminant(&state), discriminant(s.state()));
|
|
435
432
|
}
|
|
436
433
|
}
|
|
437
434
|
}
|
|
@@ -4,7 +4,7 @@ use super::{
|
|
|
4
4
|
workflow_machines::MachineResponse, Cancellable, EventInfo, NewMachineWithCommand,
|
|
5
5
|
OnEventWrapper, WFMachinesAdapter,
|
|
6
6
|
};
|
|
7
|
-
use crate::worker::workflow::WFMachinesError;
|
|
7
|
+
use crate::worker::workflow::{machines::HistEventData, WFMachinesError};
|
|
8
8
|
use rustfsm::{fsm, MachineError, StateMachine, TransitionResult};
|
|
9
9
|
use std::convert::TryFrom;
|
|
10
10
|
use temporal_sdk_core_protos::{
|
|
@@ -84,20 +84,21 @@ impl TimerMachine {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
fn new(attribs: StartTimer) -> Self {
|
|
87
|
-
Self
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
Self::from_parts(
|
|
88
|
+
Created {}.into(),
|
|
89
|
+
SharedState {
|
|
90
90
|
attrs: attribs,
|
|
91
91
|
cancelled_before_sent: false,
|
|
92
92
|
},
|
|
93
|
-
|
|
93
|
+
)
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
impl TryFrom<
|
|
97
|
+
impl TryFrom<HistEventData> for TimerMachineEvents {
|
|
98
98
|
type Error = WFMachinesError;
|
|
99
99
|
|
|
100
|
-
fn try_from(e:
|
|
100
|
+
fn try_from(e: HistEventData) -> Result<Self, Self::Error> {
|
|
101
|
+
let e = e.event;
|
|
101
102
|
Ok(match e.event_type() {
|
|
102
103
|
EventType::TimerStarted => Self::TimerStarted(e.event_id),
|
|
103
104
|
EventType::TimerCanceled => Self::TimerCanceled,
|
|
@@ -177,15 +178,9 @@ impl StartCommandCreated {
|
|
|
177
178
|
TransitionResult::default()
|
|
178
179
|
}
|
|
179
180
|
|
|
180
|
-
pub(super) fn on_cancel(self, dat: SharedState) -> TimerMachineTransition<Canceled> {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
Canceled::default(),
|
|
184
|
-
SharedState {
|
|
185
|
-
cancelled_before_sent: true,
|
|
186
|
-
..dat
|
|
187
|
-
},
|
|
188
|
-
)
|
|
181
|
+
pub(super) fn on_cancel(self, dat: &mut SharedState) -> TimerMachineTransition<Canceled> {
|
|
182
|
+
dat.cancelled_before_sent = true;
|
|
183
|
+
TransitionResult::default()
|
|
189
184
|
}
|
|
190
185
|
}
|
|
191
186
|
|
|
@@ -195,7 +190,7 @@ pub(super) struct StartCommandRecorded {}
|
|
|
195
190
|
impl StartCommandRecorded {
|
|
196
191
|
pub(super) fn on_timer_fired(
|
|
197
192
|
self,
|
|
198
|
-
dat: SharedState,
|
|
193
|
+
dat: &mut SharedState,
|
|
199
194
|
attrs: TimerFiredEventAttributes,
|
|
200
195
|
) -> TimerMachineTransition<Fired> {
|
|
201
196
|
if dat.attrs.seq.to_string() == attrs.timer_id {
|
|
@@ -210,7 +205,7 @@ impl StartCommandRecorded {
|
|
|
210
205
|
|
|
211
206
|
pub(super) fn on_cancel(
|
|
212
207
|
self,
|
|
213
|
-
dat: SharedState,
|
|
208
|
+
dat: &mut SharedState,
|
|
214
209
|
) -> TimerMachineTransition<CancelTimerCommandCreated> {
|
|
215
210
|
let cmd = Command {
|
|
216
211
|
command_type: CommandType::CancelTimer as i32,
|
|
@@ -422,13 +417,10 @@ mod test {
|
|
|
422
417
|
#[test]
|
|
423
418
|
fn cancels_ignored_terminal() {
|
|
424
419
|
for state in [TimerMachineState::Canceled(Canceled {}), Fired {}.into()] {
|
|
425
|
-
let mut s = TimerMachine
|
|
426
|
-
state: state.clone(),
|
|
427
|
-
shared_state: Default::default(),
|
|
428
|
-
};
|
|
420
|
+
let mut s = TimerMachine::from_parts(state.clone(), Default::default());
|
|
429
421
|
let cmds = s.cancel().unwrap();
|
|
430
422
|
assert_eq!(cmds.len(), 0);
|
|
431
|
-
assert_eq!(discriminant(&state), discriminant(
|
|
423
|
+
assert_eq!(discriminant(&state), discriminant(s.state()));
|
|
432
424
|
}
|
|
433
425
|
}
|
|
434
426
|
}
|
package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs
CHANGED
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
use super::{workflow_machines::MachineResponse, NewMachineWithCommand};
|
|
2
|
-
use crate::
|
|
3
|
-
|
|
4
|
-
|
|
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
|
+
},
|
|
5
11
|
};
|
|
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,54 @@ 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, 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())
|
|
66
|
+
} else {
|
|
67
|
+
create_new(attribs.search_attributes.into())
|
|
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,
|
|
38
74
|
) -> NewMachineWithCommand {
|
|
39
|
-
|
|
75
|
+
create_new(attribs.search_attributes.unwrap_or_default())
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
fn create_new(sa_map: SearchAttributes) -> NewMachineWithCommand {
|
|
79
|
+
let sm = UpsertSearchAttributesMachine::from_parts(Created {}.into(), SharedState {});
|
|
40
80
|
let cmd = Command {
|
|
41
81
|
command_type: CommandType::UpsertWorkflowSearchAttributes as i32,
|
|
42
|
-
attributes: Some(
|
|
82
|
+
attributes: Some(
|
|
83
|
+
command::Attributes::UpsertWorkflowSearchAttributesCommandAttributes(
|
|
84
|
+
UpsertWorkflowSearchAttributesCommandAttributes {
|
|
85
|
+
search_attributes: Some(sa_map),
|
|
86
|
+
},
|
|
87
|
+
),
|
|
88
|
+
),
|
|
43
89
|
};
|
|
44
90
|
NewMachineWithCommand {
|
|
45
91
|
command: cmd,
|
|
@@ -47,8 +93,8 @@ pub(super) fn upsert_search_attrs(
|
|
|
47
93
|
}
|
|
48
94
|
}
|
|
49
95
|
|
|
50
|
-
|
|
51
|
-
|
|
96
|
+
#[derive(Clone)]
|
|
97
|
+
pub(super) struct SharedState {}
|
|
52
98
|
|
|
53
99
|
/// The state-machine-specific set of commands that are the results of state transition in the
|
|
54
100
|
/// UpsertSearchAttributesMachine. There are none of these because this state machine emits the
|
|
@@ -66,20 +112,17 @@ pub(super) struct Created {}
|
|
|
66
112
|
#[derive(Debug, Default, Clone, derive_more::Display)]
|
|
67
113
|
pub(super) struct CommandIssued {}
|
|
68
114
|
|
|
115
|
+
impl CommandIssued {
|
|
116
|
+
pub(super) fn on_command_recorded(self) -> UpsertSearchAttributesMachineTransition<Done> {
|
|
117
|
+
TransitionResult::default()
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
69
121
|
/// Once the server has recorded its receipt of the search attribute update, the
|
|
70
122
|
/// UpsertSearchAttributesMachine transitions into this terminal state.
|
|
71
123
|
#[derive(Debug, Default, Clone, derive_more::Display)]
|
|
72
124
|
pub(super) struct Done {}
|
|
73
125
|
|
|
74
|
-
impl UpsertSearchAttributesMachine {
|
|
75
|
-
fn new() -> Self {
|
|
76
|
-
Self {
|
|
77
|
-
state: Created {}.into(),
|
|
78
|
-
shared_state: (),
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
126
|
impl WFMachinesAdapter for UpsertSearchAttributesMachine {
|
|
84
127
|
/// Transforms an UpsertSearchAttributesMachine-specific command (i.e. an instance of the type
|
|
85
128
|
/// UpsertSearchAttributesMachineCommand) to a more generic form supported by the abstract
|
|
@@ -109,12 +152,12 @@ impl Cancellable for UpsertSearchAttributesMachine {}
|
|
|
109
152
|
// Converts the generic history event with type EventType::UpsertWorkflowSearchAttributes into the
|
|
110
153
|
// UpsertSearchAttributesMachine-specific event type
|
|
111
154
|
// UpsertSearchAttributesMachineEvents::CommandRecorded.
|
|
112
|
-
impl TryFrom<
|
|
155
|
+
impl TryFrom<HistEventData> for UpsertSearchAttributesMachineEvents {
|
|
113
156
|
type Error = WFMachinesError;
|
|
114
157
|
|
|
115
|
-
fn try_from(e:
|
|
116
|
-
match e.
|
|
117
|
-
|
|
158
|
+
fn try_from(e: HistEventData) -> Result<Self, Self::Error> {
|
|
159
|
+
match e.event.attributes {
|
|
160
|
+
Some(history_event::Attributes::UpsertWorkflowSearchAttributesEventAttributes(_)) => {
|
|
118
161
|
Ok(UpsertSearchAttributesMachineEvents::CommandRecorded)
|
|
119
162
|
}
|
|
120
163
|
_ => Err(Self::Error::Nondeterminism(format!(
|
|
@@ -141,13 +184,6 @@ impl TryFrom<CommandType> for UpsertSearchAttributesMachineEvents {
|
|
|
141
184
|
}
|
|
142
185
|
}
|
|
143
186
|
|
|
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
187
|
// There is no Command/Response associated with this transition
|
|
152
188
|
impl From<Created> for CommandIssued {
|
|
153
189
|
fn from(_: Created) -> Self {
|
|
@@ -158,12 +194,29 @@ impl From<Created> for CommandIssued {
|
|
|
158
194
|
#[cfg(test)]
|
|
159
195
|
mod tests {
|
|
160
196
|
use super::{super::OnEventWrapper, *};
|
|
161
|
-
use crate::{
|
|
197
|
+
use crate::{
|
|
198
|
+
replay::TestHistoryBuilder,
|
|
199
|
+
test_help::{build_mock_pollers, mock_worker, MockPollCfg, ResponseType},
|
|
200
|
+
worker::{
|
|
201
|
+
client::mocks::mock_workflow_client,
|
|
202
|
+
workflow::{machines::patch_state_machine::VERSION_SEARCH_ATTR_KEY, ManagedWFFunc},
|
|
203
|
+
},
|
|
204
|
+
};
|
|
162
205
|
use rustfsm::StateMachine;
|
|
206
|
+
use std::collections::HashMap;
|
|
163
207
|
use temporal_sdk::{WfContext, WorkflowFunction};
|
|
164
|
-
use
|
|
165
|
-
|
|
208
|
+
use temporal_sdk_core_api::Worker;
|
|
209
|
+
use temporal_sdk_core_protos::{
|
|
210
|
+
coresdk::{
|
|
211
|
+
workflow_commands::SetPatchMarker, workflow_completion::WorkflowActivationCompletion,
|
|
212
|
+
AsJsonPayloadExt,
|
|
213
|
+
},
|
|
214
|
+
temporal::api::{
|
|
215
|
+
command::v1::command::Attributes, common::v1::Payload,
|
|
216
|
+
history::v1::UpsertWorkflowSearchAttributesEventAttributes,
|
|
217
|
+
},
|
|
166
218
|
};
|
|
219
|
+
use temporal_sdk_core_test_utils::WorkerTestHelpers;
|
|
167
220
|
|
|
168
221
|
#[tokio::test]
|
|
169
222
|
async fn upsert_search_attrs_from_workflow() {
|
|
@@ -216,27 +269,115 @@ mod tests {
|
|
|
216
269
|
wfm.shutdown().await.unwrap();
|
|
217
270
|
}
|
|
218
271
|
|
|
219
|
-
#[
|
|
220
|
-
|
|
221
|
-
let mut sm = UpsertSearchAttributesMachine::
|
|
222
|
-
assert_eq!(Created {}.to_string(), sm.state().to_string());
|
|
272
|
+
#[rstest::rstest]
|
|
273
|
+
fn upsert_search_attrs_sm() {
|
|
274
|
+
let mut sm = UpsertSearchAttributesMachine::from_parts(Created {}.into(), SharedState {});
|
|
223
275
|
|
|
224
|
-
let
|
|
225
|
-
|
|
226
|
-
|
|
276
|
+
let sa_attribs = UpsertWorkflowSearchAttributesEventAttributes {
|
|
277
|
+
workflow_task_completed_event_id: 0,
|
|
278
|
+
search_attributes: Some(SearchAttributes {
|
|
279
|
+
indexed_fields: HashMap::from([("Yo".to_string(), Payload::default())]),
|
|
280
|
+
}),
|
|
281
|
+
};
|
|
227
282
|
let recorded_history_event = HistoryEvent {
|
|
228
283
|
event_type: EventType::UpsertWorkflowSearchAttributes as i32,
|
|
284
|
+
attributes: Some(
|
|
285
|
+
history_event::Attributes::UpsertWorkflowSearchAttributesEventAttributes(
|
|
286
|
+
sa_attribs,
|
|
287
|
+
),
|
|
288
|
+
),
|
|
229
289
|
..Default::default()
|
|
230
290
|
};
|
|
231
291
|
assert!(sm.matches_event(&recorded_history_event));
|
|
232
|
-
let cmd_recorded_sm_event =
|
|
292
|
+
let cmd_recorded_sm_event = HistEventData {
|
|
293
|
+
event: recorded_history_event,
|
|
294
|
+
replaying: false,
|
|
295
|
+
current_task_is_last_in_history: true,
|
|
296
|
+
}
|
|
297
|
+
.try_into()
|
|
298
|
+
.unwrap();
|
|
233
299
|
|
|
234
|
-
OnEventWrapper::on_event_mut(
|
|
235
|
-
|
|
300
|
+
OnEventWrapper::on_event_mut(
|
|
301
|
+
&mut sm,
|
|
302
|
+
CommandType::UpsertWorkflowSearchAttributes
|
|
303
|
+
.try_into()
|
|
304
|
+
.unwrap(),
|
|
305
|
+
)
|
|
306
|
+
.expect("CommandScheduled should transition Created -> CommandIssued");
|
|
236
307
|
assert_eq!(CommandIssued {}.to_string(), sm.state().to_string());
|
|
237
308
|
|
|
238
|
-
OnEventWrapper::on_event_mut(&mut sm, cmd_recorded_sm_event)
|
|
239
|
-
|
|
309
|
+
let recorded_res = OnEventWrapper::on_event_mut(&mut sm, cmd_recorded_sm_event);
|
|
310
|
+
recorded_res.expect("CommandRecorded should transition CommandIssued -> Done");
|
|
240
311
|
assert_eq!(Done {}.to_string(), sm.state().to_string());
|
|
241
312
|
}
|
|
313
|
+
|
|
314
|
+
#[rstest::rstest]
|
|
315
|
+
#[tokio::test]
|
|
316
|
+
async fn upserting_change_version_directly(
|
|
317
|
+
#[values(true, false)] flag_in_history: bool,
|
|
318
|
+
#[values(true, false)] with_patched_cmd: bool,
|
|
319
|
+
) {
|
|
320
|
+
let patch_id = "whatever".to_string();
|
|
321
|
+
let mut t = TestHistoryBuilder::default();
|
|
322
|
+
t.add_by_type(EventType::WorkflowExecutionStarted);
|
|
323
|
+
t.add_full_wf_task();
|
|
324
|
+
if flag_in_history {
|
|
325
|
+
t.set_flags_first_wft(
|
|
326
|
+
&[CoreInternalFlags::UpsertSearchAttributeOnPatch as u32],
|
|
327
|
+
&[],
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
if with_patched_cmd {
|
|
331
|
+
t.add_has_change_marker(&patch_id, false);
|
|
332
|
+
}
|
|
333
|
+
t.add_upsert_search_attrs_for_patch(&[patch_id.clone()]);
|
|
334
|
+
t.add_full_wf_task();
|
|
335
|
+
t.add_workflow_execution_completed();
|
|
336
|
+
|
|
337
|
+
let mut mp = MockPollCfg::from_resp_batches(
|
|
338
|
+
"fakeid",
|
|
339
|
+
t,
|
|
340
|
+
[ResponseType::ToTaskNum(1), ResponseType::AllHistory],
|
|
341
|
+
mock_workflow_client(),
|
|
342
|
+
);
|
|
343
|
+
// Ensure the upsert command has an empty map when not using the patched command
|
|
344
|
+
if !with_patched_cmd {
|
|
345
|
+
mp.completion_asserts = Some(Box::new(|wftc| {
|
|
346
|
+
assert_matches!(wftc.commands.get(0).and_then(|c| c.attributes.as_ref()).unwrap(),
|
|
347
|
+
Attributes::UpsertWorkflowSearchAttributesCommandAttributes(attrs)
|
|
348
|
+
if attrs.search_attributes.as_ref().unwrap().indexed_fields.is_empty())
|
|
349
|
+
}));
|
|
350
|
+
}
|
|
351
|
+
let core = mock_worker(build_mock_pollers(mp));
|
|
352
|
+
|
|
353
|
+
let mut ver_upsert = HashMap::new();
|
|
354
|
+
ver_upsert.insert(
|
|
355
|
+
VERSION_SEARCH_ATTR_KEY.to_string(),
|
|
356
|
+
"hi".as_json_payload().unwrap(),
|
|
357
|
+
);
|
|
358
|
+
let act = core.poll_workflow_activation().await.unwrap();
|
|
359
|
+
let mut cmds = if with_patched_cmd {
|
|
360
|
+
vec![SetPatchMarker {
|
|
361
|
+
patch_id,
|
|
362
|
+
deprecated: false,
|
|
363
|
+
}
|
|
364
|
+
.into()]
|
|
365
|
+
} else {
|
|
366
|
+
vec![]
|
|
367
|
+
};
|
|
368
|
+
cmds.push(
|
|
369
|
+
UpsertWorkflowSearchAttributes {
|
|
370
|
+
search_attributes: ver_upsert,
|
|
371
|
+
}
|
|
372
|
+
.into(),
|
|
373
|
+
);
|
|
374
|
+
core.complete_workflow_activation(WorkflowActivationCompletion::from_cmds(
|
|
375
|
+
act.run_id, cmds,
|
|
376
|
+
))
|
|
377
|
+
.await
|
|
378
|
+
.unwrap();
|
|
379
|
+
// Now ensure that encountering the upsert in history works fine
|
|
380
|
+
let act = core.poll_workflow_activation().await.unwrap();
|
|
381
|
+
core.complete_execution(&act.run_id).await;
|
|
382
|
+
}
|
|
242
383
|
}
|