@temporalio/core-bridge 1.10.3 → 1.11.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 +563 -676
- package/Cargo.toml +3 -3
- package/lib/index.d.ts +16 -5
- package/lib/index.js.map +1 -1
- package/lib/worker-tuner.d.ts +57 -0
- package/lib/worker-tuner.js +3 -0
- package/lib/worker-tuner.js.map +1 -0
- package/package.json +3 -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/.github/workflows/heavy.yml +6 -11
- package/sdk-core/.github/workflows/per-pr.yml +23 -41
- package/sdk-core/Cargo.toml +5 -5
- package/sdk-core/README.md +2 -0
- package/sdk-core/client/Cargo.toml +4 -2
- package/sdk-core/client/src/lib.rs +60 -17
- package/sdk-core/client/src/metrics.rs +1 -1
- package/sdk-core/client/src/proxy.rs +17 -12
- package/sdk-core/client/src/raw.rs +218 -69
- package/sdk-core/client/src/retry.rs +19 -9
- package/sdk-core/core/Cargo.toml +12 -12
- package/sdk-core/core/src/abstractions.rs +3 -3
- package/sdk-core/core/src/core_tests/activity_tasks.rs +2 -1
- package/sdk-core/core/src/core_tests/determinism.rs +1 -1
- package/sdk-core/core/src/core_tests/local_activities.rs +73 -10
- package/sdk-core/core/src/core_tests/queries.rs +2 -1
- package/sdk-core/core/src/core_tests/updates.rs +162 -4
- package/sdk-core/core/src/core_tests/workers.rs +38 -2
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +158 -27
- package/sdk-core/core/src/internal_flags.rs +17 -7
- package/sdk-core/core/src/lib.rs +9 -3
- package/sdk-core/core/src/pollers/poll_buffer.rs +1 -10
- package/sdk-core/core/src/protosext/mod.rs +0 -1
- package/sdk-core/core/src/protosext/protocol_messages.rs +105 -16
- package/sdk-core/core/src/retry_logic.rs +22 -2
- package/sdk-core/core/src/telemetry/otel.rs +44 -12
- package/sdk-core/core/src/test_help/mod.rs +65 -12
- package/sdk-core/core/src/worker/activities/local_activities.rs +1 -4
- package/sdk-core/core/src/worker/activities.rs +3 -4
- package/sdk-core/core/src/worker/client/mocks.rs +7 -6
- package/sdk-core/core/src/worker/client.rs +11 -2
- package/sdk-core/core/src/worker/mod.rs +49 -24
- package/sdk-core/core/src/worker/tuner/resource_based.rs +48 -48
- package/sdk-core/core/src/worker/tuner.rs +124 -4
- package/sdk-core/core/src/worker/workflow/driven_workflow.rs +1 -1
- package/sdk-core/core/src/worker/workflow/history_update.rs +11 -2
- package/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +18 -3
- package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -0
- package/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +1 -0
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +1 -0
- package/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +1 -0
- package/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +1 -0
- package/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +1 -0
- package/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +4 -4
- package/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +1 -0
- package/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +1 -0
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -0
- package/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +3 -1
- package/sdk-core/core/src/worker/workflow/machines/update_state_machine.rs +38 -28
- package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +4 -2
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +95 -71
- package/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +1 -1
- package/sdk-core/core/src/worker/workflow/managed_run.rs +214 -14
- package/sdk-core/core/src/worker/workflow/mod.rs +49 -36
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +1 -2
- package/sdk-core/core-api/src/errors.rs +13 -7
- package/sdk-core/core-api/src/lib.rs +9 -1
- package/sdk-core/sdk/Cargo.toml +1 -1
- package/sdk-core/sdk/src/activity_context.rs +3 -4
- package/sdk-core/sdk/src/lib.rs +96 -49
- package/sdk-core/sdk/src/workflow_context/options.rs +8 -4
- package/sdk-core/sdk/src/workflow_context.rs +53 -49
- package/sdk-core/sdk/src/workflow_future.rs +10 -4
- package/sdk-core/sdk-core-protos/Cargo.toml +4 -3
- package/sdk-core/sdk-core-protos/build.rs +2 -0
- package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/.github/workflows/build.yaml +18 -0
- package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/LICENSE +21 -0
- package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/Makefile +59 -0
- package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/README.md +25 -0
- package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/VERSION +1 -0
- package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/buf.gen.yaml +14 -0
- package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/buf.lock +8 -0
- package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/buf.yaml +9 -0
- package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/temporal/api/cloud/cloudservice/v1/request_response.proto +520 -0
- package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/temporal/api/cloud/cloudservice/v1/service.proto +263 -0
- package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/temporal/api/cloud/identity/v1/message.proto +173 -0
- package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/temporal/api/cloud/namespace/v1/message.proto +164 -0
- package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/temporal/api/cloud/operation/v1/message.proto +36 -0
- package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/temporal/api/cloud/region/v1/message.proto +22 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/.github/workflows/trigger-api-go-update.yml +50 -8
- package/sdk-core/sdk-core-protos/protos/api_upstream/.gitmodules +3 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv2.json +132 -54
- package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv3.yaml +177 -81
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/command/v1/message.proto +13 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +2 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +8 -3
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/history/v1/message.proto +10 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/nexus/v1/message.proto +3 -3
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +6 -6
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/sdk/v1/enhanced_stack_trace.proto +96 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/sdk/v1/user_metadata.proto +49 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/sdk/v1/workflow_metadata.proto +6 -7
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +55 -24
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflow/v1/message.proto +7 -0
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +21 -4
- package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +64 -45
- package/sdk-core/sdk-core-protos/src/history_builder.rs +8 -1
- package/sdk-core/sdk-core-protos/src/lib.rs +40 -10
- package/sdk-core/test-utils/src/canned_histories.rs +1 -1
- package/sdk-core/tests/fuzzy_workflow.rs +4 -2
- package/sdk-core/tests/heavy_tests.rs +3 -3
- package/sdk-core/tests/integ_tests/activity_functions.rs +2 -2
- package/sdk-core/tests/integ_tests/client_tests.rs +234 -6
- package/sdk-core/tests/integ_tests/update_tests.rs +180 -47
- package/sdk-core/tests/integ_tests/worker_tests.rs +32 -0
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +47 -3
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +10 -10
- package/sdk-core/tests/main.rs +1 -0
- package/src/conversions.rs +84 -11
- package/src/runtime.rs +5 -17
- package/src/worker.rs +27 -6
- package/ts/index.ts +24 -5
- package/ts/worker-tuner.ts +71 -0
|
@@ -6,7 +6,7 @@ use crate::{
|
|
|
6
6
|
use itertools::Itertools;
|
|
7
7
|
use prost::EncodeError;
|
|
8
8
|
use rustfsm::{fsm, MachineError, StateMachine, TransitionResult};
|
|
9
|
-
use std::
|
|
9
|
+
use std::convert::TryFrom;
|
|
10
10
|
use temporal_sdk_core_protos::{
|
|
11
11
|
coresdk::{
|
|
12
12
|
workflow_activation::DoUpdate,
|
|
@@ -18,6 +18,7 @@ use temporal_sdk_core_protos::{
|
|
|
18
18
|
enums::v1::{CommandType, EventType},
|
|
19
19
|
failure::v1::Failure,
|
|
20
20
|
protocol::v1::Message as ProtocolMessage,
|
|
21
|
+
update,
|
|
21
22
|
update::v1::{outcome, Acceptance, Outcome, Rejection, Response},
|
|
22
23
|
},
|
|
23
24
|
utilities::pack_any,
|
|
@@ -59,9 +60,9 @@ fsm! {
|
|
|
59
60
|
#[derive(Debug, derive_more::Display)]
|
|
60
61
|
pub(super) enum UpdateMachineCommand {
|
|
61
62
|
#[display(fmt = "Accept")]
|
|
62
|
-
Accept,
|
|
63
|
+
Accept(update::v1::Request),
|
|
63
64
|
#[display(fmt = "Reject")]
|
|
64
|
-
Reject(Failure),
|
|
65
|
+
Reject(update::v1::Request, Failure),
|
|
65
66
|
#[display(fmt = "Complete")]
|
|
66
67
|
Complete(Payload),
|
|
67
68
|
#[display(fmt = "Fail")]
|
|
@@ -73,7 +74,7 @@ pub(super) struct SharedState {
|
|
|
73
74
|
message_id: String,
|
|
74
75
|
instance_id: String,
|
|
75
76
|
event_seq_id: i64,
|
|
76
|
-
|
|
77
|
+
meta: update::v1::Meta,
|
|
77
78
|
}
|
|
78
79
|
|
|
79
80
|
impl UpdateMachine {
|
|
@@ -81,27 +82,31 @@ impl UpdateMachine {
|
|
|
81
82
|
message_id: String,
|
|
82
83
|
instance_id: String,
|
|
83
84
|
event_seq_id: i64,
|
|
84
|
-
|
|
85
|
+
request: UpdateRequest,
|
|
85
86
|
replaying: bool,
|
|
86
87
|
) -> NewMachineWithResponse {
|
|
88
|
+
let meta = request.meta().clone();
|
|
89
|
+
let do_update = DoUpdate {
|
|
90
|
+
id: meta.update_id.clone(),
|
|
91
|
+
protocol_instance_id: instance_id.clone(),
|
|
92
|
+
name: request.name().to_string(),
|
|
93
|
+
input: request.input(),
|
|
94
|
+
headers: request.headers(),
|
|
95
|
+
meta: Some(meta.clone()),
|
|
96
|
+
run_validator: !replaying,
|
|
97
|
+
};
|
|
87
98
|
let me = Self::from_parts(
|
|
88
|
-
RequestInitiated {
|
|
99
|
+
RequestInitiated {
|
|
100
|
+
original_request: request.original,
|
|
101
|
+
}
|
|
102
|
+
.into(),
|
|
89
103
|
SharedState {
|
|
90
104
|
message_id,
|
|
91
|
-
instance_id
|
|
105
|
+
instance_id,
|
|
92
106
|
event_seq_id,
|
|
93
|
-
|
|
107
|
+
meta,
|
|
94
108
|
},
|
|
95
109
|
);
|
|
96
|
-
let do_update = DoUpdate {
|
|
97
|
-
id: mem::replace(&mut request.meta.update_id, "".to_string()),
|
|
98
|
-
protocol_instance_id: instance_id,
|
|
99
|
-
name: request.name,
|
|
100
|
-
input: request.input,
|
|
101
|
-
headers: request.headers,
|
|
102
|
-
meta: Some(request.meta),
|
|
103
|
-
run_validator: !replaying,
|
|
104
|
-
};
|
|
105
110
|
NewMachineWithResponse {
|
|
106
111
|
machine: me.into(),
|
|
107
112
|
response: MachineResponse::PushWFJob(do_update.into()),
|
|
@@ -116,7 +121,7 @@ impl UpdateMachine {
|
|
|
116
121
|
None => {
|
|
117
122
|
return Err(WFMachinesError::Fatal(format!(
|
|
118
123
|
"Update response for update {} had an empty result, this is a lang layer bug.",
|
|
119
|
-
&self.shared_state.
|
|
124
|
+
&self.shared_state.meta.update_id
|
|
120
125
|
)))
|
|
121
126
|
}
|
|
122
127
|
Some(update_response::Response::Accepted(_)) => {
|
|
@@ -132,7 +137,7 @@ impl UpdateMachine {
|
|
|
132
137
|
.map_err(|e| match e {
|
|
133
138
|
MachineError::InvalidTransition => WFMachinesError::Nondeterminism(format!(
|
|
134
139
|
"Invalid transition while handling update response (id {}) in state {}",
|
|
135
|
-
&self.shared_state.
|
|
140
|
+
&self.shared_state.meta.update_id,
|
|
136
141
|
self.state(),
|
|
137
142
|
)),
|
|
138
143
|
MachineError::Underlying(e) => e,
|
|
@@ -231,29 +236,29 @@ impl WFMachinesAdapter for UpdateMachine {
|
|
|
231
236
|
_event_info: Option<EventInfo>,
|
|
232
237
|
) -> Result<Vec<MachineResponse>, WFMachinesError> {
|
|
233
238
|
Ok(match my_command {
|
|
234
|
-
UpdateMachineCommand::Accept => self.build_command_msg(
|
|
239
|
+
UpdateMachineCommand::Accept(orig) => self.build_command_msg(
|
|
235
240
|
format!("{}/accept", self.shared_state.message_id),
|
|
236
241
|
UpdateMsg::Accept(Acceptance {
|
|
237
242
|
accepted_request_message_id: self.shared_state.message_id.clone(),
|
|
238
243
|
accepted_request_sequencing_event_id: self.shared_state.event_seq_id,
|
|
239
|
-
|
|
244
|
+
accepted_request: Some(orig),
|
|
240
245
|
}),
|
|
241
246
|
)?,
|
|
242
|
-
UpdateMachineCommand::Reject(fail) => {
|
|
247
|
+
UpdateMachineCommand::Reject(orig, fail) => {
|
|
243
248
|
vec![self.build_msg(
|
|
244
249
|
format!("{}/reject", self.shared_state.message_id),
|
|
245
250
|
UpdateMsg::Reject(Rejection {
|
|
246
251
|
rejected_request_message_id: self.shared_state.message_id.clone(),
|
|
247
252
|
rejected_request_sequencing_event_id: self.shared_state.event_seq_id,
|
|
253
|
+
rejected_request: Some(orig),
|
|
248
254
|
failure: Some(fail),
|
|
249
|
-
..Default::default()
|
|
250
255
|
}),
|
|
251
256
|
)?]
|
|
252
257
|
}
|
|
253
258
|
UpdateMachineCommand::Complete(p) => self.build_command_msg(
|
|
254
259
|
format!("{}/complete", self.shared_state.message_id),
|
|
255
260
|
UpdateMsg::Response(Response {
|
|
256
|
-
meta: Some(self.shared_state.
|
|
261
|
+
meta: Some(self.shared_state.meta.clone()),
|
|
257
262
|
outcome: Some(Outcome {
|
|
258
263
|
value: Some(outcome::Value::Success(p.into())),
|
|
259
264
|
}),
|
|
@@ -262,7 +267,7 @@ impl WFMachinesAdapter for UpdateMachine {
|
|
|
262
267
|
UpdateMachineCommand::Fail(f) => self.build_command_msg(
|
|
263
268
|
format!("{}/complete", self.shared_state.message_id),
|
|
264
269
|
UpdateMsg::Response(Response {
|
|
265
|
-
meta: Some(self.shared_state.
|
|
270
|
+
meta: Some(self.shared_state.meta.clone()),
|
|
266
271
|
outcome: Some(Outcome {
|
|
267
272
|
value: Some(outcome::Value::Failure(f)),
|
|
268
273
|
}),
|
|
@@ -284,13 +289,18 @@ impl TryFrom<CommandType> for UpdateMachineEvents {
|
|
|
284
289
|
}
|
|
285
290
|
|
|
286
291
|
#[derive(Default, Clone)]
|
|
287
|
-
pub(super) struct RequestInitiated {
|
|
292
|
+
pub(super) struct RequestInitiated {
|
|
293
|
+
original_request: update::v1::Request,
|
|
294
|
+
}
|
|
288
295
|
impl RequestInitiated {
|
|
289
296
|
fn on_accept(self) -> UpdateMachineTransition<Accepted> {
|
|
290
|
-
UpdateMachineTransition::commands([UpdateMachineCommand::Accept])
|
|
297
|
+
UpdateMachineTransition::commands([UpdateMachineCommand::Accept(self.original_request)])
|
|
291
298
|
}
|
|
292
299
|
fn on_reject(self, fail: Failure) -> UpdateMachineTransition<Rejected> {
|
|
293
|
-
UpdateMachineTransition::commands([UpdateMachineCommand::Reject(
|
|
300
|
+
UpdateMachineTransition::commands([UpdateMachineCommand::Reject(
|
|
301
|
+
self.original_request,
|
|
302
|
+
fail,
|
|
303
|
+
)])
|
|
294
304
|
}
|
|
295
305
|
}
|
|
296
306
|
|
package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs
CHANGED
|
@@ -86,6 +86,7 @@ fn create_new(sa_map: SearchAttributes) -> NewMachineWithCommand {
|
|
|
86
86
|
},
|
|
87
87
|
),
|
|
88
88
|
),
|
|
89
|
+
user_metadata: Default::default(),
|
|
89
90
|
};
|
|
90
91
|
NewMachineWithCommand {
|
|
91
92
|
command: cmd,
|
|
@@ -339,7 +340,7 @@ mod tests {
|
|
|
339
340
|
);
|
|
340
341
|
// Ensure the upsert command has an empty map when not using the patched command
|
|
341
342
|
if !with_patched_cmd {
|
|
342
|
-
mp.
|
|
343
|
+
mp.completion_mock_fn = Some(Box::new(|wftc| {
|
|
343
344
|
let cmd_attrs = wftc
|
|
344
345
|
.commands
|
|
345
346
|
.first()
|
|
@@ -349,11 +350,12 @@ mod tests {
|
|
|
349
350
|
cmd_attrs,
|
|
350
351
|
Attributes::CompleteWorkflowExecutionCommandAttributes(_)
|
|
351
352
|
) {
|
|
352
|
-
return;
|
|
353
|
+
return Ok(Default::default());
|
|
353
354
|
}
|
|
354
355
|
assert_matches!(cmd_attrs,
|
|
355
356
|
Attributes::UpsertWorkflowSearchAttributesCommandAttributes(attrs)
|
|
356
357
|
if attrs.search_attributes.clone().unwrap_or_default().indexed_fields.is_empty());
|
|
358
|
+
Ok(Default::default())
|
|
357
359
|
}));
|
|
358
360
|
}
|
|
359
361
|
let mut mock = build_mock_pollers(mp);
|
|
@@ -14,7 +14,7 @@ use super::{
|
|
|
14
14
|
};
|
|
15
15
|
use crate::{
|
|
16
16
|
abstractions::dbg_panic,
|
|
17
|
-
internal_flags::InternalFlags,
|
|
17
|
+
internal_flags::{CoreInternalFlags, InternalFlags},
|
|
18
18
|
protosext::{
|
|
19
19
|
protocol_messages::{IncomingProtocolMessage, IncomingProtocolMessageBody},
|
|
20
20
|
CompleteLocalActivityData, HistoryEventExt, ValidScheduleLA,
|
|
@@ -37,6 +37,7 @@ use crate::{
|
|
|
37
37
|
ExecutingLAId, LocalActRequest, LocalActivityExecutionResult, LocalActivityResolution,
|
|
38
38
|
},
|
|
39
39
|
};
|
|
40
|
+
use anyhow::Context;
|
|
40
41
|
use siphasher::sip::SipHasher13;
|
|
41
42
|
use slotmap::{SlotMap, SparseSecondaryMap};
|
|
42
43
|
use std::{
|
|
@@ -238,7 +239,7 @@ impl WorkflowMachines {
|
|
|
238
239
|
pub(crate) fn new(basics: RunBasics, driven_wf: DrivenWorkflow) -> Self {
|
|
239
240
|
let replaying = basics.history.previous_wft_started_id > 0;
|
|
240
241
|
let mut observed_internal_flags = InternalFlags::new(basics.capabilities);
|
|
241
|
-
// Peek ahead to determine used
|
|
242
|
+
// Peek ahead to determine used flags in the first WFT.
|
|
242
243
|
if let Some(attrs) = basics.history.peek_next_wft_completed(0) {
|
|
243
244
|
observed_internal_flags.add_from_complete(attrs);
|
|
244
245
|
};
|
|
@@ -469,22 +470,30 @@ impl WorkflowMachines {
|
|
|
469
470
|
.add_lang_used(flags);
|
|
470
471
|
}
|
|
471
472
|
|
|
473
|
+
pub(crate) fn try_use_flag(&self, flag: CoreInternalFlags, should_record: bool) -> bool {
|
|
474
|
+
self.observed_internal_flags
|
|
475
|
+
.borrow_mut()
|
|
476
|
+
.try_use(flag, should_record)
|
|
477
|
+
}
|
|
478
|
+
|
|
472
479
|
/// Undo a speculative workflow task by resetting to a certain WFT Started ID. This can happen
|
|
473
480
|
/// when an update request is rejected.
|
|
474
481
|
pub(crate) fn reset_last_started_id(&mut self, id: i64) {
|
|
475
482
|
debug!("Resetting back to event id {} due to speculative WFT", id);
|
|
476
483
|
self.current_started_event_id = id;
|
|
477
|
-
//
|
|
478
|
-
//
|
|
479
|
-
//
|
|
480
|
-
|
|
484
|
+
// We must reset the last event we "processed" to be after the last WFT we really completed
|
|
485
|
+
// + any command events (since the SDK "processed" those when it emitted the commands). This
|
|
486
|
+
// is also equal to what we just processed in the speculative task, minus two, since we
|
|
487
|
+
// would've just handled the most recent WFT started event, and we need to drop that & the
|
|
488
|
+
// schedule event just before it.
|
|
489
|
+
self.last_processed_event -= 2;
|
|
481
490
|
// Then, we have to drop any state machines (which should only be one workflow task machine)
|
|
482
491
|
// we may have created when servicing the speculative task.
|
|
483
492
|
// Remove when https://github.com/rust-lang/rust/issues/59618 is stable
|
|
484
493
|
let remove_these: Vec<_> = self
|
|
485
494
|
.machines_by_event_id
|
|
486
495
|
.iter()
|
|
487
|
-
.filter(|(mid, _)| **mid >
|
|
496
|
+
.filter(|(mid, _)| **mid > self.last_processed_event)
|
|
488
497
|
.map(|(mid, mkey)| (*mid, *mkey))
|
|
489
498
|
.collect();
|
|
490
499
|
for (mid, mkey) in remove_these {
|
|
@@ -526,43 +535,6 @@ impl WorkflowMachines {
|
|
|
526
535
|
return Ok(0);
|
|
527
536
|
}
|
|
528
537
|
|
|
529
|
-
fn get_processable_messages(
|
|
530
|
-
me: &mut WorkflowMachines,
|
|
531
|
-
for_event_id: i64,
|
|
532
|
-
) -> Vec<IncomingProtocolMessage> {
|
|
533
|
-
// Another thing to replace when `drain_filter` exists
|
|
534
|
-
let mut ret = vec![];
|
|
535
|
-
me.protocol_msgs = std::mem::take(&mut me.protocol_msgs)
|
|
536
|
-
.into_iter()
|
|
537
|
-
.filter_map(|x| {
|
|
538
|
-
if x.processable_after_event_id()
|
|
539
|
-
.is_some_and(|eid| eid <= for_event_id)
|
|
540
|
-
{
|
|
541
|
-
ret.push(x);
|
|
542
|
-
None
|
|
543
|
-
} else {
|
|
544
|
-
Some(x)
|
|
545
|
-
}
|
|
546
|
-
})
|
|
547
|
-
.collect();
|
|
548
|
-
ret
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
// Peek to the next WFT complete and update ourselves with data we might need in it.
|
|
552
|
-
if let Some(next_complete) = self
|
|
553
|
-
.last_history_from_server
|
|
554
|
-
.peek_next_wft_completed(self.last_processed_event)
|
|
555
|
-
{
|
|
556
|
-
// We update the internal flags before applying the current task
|
|
557
|
-
(*self.observed_internal_flags)
|
|
558
|
-
.borrow_mut()
|
|
559
|
-
.add_from_complete(next_complete);
|
|
560
|
-
// Save this tasks' Build ID if it had one
|
|
561
|
-
if let Some(bid) = next_complete.worker_version.as_ref().map(|wv| &wv.build_id) {
|
|
562
|
-
self.current_wft_build_id = Some(bid.to_string());
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
|
|
566
538
|
let last_handled_wft_started_id = self.current_started_event_id;
|
|
567
539
|
let (events, has_final_event) = match self
|
|
568
540
|
.last_history_from_server
|
|
@@ -584,7 +556,37 @@ impl WorkflowMachines {
|
|
|
584
556
|
};
|
|
585
557
|
let num_events_to_process = events.len();
|
|
586
558
|
|
|
587
|
-
//
|
|
559
|
+
// Process any WFT completed events in the next sequence, as well as peek ahead to the
|
|
560
|
+
// subsequent one to properly apply flags & any other data. Macro used to avoid self
|
|
561
|
+
// double-borrow.
|
|
562
|
+
macro_rules! apply_wft_complete_data {
|
|
563
|
+
($me:expr, $wtc:expr) => {{
|
|
564
|
+
(*$me.observed_internal_flags)
|
|
565
|
+
.borrow_mut()
|
|
566
|
+
.add_from_complete($wtc);
|
|
567
|
+
if let Some(bid) = $wtc.worker_version.as_ref().map(|wv| &wv.build_id) {
|
|
568
|
+
$me.current_wft_build_id = Some(bid.to_string());
|
|
569
|
+
}
|
|
570
|
+
}};
|
|
571
|
+
}
|
|
572
|
+
let mut peeked_events = events.iter().peekable();
|
|
573
|
+
while let Some(event) = peeked_events.next() {
|
|
574
|
+
if let Some(history_event::Attributes::WorkflowTaskCompletedEventAttributes(ref wtc)) =
|
|
575
|
+
event.attributes
|
|
576
|
+
{
|
|
577
|
+
apply_wft_complete_data!(self, wtc);
|
|
578
|
+
}
|
|
579
|
+
if peeked_events.peek().is_none() {
|
|
580
|
+
if let Some(wtc) = self
|
|
581
|
+
.last_history_from_server
|
|
582
|
+
.peek_next_wft_completed(event.event_id)
|
|
583
|
+
{
|
|
584
|
+
apply_wft_complete_data!(self, wtc);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
// We're caught up on replay if there are no new events to process
|
|
588
590
|
if events.is_empty() {
|
|
589
591
|
self.replaying = false;
|
|
590
592
|
}
|
|
@@ -596,6 +598,7 @@ impl WorkflowMachines {
|
|
|
596
598
|
}
|
|
597
599
|
}
|
|
598
600
|
|
|
601
|
+
let mut update_admitted_event_messages = HashMap::<String, IncomingProtocolMessage>::new();
|
|
599
602
|
let mut do_handle_event = true;
|
|
600
603
|
let mut history = events.into_iter().peekable();
|
|
601
604
|
while let Some(event) = history.next() {
|
|
@@ -628,8 +631,42 @@ impl WorkflowMachines {
|
|
|
628
631
|
self.replaying = false;
|
|
629
632
|
}
|
|
630
633
|
|
|
634
|
+
if matches!(
|
|
635
|
+
event.attributes,
|
|
636
|
+
Some(history_event::Attributes::WorkflowExecutionUpdateAdmittedEventAttributes(_)),
|
|
637
|
+
) {
|
|
638
|
+
// The server has sent a durable update admitted event: create the message that would have been sent
|
|
639
|
+
// for a non-durable update request message.
|
|
640
|
+
let msg = IncomingProtocolMessage::try_from(&event).context(
|
|
641
|
+
"Failed to create protocol message from WorkflowExecutionUpdateAdmittedEvent",
|
|
642
|
+
)?;
|
|
643
|
+
if self.replaying {
|
|
644
|
+
// Stash the message for use if the update request is accepted.
|
|
645
|
+
update_admitted_event_messages.insert(msg.protocol_instance_id.clone(), msg);
|
|
646
|
+
} else {
|
|
647
|
+
// Use the message now.
|
|
648
|
+
self.protocol_msgs.push(msg);
|
|
649
|
+
}
|
|
650
|
+
do_handle_event = false;
|
|
651
|
+
}
|
|
652
|
+
|
|
631
653
|
// Process any messages that should be processed before the event we're about to handle
|
|
632
|
-
let
|
|
654
|
+
let for_event_id = eid - 1;
|
|
655
|
+
// Another thing to replace when `drain_filter` exists
|
|
656
|
+
let mut processable_msgs = vec![];
|
|
657
|
+
self.protocol_msgs = std::mem::take(&mut self.protocol_msgs)
|
|
658
|
+
.into_iter()
|
|
659
|
+
.filter_map(|x| {
|
|
660
|
+
if x.processable_after_event_id()
|
|
661
|
+
.is_some_and(|eid| eid <= for_event_id)
|
|
662
|
+
{
|
|
663
|
+
processable_msgs.push(x);
|
|
664
|
+
None
|
|
665
|
+
} else {
|
|
666
|
+
Some(x)
|
|
667
|
+
}
|
|
668
|
+
})
|
|
669
|
+
.collect();
|
|
633
670
|
for msg in processable_msgs {
|
|
634
671
|
self.handle_protocol_message(msg)?;
|
|
635
672
|
}
|
|
@@ -699,26 +736,16 @@ impl WorkflowMachines {
|
|
|
699
736
|
history_event::Attributes::WorkflowExecutionUpdateAcceptedEventAttributes(ref atts),
|
|
700
737
|
) = e.attributes
|
|
701
738
|
{
|
|
702
|
-
//
|
|
703
|
-
//
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
.clone()
|
|
713
|
-
.ok_or_else(|| {
|
|
714
|
-
WFMachinesError::Fatal(
|
|
715
|
-
"Update accepted event must contain accepted request"
|
|
716
|
-
.to_string(),
|
|
717
|
-
)
|
|
718
|
-
})?
|
|
719
|
-
.try_into()?,
|
|
720
|
-
),
|
|
721
|
-
}));
|
|
739
|
+
// We've encountered an UpdateAccepted event during replay: pretend that we received the message we
|
|
740
|
+
// would have when receiving an update request under not-replay. If this event was preceded by an
|
|
741
|
+
// UpdateAdmitted event, then use the message that we created when we encountered that.
|
|
742
|
+
delayed_actions.push(DelayedAction::ProtocolMessage(
|
|
743
|
+
update_admitted_event_messages
|
|
744
|
+
.remove(&atts.protocol_instance_id)
|
|
745
|
+
.map_or_else(|| e.try_into().context(
|
|
746
|
+
"Failed to create protocol message from WorkflowExecutionUpdateAcceptedEvent",
|
|
747
|
+
), Ok)?,
|
|
748
|
+
));
|
|
722
749
|
}
|
|
723
750
|
}
|
|
724
751
|
for action in delayed_actions {
|
|
@@ -780,10 +807,7 @@ impl WorkflowMachines {
|
|
|
780
807
|
Ok(EventHandlingOutcome::Normal)
|
|
781
808
|
};
|
|
782
809
|
}
|
|
783
|
-
if event.event_type() == EventType::Unspecified
|
|
784
|
-
|| event.event_type() == EventType::WorkflowExecutionUpdateAdmitted
|
|
785
|
-
|| event.attributes.is_none()
|
|
786
|
-
{
|
|
810
|
+
if event.event_type() == EventType::Unspecified || event.attributes.is_none() {
|
|
787
811
|
return if !event.worker_may_ignore {
|
|
788
812
|
Err(WFMachinesError::Fatal(format!(
|
|
789
813
|
"Event type is unspecified! This history is invalid. Event detail: {event:?}"
|
|
@@ -910,7 +934,7 @@ impl WorkflowMachines {
|
|
|
910
934
|
attrs,
|
|
911
935
|
)) = event_dat.event.attributes
|
|
912
936
|
{
|
|
913
|
-
if let Some(st) = event_dat.event.event_time
|
|
937
|
+
if let Some(st) = event_dat.event.event_time {
|
|
914
938
|
let as_systime: SystemTime = st.try_into()?;
|
|
915
939
|
self.workflow_start_time = Some(as_systime);
|
|
916
940
|
// Set the workflow time to be the event time of the first event, so that
|
|
@@ -98,7 +98,7 @@ impl TryFrom<HistEventData> for WorkflowTaskMachineEvents {
|
|
|
98
98
|
Ok(match e.event_type() {
|
|
99
99
|
EventType::WorkflowTaskScheduled => Self::WorkflowTaskScheduled,
|
|
100
100
|
EventType::WorkflowTaskStarted => Self::WorkflowTaskStarted({
|
|
101
|
-
let time = if let Some(time) = e.event_time
|
|
101
|
+
let time = if let Some(time) = e.event_time {
|
|
102
102
|
match time.try_into() {
|
|
103
103
|
Ok(t) => t,
|
|
104
104
|
Err(_) => {
|