@temporalio/core-bridge 1.5.2 → 1.6.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 +255 -48
- package/package.json +4 -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/pipeline.yml +1 -3
- package/sdk-core/.cargo/config.toml +5 -2
- package/sdk-core/.github/workflows/heavy.yml +28 -0
- package/sdk-core/Cargo.toml +1 -1
- package/sdk-core/README.md +9 -5
- package/sdk-core/client/src/lib.rs +211 -36
- package/sdk-core/client/src/raw.rs +1 -1
- package/sdk-core/client/src/retry.rs +32 -20
- package/sdk-core/core/Cargo.toml +23 -9
- package/sdk-core/core/src/abstractions.rs +11 -0
- package/sdk-core/core/src/core_tests/activity_tasks.rs +6 -5
- package/sdk-core/core/src/core_tests/local_activities.rs +263 -22
- package/sdk-core/core/src/core_tests/queries.rs +2 -2
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +249 -5
- package/sdk-core/core/src/ephemeral_server/mod.rs +5 -6
- package/sdk-core/core/src/lib.rs +2 -0
- package/sdk-core/core/src/protosext/mod.rs +1 -1
- package/sdk-core/core/src/telemetry/log_export.rs +1 -1
- package/sdk-core/core/src/telemetry/mod.rs +23 -8
- package/sdk-core/core/src/test_help/mod.rs +8 -1
- package/sdk-core/core/src/worker/activities/local_activities.rs +259 -125
- package/sdk-core/core/src/worker/activities.rs +3 -2
- package/sdk-core/core/src/worker/mod.rs +53 -26
- 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 +835 -277
- package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +9 -17
- package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +3 -5
- package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +1 -2
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +3 -5
- package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +1 -2
- package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +1 -2
- package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +1 -2
- package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +73 -51
- package/sdk-core/core/src/worker/workflow/machines/mod.rs +3 -3
- package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +4 -4
- package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +1 -2
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +3 -5
- package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +6 -7
- 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 +4 -4
- 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 +89 -58
- package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +4 -7
- package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +21 -9
- package/sdk-core/core/src/worker/workflow/managed_run.rs +1021 -360
- package/sdk-core/core/src/worker/workflow/mod.rs +306 -346
- package/sdk-core/core/src/worker/workflow/run_cache.rs +29 -53
- package/sdk-core/core/src/worker/workflow/wft_extraction.rs +125 -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 +115 -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 +444 -714
- package/sdk-core/core-api/Cargo.toml +2 -0
- package/sdk-core/core-api/src/errors.rs +1 -34
- package/sdk-core/core-api/src/lib.rs +6 -2
- package/sdk-core/core-api/src/worker.rs +14 -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 +6 -6
- package/sdk-core/fsm/rustfsm_trait/src/lib.rs +7 -3
- package/sdk-core/histories/evict_while_la_running_no_interference-16_history.bin +0 -0
- package/sdk-core/protos/api_upstream/Makefile +5 -5
- 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 +12 -19
- package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +2 -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 -2
- 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 +3 -3
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +20 -2
- package/sdk-core/protos/api_upstream/temporal/api/{update/v1/message.proto → enums/v1/interaction_type.proto} +11 -18
- 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 +2 -13
- 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 +13 -19
- package/sdk-core/protos/api_upstream/temporal/api/interaction/v1/message.proto +87 -0
- package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +2 -2
- 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/taskqueue/v1/message.proto +2 -2
- 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 +13 -8
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +2 -2
- package/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +2 -0
- 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 +4 -3
- package/sdk-core/sdk/src/lib.rs +87 -21
- package/sdk-core/sdk/src/workflow_future.rs +7 -12
- 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 +26 -19
- package/sdk-core/sdk-core-protos/src/history_info.rs +4 -0
- package/sdk-core/sdk-core-protos/src/lib.rs +78 -34
- 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/histfetch.rs +1 -1
- package/sdk-core/test-utils/src/lib.rs +50 -18
- 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} +114 -7
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +5 -2
- package/sdk-core/tests/integ_tests/metrics_tests.rs +1 -1
- package/sdk-core/tests/integ_tests/polling_tests.rs +1 -39
- package/sdk-core/tests/integ_tests/queries_tests.rs +2 -127
- package/sdk-core/tests/integ_tests/visibility_tests.rs +52 -5
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +74 -1
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +5 -13
- package/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +2 -10
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +69 -197
- package/sdk-core/tests/integ_tests/workflow_tests/patches.rs +4 -28
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +12 -7
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +14 -14
- package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +3 -19
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +3 -19
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests.rs +5 -6
- package/sdk-core/tests/main.rs +2 -12
- package/sdk-core/tests/runner.rs +71 -34
- package/sdk-core/tests/wf_input_replay.rs +32 -0
- 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
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
mod local_acts;
|
|
2
2
|
|
|
3
|
-
pub(crate) use temporal_sdk_core_api::errors::WFMachinesError;
|
|
4
|
-
|
|
5
3
|
use super::{
|
|
6
4
|
activity_state_machine::new_activity, cancel_external_state_machine::new_external_cancel,
|
|
7
5
|
cancel_workflow_state_machine::cancel_workflow,
|
|
@@ -20,9 +18,10 @@ use crate::{
|
|
|
20
18
|
telemetry::{metrics::MetricsContext, VecDisplayer},
|
|
21
19
|
worker::{
|
|
22
20
|
workflow::{
|
|
21
|
+
history_update::NextWFT,
|
|
23
22
|
machines::modify_workflow_properties_state_machine::modify_workflow_properties,
|
|
24
23
|
CommandID, DrivenWorkflow, HistoryUpdate, LocalResolution, OutgoingJob, WFCommand,
|
|
25
|
-
WorkflowFetcher, WorkflowStartedInfo,
|
|
24
|
+
WFMachinesError, WorkflowFetcher, WorkflowStartedInfo,
|
|
26
25
|
},
|
|
27
26
|
ExecutingLAId, LocalActRequest, LocalActivityExecutionResult, LocalActivityResolution,
|
|
28
27
|
},
|
|
@@ -133,7 +132,7 @@ pub(crate) struct WorkflowMachines {
|
|
|
133
132
|
}
|
|
134
133
|
|
|
135
134
|
#[derive(Debug, derive_more::Display)]
|
|
136
|
-
#[display(fmt = "Cmd&Machine({})"
|
|
135
|
+
#[display(fmt = "Cmd&Machine({command})")]
|
|
137
136
|
struct CommandAndMachine {
|
|
138
137
|
command: MachineAssociatedCommand,
|
|
139
138
|
machine: MachineKey,
|
|
@@ -142,7 +141,7 @@ struct CommandAndMachine {
|
|
|
142
141
|
#[derive(Debug, derive_more::Display)]
|
|
143
142
|
enum MachineAssociatedCommand {
|
|
144
143
|
Real(Box<ProtoCommand>),
|
|
145
|
-
#[display(fmt = "FakeLocalActivityMarker({})"
|
|
144
|
+
#[display(fmt = "FakeLocalActivityMarker({_0})")]
|
|
146
145
|
FakeLocalActivityMarker(u32),
|
|
147
146
|
}
|
|
148
147
|
|
|
@@ -156,7 +155,7 @@ struct ChangeInfo {
|
|
|
156
155
|
#[must_use]
|
|
157
156
|
#[allow(clippy::large_enum_variant)]
|
|
158
157
|
pub(super) enum MachineResponse {
|
|
159
|
-
#[display(fmt = "PushWFJob({})"
|
|
158
|
+
#[display(fmt = "PushWFJob({_0})")]
|
|
160
159
|
PushWFJob(OutgoingJob),
|
|
161
160
|
|
|
162
161
|
/// Pushes a new command into the list that will be sent to server once we respond with the
|
|
@@ -165,31 +164,31 @@ pub(super) enum MachineResponse {
|
|
|
165
164
|
/// The machine requests the creation of another *different* machine. This acts as if lang
|
|
166
165
|
/// had replied to the activation with a command, but we use a special set of IDs to avoid
|
|
167
166
|
/// collisions.
|
|
168
|
-
#[display(fmt = "NewCoreOriginatedCommand({:?})"
|
|
167
|
+
#[display(fmt = "NewCoreOriginatedCommand({_0:?})")]
|
|
169
168
|
NewCoreOriginatedCommand(ProtoCmdAttrs),
|
|
170
|
-
#[display(fmt = "IssueFakeLocalActivityMarker({})"
|
|
169
|
+
#[display(fmt = "IssueFakeLocalActivityMarker({_0})")]
|
|
171
170
|
IssueFakeLocalActivityMarker(u32),
|
|
172
171
|
#[display(fmt = "TriggerWFTaskStarted")]
|
|
173
172
|
TriggerWFTaskStarted {
|
|
174
173
|
task_started_event_id: i64,
|
|
175
174
|
time: SystemTime,
|
|
176
175
|
},
|
|
177
|
-
#[display(fmt = "UpdateRunIdOnWorkflowReset({})"
|
|
176
|
+
#[display(fmt = "UpdateRunIdOnWorkflowReset({run_id})")]
|
|
178
177
|
UpdateRunIdOnWorkflowReset { run_id: String },
|
|
179
178
|
|
|
180
179
|
/// Queue a local activity to be processed by the worker
|
|
181
180
|
#[display(fmt = "QueueLocalActivity")]
|
|
182
181
|
QueueLocalActivity(ValidScheduleLA),
|
|
183
182
|
/// Request cancellation of an executing local activity
|
|
184
|
-
#[display(fmt = "RequestCancelLocalActivity({})"
|
|
183
|
+
#[display(fmt = "RequestCancelLocalActivity({_0})")]
|
|
185
184
|
RequestCancelLocalActivity(u32),
|
|
186
185
|
/// Indicates we are abandoning the indicated LA, so we can remove it from "outstanding" LAs
|
|
187
186
|
/// and we will not try to WFT heartbeat because of it.
|
|
188
|
-
#[display(fmt = "AbandonLocalActivity({:?})"
|
|
187
|
+
#[display(fmt = "AbandonLocalActivity({_0:?})")]
|
|
189
188
|
AbandonLocalActivity(u32),
|
|
190
189
|
|
|
191
190
|
/// Set the workflow time to the provided time
|
|
192
|
-
#[display(fmt = "UpdateWFTime({:?})"
|
|
191
|
+
#[display(fmt = "UpdateWFTime({_0:?})")]
|
|
193
192
|
UpdateWFTime(Option<SystemTime>),
|
|
194
193
|
}
|
|
195
194
|
|
|
@@ -212,7 +211,7 @@ impl WorkflowMachines {
|
|
|
212
211
|
driven_wf: DrivenWorkflow,
|
|
213
212
|
metrics: MetricsContext,
|
|
214
213
|
) -> Self {
|
|
215
|
-
let replaying = history.
|
|
214
|
+
let replaying = history.previous_wft_started_id > 0;
|
|
216
215
|
Self {
|
|
217
216
|
last_history_from_server: history,
|
|
218
217
|
namespace,
|
|
@@ -255,10 +254,10 @@ impl WorkflowMachines {
|
|
|
255
254
|
.and_then(|(st, et)| et.duration_since(st).ok())
|
|
256
255
|
}
|
|
257
256
|
|
|
258
|
-
pub(crate)
|
|
257
|
+
pub(crate) fn new_history_from_server(&mut self, update: HistoryUpdate) -> Result<()> {
|
|
259
258
|
self.last_history_from_server = update;
|
|
260
|
-
self.replaying = self.last_history_from_server.
|
|
261
|
-
self.apply_next_wft_from_history()
|
|
259
|
+
self.replaying = self.last_history_from_server.previous_wft_started_id > 0;
|
|
260
|
+
self.apply_next_wft_from_history()?;
|
|
262
261
|
Ok(())
|
|
263
262
|
}
|
|
264
263
|
|
|
@@ -290,9 +289,8 @@ impl WorkflowMachines {
|
|
|
290
289
|
self.process_machine_responses(mk, resps)?;
|
|
291
290
|
} else {
|
|
292
291
|
return Err(WFMachinesError::Nondeterminism(format!(
|
|
293
|
-
"Command matching activity with seq num {} existed but was not a \
|
|
294
|
-
local activity!"
|
|
295
|
-
seq
|
|
292
|
+
"Command matching activity with seq num {seq} existed but was not a \
|
|
293
|
+
local activity!"
|
|
296
294
|
)));
|
|
297
295
|
}
|
|
298
296
|
self.local_activity_data.done_executing(seq);
|
|
@@ -366,8 +364,8 @@ impl WorkflowMachines {
|
|
|
366
364
|
|
|
367
365
|
/// Iterate the state machines, which consists of grabbing any pending outgoing commands from
|
|
368
366
|
/// the workflow code, handling them, and preparing them to be sent off to the server.
|
|
369
|
-
pub(crate)
|
|
370
|
-
let results = self.drive_me.fetch_workflow_iteration_output()
|
|
367
|
+
pub(crate) fn iterate_machines(&mut self) -> Result<()> {
|
|
368
|
+
let results = self.drive_me.fetch_workflow_iteration_output();
|
|
371
369
|
self.handle_driven_results(results)?;
|
|
372
370
|
self.prepare_commands()?;
|
|
373
371
|
if self.workflow_is_finished() {
|
|
@@ -378,10 +376,16 @@ impl WorkflowMachines {
|
|
|
378
376
|
Ok(())
|
|
379
377
|
}
|
|
380
378
|
|
|
379
|
+
/// Returns true if machines are ready to apply the next WFT sequence, false if events will need
|
|
380
|
+
/// to be fetched in order to create a complete update with the entire next WFT sequence.
|
|
381
|
+
pub(crate) fn ready_to_apply_next_wft(&self) -> bool {
|
|
382
|
+
self.last_history_from_server
|
|
383
|
+
.can_take_next_wft_sequence(self.current_started_event_id)
|
|
384
|
+
}
|
|
385
|
+
|
|
381
386
|
/// Apply the next (unapplied) entire workflow task from history to these machines. Will replay
|
|
382
|
-
/// any events that need to be replayed until caught up to the newest WFT.
|
|
383
|
-
|
|
384
|
-
pub(crate) async fn apply_next_wft_from_history(&mut self) -> Result<usize> {
|
|
387
|
+
/// any events that need to be replayed until caught up to the newest WFT.
|
|
388
|
+
pub(crate) fn apply_next_wft_from_history(&mut self) -> Result<usize> {
|
|
385
389
|
// If we have already seen the terminal event for the entire workflow in a previous WFT,
|
|
386
390
|
// then we don't need to do anything here, and in fact we need to avoid re-applying the
|
|
387
391
|
// final WFT.
|
|
@@ -390,16 +394,25 @@ impl WorkflowMachines {
|
|
|
390
394
|
}
|
|
391
395
|
|
|
392
396
|
let last_handled_wft_started_id = self.current_started_event_id;
|
|
393
|
-
let events =
|
|
394
|
-
|
|
397
|
+
let events =
|
|
398
|
+
match self
|
|
395
399
|
.last_history_from_server
|
|
396
400
|
.take_next_wft_sequence(last_handled_wft_started_id)
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
401
|
+
{
|
|
402
|
+
NextWFT::ReplayOver => {
|
|
403
|
+
vec![]
|
|
404
|
+
}
|
|
405
|
+
NextWFT::WFT(mut evts) => {
|
|
406
|
+
// Do not re-process events we have already processed
|
|
407
|
+
evts.retain(|e| e.event_id > self.last_processed_event);
|
|
408
|
+
evts
|
|
409
|
+
}
|
|
410
|
+
NextWFT::NeedFetch => return Err(WFMachinesError::Fatal(
|
|
411
|
+
"Need to fetch history events to continue applying workflow task, but this \
|
|
412
|
+
should be prevented ahead of time! This is a Core SDK bug."
|
|
413
|
+
.to_string(),
|
|
414
|
+
)),
|
|
415
|
+
};
|
|
403
416
|
let num_events_to_process = events.len();
|
|
404
417
|
|
|
405
418
|
// We're caught up on reply if there are no new events to process
|
|
@@ -434,7 +447,11 @@ impl WorkflowMachines {
|
|
|
434
447
|
|
|
435
448
|
// Scan through to the next WFT, searching for any patch / la markers, so that we can
|
|
436
449
|
// pre-resolve them.
|
|
437
|
-
|
|
450
|
+
let mut wake_las = vec![];
|
|
451
|
+
for e in self
|
|
452
|
+
.last_history_from_server
|
|
453
|
+
.peek_next_wft_sequence(last_handled_wft_started_id)
|
|
454
|
+
{
|
|
438
455
|
if let Some((patch_id, _)) = e.get_patch_marker_details() {
|
|
439
456
|
self.encountered_change_markers.insert(
|
|
440
457
|
patch_id.clone(),
|
|
@@ -448,7 +465,30 @@ impl WorkflowMachines {
|
|
|
448
465
|
.into(),
|
|
449
466
|
);
|
|
450
467
|
} else if e.is_local_activity_marker() {
|
|
451
|
-
|
|
468
|
+
if let Some(la_dat) = e.clone().into_local_activity_marker_details() {
|
|
469
|
+
if let Ok(mk) =
|
|
470
|
+
self.get_machine_key(CommandID::LocalActivity(la_dat.marker_dat.seq))
|
|
471
|
+
{
|
|
472
|
+
wake_las.push((mk, la_dat));
|
|
473
|
+
} else {
|
|
474
|
+
self.local_activity_data.insert_peeked_marker(la_dat);
|
|
475
|
+
}
|
|
476
|
+
} else {
|
|
477
|
+
return Err(WFMachinesError::Fatal(format!(
|
|
478
|
+
"Local activity marker was unparsable: {e:?}"
|
|
479
|
+
)));
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
for (mk, la_dat) in wake_las {
|
|
484
|
+
let mach = self.machine_mut(mk);
|
|
485
|
+
if let Machines::LocalActivityMachine(ref mut lam) = *mach {
|
|
486
|
+
if lam.will_accept_resolve_marker() {
|
|
487
|
+
let resps = lam.try_resolve_with_dat(la_dat.into())?;
|
|
488
|
+
self.process_machine_responses(mk, resps)?;
|
|
489
|
+
} else {
|
|
490
|
+
self.local_activity_data.insert_peeked_marker(la_dat);
|
|
491
|
+
}
|
|
452
492
|
}
|
|
453
493
|
}
|
|
454
494
|
|
|
@@ -488,7 +528,7 @@ impl WorkflowMachines {
|
|
|
488
528
|
}
|
|
489
529
|
if self.replaying
|
|
490
530
|
&& self.current_started_event_id
|
|
491
|
-
>= self.last_history_from_server.
|
|
531
|
+
>= self.last_history_from_server.previous_wft_started_id
|
|
492
532
|
&& event.event_type() != EventType::WorkflowTaskCompleted
|
|
493
533
|
{
|
|
494
534
|
// Replay is finished
|
|
@@ -497,8 +537,7 @@ impl WorkflowMachines {
|
|
|
497
537
|
if event.event_type() == EventType::Unspecified || event.attributes.is_none() {
|
|
498
538
|
return if !event.worker_may_ignore {
|
|
499
539
|
Err(WFMachinesError::Fatal(format!(
|
|
500
|
-
"Event type is unspecified! This history is invalid. Event detail: {:?}"
|
|
501
|
-
event
|
|
540
|
+
"Event type is unspecified! This history is invalid. Event detail: {event:?}"
|
|
502
541
|
)))
|
|
503
542
|
} else {
|
|
504
543
|
debug!("Event is ignorable");
|
|
@@ -526,8 +565,7 @@ impl WorkflowMachines {
|
|
|
526
565
|
None => {
|
|
527
566
|
return Err(WFMachinesError::Nondeterminism(format!(
|
|
528
567
|
"During event handling, this event had an initial command ID but we \
|
|
529
|
-
could not find a matching command for it: {:?}"
|
|
530
|
-
event
|
|
568
|
+
could not find a matching command for it: {event:?}"
|
|
531
569
|
)));
|
|
532
570
|
}
|
|
533
571
|
}
|
|
@@ -550,7 +588,7 @@ impl WorkflowMachines {
|
|
|
550
588
|
fn handle_command_event(&mut self, event: HistoryEvent) -> Result<()> {
|
|
551
589
|
if event.is_local_activity_marker() {
|
|
552
590
|
let deets = event.extract_local_activity_marker_data().ok_or_else(|| {
|
|
553
|
-
WFMachinesError::Fatal(format!("Local activity marker was unparsable: {:?}"
|
|
591
|
+
WFMachinesError::Fatal(format!("Local activity marker was unparsable: {event:?}"))
|
|
554
592
|
})?;
|
|
555
593
|
let cmdid = CommandID::LocalActivity(deets.seq);
|
|
556
594
|
let mkey = self.get_machine_key(cmdid)?;
|
|
@@ -562,8 +600,7 @@ impl WorkflowMachines {
|
|
|
562
600
|
} else {
|
|
563
601
|
return Err(WFMachinesError::Fatal(format!(
|
|
564
602
|
"Encountered local activity marker but the associated machine was of the \
|
|
565
|
-
wrong type! {:?}"
|
|
566
|
-
event
|
|
603
|
+
wrong type! {event:?}"
|
|
567
604
|
)));
|
|
568
605
|
}
|
|
569
606
|
}
|
|
@@ -588,8 +625,7 @@ impl WorkflowMachines {
|
|
|
588
625
|
c
|
|
589
626
|
} else {
|
|
590
627
|
return Err(WFMachinesError::Nondeterminism(format!(
|
|
591
|
-
"No command scheduled for event {}"
|
|
592
|
-
event
|
|
628
|
+
"No command scheduled for event {event}"
|
|
593
629
|
)));
|
|
594
630
|
};
|
|
595
631
|
|
|
@@ -645,8 +681,7 @@ impl WorkflowMachines {
|
|
|
645
681
|
);
|
|
646
682
|
} else {
|
|
647
683
|
return Err(WFMachinesError::Fatal(format!(
|
|
648
|
-
"WorkflowExecutionStarted event did not have appropriate attributes: {}"
|
|
649
|
-
event
|
|
684
|
+
"WorkflowExecutionStarted event did not have appropriate attributes: {event}"
|
|
650
685
|
)));
|
|
651
686
|
}
|
|
652
687
|
}
|
|
@@ -682,8 +717,7 @@ impl WorkflowMachines {
|
|
|
682
717
|
}
|
|
683
718
|
_ => {
|
|
684
719
|
return Err(WFMachinesError::Fatal(format!(
|
|
685
|
-
"The event is not a non-stateful event, but we tried to handle it as one: {}"
|
|
686
|
-
event
|
|
720
|
+
"The event is not a non-stateful event, but we tried to handle it as one: {event}"
|
|
687
721
|
)));
|
|
688
722
|
}
|
|
689
723
|
}
|
|
@@ -756,7 +790,7 @@ impl WorkflowMachines {
|
|
|
756
790
|
) -> Result<()> {
|
|
757
791
|
let sm = self.machine(smk);
|
|
758
792
|
if !machine_responses.is_empty() {
|
|
759
|
-
|
|
793
|
+
trace!(responses = %machine_responses.display(), machine_name = %sm.name(),
|
|
760
794
|
"Machine produced responses");
|
|
761
795
|
}
|
|
762
796
|
self.process_machine_resps_impl(smk, machine_responses)
|
|
@@ -811,8 +845,7 @@ impl WorkflowMachines {
|
|
|
811
845
|
}
|
|
812
846
|
c => {
|
|
813
847
|
return Err(WFMachinesError::Fatal(format!(
|
|
814
|
-
"A machine requested to create a new command of an unsupported type: {:?}"
|
|
815
|
-
c
|
|
848
|
+
"A machine requested to create a new command of an unsupported type: {c:?}"
|
|
816
849
|
)))
|
|
817
850
|
}
|
|
818
851
|
},
|
|
@@ -849,7 +882,7 @@ impl WorkflowMachines {
|
|
|
849
882
|
Duration::from_secs(0),
|
|
850
883
|
removed_act.attempt,
|
|
851
884
|
None,
|
|
852
|
-
|
|
885
|
+
removed_act.original_schedule_time,
|
|
853
886
|
)?;
|
|
854
887
|
self.process_machine_responses(smk, more_responses)?;
|
|
855
888
|
} else {
|
|
@@ -937,8 +970,7 @@ impl WorkflowMachines {
|
|
|
937
970
|
)
|
|
938
971
|
.map_err(|e| {
|
|
939
972
|
WFMachinesError::Fatal(format!(
|
|
940
|
-
"Invalid schedule local activity request (seq {}): {}"
|
|
941
|
-
seq, e
|
|
973
|
+
"Invalid schedule local activity request (seq {seq}): {e}"
|
|
942
974
|
))
|
|
943
975
|
})?;
|
|
944
976
|
let (la, mach_resp) = new_local_activity(
|
|
@@ -1075,7 +1107,7 @@ impl WorkflowMachines {
|
|
|
1075
1107
|
|
|
1076
1108
|
fn get_machine_key(&self, id: CommandID) -> Result<MachineKey> {
|
|
1077
1109
|
Ok(*self.id_to_machine.get(&id).ok_or_else(|| {
|
|
1078
|
-
WFMachinesError::Fatal(format!("Missing associated machine for {:?}"
|
|
1110
|
+
WFMachinesError::Fatal(format!("Missing associated machine for {id:?}"))
|
|
1079
1111
|
})?)
|
|
1080
1112
|
}
|
|
1081
1113
|
|
|
@@ -1173,9 +1205,8 @@ fn change_marker_handling(event: &HistoryEvent, mach: &Machines) -> Result<Chang
|
|
|
1173
1205
|
return Ok(ChangeMarkerOutcome::SkipEvent);
|
|
1174
1206
|
}
|
|
1175
1207
|
return Err(WFMachinesError::Nondeterminism(format!(
|
|
1176
|
-
"Non-deprecated patch marker encountered for change {}, \
|
|
1177
|
-
but there is no corresponding change command!"
|
|
1178
|
-
patch_name
|
|
1208
|
+
"Non-deprecated patch marker encountered for change {patch_name}, \
|
|
1209
|
+
but there is no corresponding change command!"
|
|
1179
1210
|
)));
|
|
1180
1211
|
}
|
|
1181
1212
|
// Patch machines themselves may also not *have* matching markers, where non-deprecated
|
|
@@ -48,7 +48,7 @@ pub(super) enum WFTaskMachineCommand {
|
|
|
48
48
|
task_started_event_id: i64,
|
|
49
49
|
time: SystemTime,
|
|
50
50
|
},
|
|
51
|
-
#[display(fmt = "RunIdOnWorkflowResetUpdate({})"
|
|
51
|
+
#[display(fmt = "RunIdOnWorkflowResetUpdate({run_id})")]
|
|
52
52
|
RunIdOnWorkflowResetUpdate { run_id: String },
|
|
53
53
|
}
|
|
54
54
|
|
|
@@ -121,8 +121,7 @@ impl TryFrom<HistoryEvent> for WorkflowTaskMachineEvents {
|
|
|
121
121
|
}
|
|
122
122
|
} else {
|
|
123
123
|
return Err(WFMachinesError::Fatal(format!(
|
|
124
|
-
"Workflow task started event must contain timestamp: {}"
|
|
125
|
-
e
|
|
124
|
+
"Workflow task started event must contain timestamp: {e}"
|
|
126
125
|
)));
|
|
127
126
|
};
|
|
128
127
|
WFTStartedDat {
|
|
@@ -150,15 +149,13 @@ impl TryFrom<HistoryEvent> for WorkflowTaskMachineEvents {
|
|
|
150
149
|
})
|
|
151
150
|
} else {
|
|
152
151
|
return Err(WFMachinesError::Fatal(format!(
|
|
153
|
-
"Workflow task failed is missing attributes: {}"
|
|
154
|
-
e
|
|
152
|
+
"Workflow task failed is missing attributes: {e}"
|
|
155
153
|
)));
|
|
156
154
|
}
|
|
157
155
|
}
|
|
158
156
|
_ => {
|
|
159
157
|
return Err(WFMachinesError::Nondeterminism(format!(
|
|
160
|
-
"Event does not apply to a wf task machine: {}"
|
|
161
|
-
e
|
|
158
|
+
"Event does not apply to a wf task machine: {e}"
|
|
162
159
|
)))
|
|
163
160
|
}
|
|
164
161
|
})
|
|
@@ -4,11 +4,13 @@ use crate::{
|
|
|
4
4
|
test_help::TEST_Q,
|
|
5
5
|
worker::{
|
|
6
6
|
workflow::{
|
|
7
|
-
history_update::TestHBExt, machines::WorkflowMachines, WFCommand,
|
|
7
|
+
history_update::tests::TestHBExt, machines::WorkflowMachines, WFCommand,
|
|
8
|
+
WorkflowFetcher,
|
|
8
9
|
},
|
|
9
10
|
LocalActRequest, LocalActivityResolution,
|
|
10
11
|
},
|
|
11
12
|
};
|
|
13
|
+
use crossbeam::channel::bounded;
|
|
12
14
|
use std::{convert::TryInto, time::Duration};
|
|
13
15
|
use temporal_sdk::{WorkflowFunction, WorkflowResult};
|
|
14
16
|
use temporal_sdk_core_protos::{
|
|
@@ -27,13 +29,12 @@ use tokio::{
|
|
|
27
29
|
};
|
|
28
30
|
|
|
29
31
|
pub(crate) struct WFFutureDriver {
|
|
30
|
-
|
|
32
|
+
completions_q: crossbeam::channel::Receiver<WorkflowActivationCompletion>,
|
|
31
33
|
}
|
|
32
34
|
|
|
33
|
-
#[async_trait::async_trait]
|
|
34
35
|
impl WorkflowFetcher for WFFutureDriver {
|
|
35
|
-
|
|
36
|
-
if let
|
|
36
|
+
fn fetch_workflow_iteration_output(&mut self) -> Vec<WFCommand> {
|
|
37
|
+
if let Ok(completion) = self.completions_q.try_recv() {
|
|
37
38
|
debug!("Managed wf completion: {}", completion);
|
|
38
39
|
completion
|
|
39
40
|
.status
|
|
@@ -57,6 +58,8 @@ impl WorkflowFetcher for WFFutureDriver {
|
|
|
57
58
|
pub struct ManagedWFFunc {
|
|
58
59
|
mgr: WorkflowManager,
|
|
59
60
|
activation_tx: UnboundedSender<WorkflowActivation>,
|
|
61
|
+
completions_rx: UnboundedReceiver<WorkflowActivationCompletion>,
|
|
62
|
+
completions_sync_tx: crossbeam::channel::Sender<WorkflowActivationCompletion>,
|
|
60
63
|
future_handle: Option<JoinHandle<WorkflowResult<()>>>,
|
|
61
64
|
was_shutdown: bool,
|
|
62
65
|
}
|
|
@@ -79,7 +82,10 @@ impl ManagedWFFunc {
|
|
|
79
82
|
completions_tx,
|
|
80
83
|
);
|
|
81
84
|
let spawned = tokio::spawn(wff);
|
|
82
|
-
let
|
|
85
|
+
let (completions_sync_tx, completions_sync_rx) = bounded(1);
|
|
86
|
+
let driver = WFFutureDriver {
|
|
87
|
+
completions_q: completions_sync_rx,
|
|
88
|
+
};
|
|
83
89
|
let state_machines = WorkflowMachines::new(
|
|
84
90
|
"test_namespace".to_string(),
|
|
85
91
|
"wfid".to_string(),
|
|
@@ -93,6 +99,8 @@ impl ManagedWFFunc {
|
|
|
93
99
|
Self {
|
|
94
100
|
mgr,
|
|
95
101
|
activation_tx: activations,
|
|
102
|
+
completions_rx,
|
|
103
|
+
completions_sync_tx,
|
|
96
104
|
future_handle: Some(spawned),
|
|
97
105
|
was_shutdown: false,
|
|
98
106
|
}
|
|
@@ -100,7 +108,7 @@ impl ManagedWFFunc {
|
|
|
100
108
|
|
|
101
109
|
#[instrument(skip(self))]
|
|
102
110
|
pub(crate) async fn get_next_activation(&mut self) -> Result<WorkflowActivation> {
|
|
103
|
-
let res = self.mgr.get_next_activation()
|
|
111
|
+
let res = self.mgr.get_next_activation()?;
|
|
104
112
|
debug!("Managed wf next activation: {}", &res);
|
|
105
113
|
self.push_activation_to_wf(&res).await?;
|
|
106
114
|
Ok(res)
|
|
@@ -121,7 +129,7 @@ impl ManagedWFFunc {
|
|
|
121
129
|
&mut self,
|
|
122
130
|
update: HistoryUpdate,
|
|
123
131
|
) -> Result<WorkflowActivation> {
|
|
124
|
-
let res = self.mgr.feed_history_from_server(update)
|
|
132
|
+
let res = self.mgr.feed_history_from_server(update)?;
|
|
125
133
|
self.push_activation_to_wf(&res).await?;
|
|
126
134
|
Ok(res)
|
|
127
135
|
}
|
|
@@ -183,7 +191,11 @@ impl ManagedWFFunc {
|
|
|
183
191
|
self.activation_tx
|
|
184
192
|
.send(res.clone())
|
|
185
193
|
.expect("Workflow should not be dropped if we are still sending activations");
|
|
186
|
-
|
|
194
|
+
// Move the completion response to the sync workflow bridge
|
|
195
|
+
self.completions_sync_tx
|
|
196
|
+
.send(self.completions_rx.recv().await.unwrap())
|
|
197
|
+
.unwrap();
|
|
198
|
+
self.mgr.machines.iterate_machines()?;
|
|
187
199
|
Ok(())
|
|
188
200
|
}
|
|
189
201
|
}
|