@temporalio/core-bridge 1.7.0 → 1.7.2
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 +500 -400
- 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/client/src/lib.rs +23 -6
- package/sdk-core/client/src/raw.rs +15 -6
- package/sdk-core/core/Cargo.toml +1 -0
- package/sdk-core/core/src/core_tests/activity_tasks.rs +13 -5
- package/sdk-core/core/src/core_tests/determinism.rs +49 -2
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +21 -39
- package/sdk-core/core/src/internal_flags.rs +132 -60
- package/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +10 -7
- package/sdk-core/core/src/worker/activities.rs +152 -142
- package/sdk-core/core/src/worker/client.rs +12 -8
- package/sdk-core/core/src/worker/mod.rs +8 -5
- package/sdk-core/core/src/worker/workflow/history_update.rs +86 -2
- package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +4 -1
- package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +23 -88
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +6 -6
- package/sdk-core/core/src/worker/workflow/managed_run.rs +9 -2
- package/sdk-core/core/src/worker/workflow/mod.rs +22 -8
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +29 -27
- package/sdk-core/protos/api_upstream/.github/workflows/publish-docs.yml +23 -0
- package/sdk-core/protos/api_upstream/Makefile +1 -1
- package/sdk-core/protos/api_upstream/buf.yaml +5 -0
- package/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +17 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +2 -0
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +6 -3
- package/sdk-core/protos/api_upstream/temporal/api/protocol/v1/message.proto +1 -1
- package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +12 -22
- package/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +2 -2
- package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +2 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +145 -48
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +19 -8
- package/sdk-core/test-utils/src/lib.rs +29 -7
- package/sdk-core/tests/integ_tests/activity_functions.rs +5 -0
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +2 -4
- package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +0 -1
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +5 -7
- package/sdk-core/tests/integ_tests/workflow_tests.rs +3 -7
- package/sdk-core/tests/main.rs +16 -24
package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs
CHANGED
|
@@ -38,7 +38,7 @@ fsm! {
|
|
|
38
38
|
// upon observing a history event indicating that the command has been recorded. Note that this
|
|
39
39
|
// does not imply that the command has been _executed_, only that it _will be_ executed at some
|
|
40
40
|
// point in the future.
|
|
41
|
-
CommandIssued --(CommandRecorded
|
|
41
|
+
CommandIssued --(CommandRecorded, on_command_recorded) --> Done;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
/// Instantiates an UpsertSearchAttributesMachine and packs it together with an initial command
|
|
@@ -62,37 +62,21 @@ pub(super) fn upsert_search_attrs(
|
|
|
62
62
|
);
|
|
63
63
|
// We must still create the command to preserve compatability with anyone previously doing
|
|
64
64
|
// this.
|
|
65
|
-
create_new(Default::default()
|
|
65
|
+
create_new(Default::default())
|
|
66
66
|
} else {
|
|
67
|
-
create_new(attribs.search_attributes.into()
|
|
67
|
+
create_new(attribs.search_attributes.into())
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
/// May be used by other state machines / internal needs which desire upserting search attributes.
|
|
72
72
|
pub(super) fn upsert_search_attrs_internal(
|
|
73
73
|
attribs: UpsertWorkflowSearchAttributesCommandAttributes,
|
|
74
|
-
internal_flags: InternalFlagsRef,
|
|
75
74
|
) -> NewMachineWithCommand {
|
|
76
|
-
create_new(
|
|
77
|
-
attribs.search_attributes.unwrap_or_default(),
|
|
78
|
-
true,
|
|
79
|
-
internal_flags,
|
|
80
|
-
)
|
|
75
|
+
create_new(attribs.search_attributes.unwrap_or_default())
|
|
81
76
|
}
|
|
82
77
|
|
|
83
|
-
fn create_new(
|
|
84
|
-
|
|
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
|
-
);
|
|
78
|
+
fn create_new(sa_map: SearchAttributes) -> NewMachineWithCommand {
|
|
79
|
+
let sm = UpsertSearchAttributesMachine::from_parts(Created {}.into(), SharedState {});
|
|
96
80
|
let cmd = Command {
|
|
97
81
|
command_type: CommandType::UpsertWorkflowSearchAttributes as i32,
|
|
98
82
|
attributes: Some(
|
|
@@ -110,11 +94,7 @@ fn create_new(
|
|
|
110
94
|
}
|
|
111
95
|
|
|
112
96
|
#[derive(Clone)]
|
|
113
|
-
pub(super) struct SharedState {
|
|
114
|
-
should_skip_determinism: bool,
|
|
115
|
-
sa_map: SearchAttributes,
|
|
116
|
-
internal_flags: InternalFlagsRef,
|
|
117
|
-
}
|
|
97
|
+
pub(super) struct SharedState {}
|
|
118
98
|
|
|
119
99
|
/// The state-machine-specific set of commands that are the results of state transition in the
|
|
120
100
|
/// UpsertSearchAttributesMachine. There are none of these because this state machine emits the
|
|
@@ -131,30 +111,9 @@ pub(super) struct Created {}
|
|
|
131
111
|
/// higher-level machinery, it transitions into this state.
|
|
132
112
|
#[derive(Debug, Default, Clone, derive_more::Display)]
|
|
133
113
|
pub(super) struct CommandIssued {}
|
|
134
|
-
pub(super) struct CmdRecDat {
|
|
135
|
-
sa_map: Option<SearchAttributes>,
|
|
136
|
-
replaying: bool,
|
|
137
|
-
}
|
|
138
114
|
|
|
139
115
|
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
|
-
}
|
|
116
|
+
pub(super) fn on_command_recorded(self) -> UpsertSearchAttributesMachineTransition<Done> {
|
|
158
117
|
TransitionResult::default()
|
|
159
118
|
}
|
|
160
119
|
}
|
|
@@ -198,14 +157,9 @@ impl TryFrom<HistEventData> for UpsertSearchAttributesMachineEvents {
|
|
|
198
157
|
|
|
199
158
|
fn try_from(e: HistEventData) -> Result<Self, Self::Error> {
|
|
200
159
|
match e.event.attributes {
|
|
201
|
-
Some(history_event::Attributes::UpsertWorkflowSearchAttributesEventAttributes(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
CmdRecDat {
|
|
205
|
-
sa_map: attrs.search_attributes,
|
|
206
|
-
replaying: e.replaying,
|
|
207
|
-
},
|
|
208
|
-
)),
|
|
160
|
+
Some(history_event::Attributes::UpsertWorkflowSearchAttributesEventAttributes(_)) => {
|
|
161
|
+
Ok(UpsertSearchAttributesMachineEvents::CommandRecorded)
|
|
162
|
+
}
|
|
209
163
|
_ => Err(Self::Error::Nondeterminism(format!(
|
|
210
164
|
"UpsertWorkflowSearchAttributesMachine does not handle {e}"
|
|
211
165
|
))),
|
|
@@ -241,7 +195,6 @@ impl From<Created> for CommandIssued {
|
|
|
241
195
|
mod tests {
|
|
242
196
|
use super::{super::OnEventWrapper, *};
|
|
243
197
|
use crate::{
|
|
244
|
-
internal_flags::InternalFlags,
|
|
245
198
|
replay::TestHistoryBuilder,
|
|
246
199
|
test_help::{build_mock_pollers, mock_worker, MockPollCfg, ResponseType},
|
|
247
200
|
worker::{
|
|
@@ -249,8 +202,8 @@ mod tests {
|
|
|
249
202
|
workflow::{machines::patch_state_machine::VERSION_SEARCH_ATTR_KEY, ManagedWFFunc},
|
|
250
203
|
},
|
|
251
204
|
};
|
|
252
|
-
use rustfsm::
|
|
253
|
-
use std::
|
|
205
|
+
use rustfsm::StateMachine;
|
|
206
|
+
use std::collections::HashMap;
|
|
254
207
|
use temporal_sdk::{WfContext, WorkflowFunction};
|
|
255
208
|
use temporal_sdk_core_api::Worker;
|
|
256
209
|
use temporal_sdk_core_protos::{
|
|
@@ -317,25 +270,14 @@ mod tests {
|
|
|
317
270
|
}
|
|
318
271
|
|
|
319
272
|
#[rstest::rstest]
|
|
320
|
-
fn upsert_search_attrs_sm(
|
|
321
|
-
let mut sm = UpsertSearchAttributesMachine::from_parts(
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
},
|
|
328
|
-
);
|
|
329
|
-
|
|
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()
|
|
273
|
+
fn upsert_search_attrs_sm() {
|
|
274
|
+
let mut sm = UpsertSearchAttributesMachine::from_parts(Created {}.into(), SharedState {});
|
|
275
|
+
|
|
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
|
+
}),
|
|
339
281
|
};
|
|
340
282
|
let recorded_history_event = HistoryEvent {
|
|
341
283
|
event_type: EventType::UpsertWorkflowSearchAttributes as i32,
|
|
@@ -365,15 +307,8 @@ mod tests {
|
|
|
365
307
|
assert_eq!(CommandIssued {}.to_string(), sm.state().to_string());
|
|
366
308
|
|
|
367
309
|
let recorded_res = OnEventWrapper::on_event_mut(&mut sm, cmd_recorded_sm_event);
|
|
368
|
-
|
|
369
|
-
|
|
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
|
-
}
|
|
310
|
+
recorded_res.expect("CommandRecorded should transition CommandIssued -> Done");
|
|
311
|
+
assert_eq!(Done {}.to_string(), sm.state().to_string());
|
|
377
312
|
}
|
|
378
313
|
|
|
379
314
|
#[rstest::rstest]
|
|
@@ -331,6 +331,11 @@ impl WorkflowMachines {
|
|
|
331
331
|
/// sent off to the server. They are not removed from the internal queue, that happens when
|
|
332
332
|
/// corresponding history events from the server are being handled.
|
|
333
333
|
pub(crate) fn get_commands(&self) -> Vec<ProtoCommand> {
|
|
334
|
+
// Since we're about to write a WFT, record any internal flags we know about which aren't
|
|
335
|
+
// already recorded.
|
|
336
|
+
(*self.observed_internal_flags)
|
|
337
|
+
.borrow_mut()
|
|
338
|
+
.write_all_known();
|
|
334
339
|
self.commands
|
|
335
340
|
.iter()
|
|
336
341
|
.filter_map(|c| {
|
|
@@ -363,8 +368,6 @@ impl WorkflowMachines {
|
|
|
363
368
|
available_internal_flags: (*self.observed_internal_flags)
|
|
364
369
|
.borrow()
|
|
365
370
|
.all_lang()
|
|
366
|
-
.iter()
|
|
367
|
-
.copied()
|
|
368
371
|
.collect(),
|
|
369
372
|
}
|
|
370
373
|
}
|
|
@@ -924,10 +927,7 @@ impl WorkflowMachines {
|
|
|
924
927
|
}
|
|
925
928
|
ProtoCmdAttrs::UpsertWorkflowSearchAttributesCommandAttributes(attrs) => {
|
|
926
929
|
self.add_cmd_to_wf_task(
|
|
927
|
-
upsert_search_attrs_internal(
|
|
928
|
-
attrs,
|
|
929
|
-
self.observed_internal_flags.clone(),
|
|
930
|
-
),
|
|
930
|
+
upsert_search_attrs_internal(attrs),
|
|
931
931
|
CommandIdKind::NeverResolves,
|
|
932
932
|
);
|
|
933
933
|
}
|
|
@@ -550,8 +550,15 @@ impl ManagedRun {
|
|
|
550
550
|
|
|
551
551
|
/// Delete the currently tracked workflow activation and return it, if any. Should be called
|
|
552
552
|
/// after the processing of the activation completion, and WFT reporting.
|
|
553
|
-
pub(super) fn delete_activation(
|
|
554
|
-
self
|
|
553
|
+
pub(super) fn delete_activation(
|
|
554
|
+
&mut self,
|
|
555
|
+
pred: impl FnOnce(&OutstandingActivation) -> bool,
|
|
556
|
+
) -> Option<OutstandingActivation> {
|
|
557
|
+
if self.activation().map(pred).unwrap_or_default() {
|
|
558
|
+
self.activation.take()
|
|
559
|
+
} else {
|
|
560
|
+
None
|
|
561
|
+
}
|
|
555
562
|
}
|
|
556
563
|
|
|
557
564
|
/// Called when local activities resolve
|
|
@@ -23,8 +23,8 @@ pub(crate) use managed_run::ManagedWFFunc;
|
|
|
23
23
|
|
|
24
24
|
use crate::{
|
|
25
25
|
abstractions::{
|
|
26
|
-
stream_when_allowed, take_cell::TakeCell, MeteredSemaphore,
|
|
27
|
-
UsedMeteredSemPermit,
|
|
26
|
+
dbg_panic, stream_when_allowed, take_cell::TakeCell, MeteredSemaphore,
|
|
27
|
+
TrackedOwnedMeteredSemPermit, UsedMeteredSemPermit,
|
|
28
28
|
},
|
|
29
29
|
internal_flags::InternalFlags,
|
|
30
30
|
protosext::{legacy_query_failure, ValidPollWFTQResponse},
|
|
@@ -294,6 +294,7 @@ impl Workflows {
|
|
|
294
294
|
workflow_completion::Success::from_variants(vec![]).into(),
|
|
295
295
|
),
|
|
296
296
|
},
|
|
297
|
+
true,
|
|
297
298
|
// We need to say a type, but the type is irrelevant, so imagine some
|
|
298
299
|
// boxed function we'll never call.
|
|
299
300
|
Option::<Box<dyn Fn(PostActivateHookData) + Send>>::None,
|
|
@@ -309,6 +310,7 @@ impl Workflows {
|
|
|
309
310
|
run_id,
|
|
310
311
|
status: Some(auto_fail_to_complete_status(machines_err)),
|
|
311
312
|
},
|
|
313
|
+
true,
|
|
312
314
|
Option::<Box<dyn Fn(PostActivateHookData) + Send>>::None,
|
|
313
315
|
)
|
|
314
316
|
.await?;
|
|
@@ -324,8 +326,9 @@ impl Workflows {
|
|
|
324
326
|
pub(super) async fn activation_completed(
|
|
325
327
|
&self,
|
|
326
328
|
completion: WorkflowActivationCompletion,
|
|
329
|
+
is_autocomplete: bool,
|
|
327
330
|
post_activate_hook: Option<impl Fn(PostActivateHookData)>,
|
|
328
|
-
) -> Result<
|
|
331
|
+
) -> Result<(), CompleteWfError> {
|
|
329
332
|
let is_empty_completion = completion.is_empty();
|
|
330
333
|
let completion = validate_completion(completion)?;
|
|
331
334
|
let run_id = completion.run_id().to_string();
|
|
@@ -337,7 +340,7 @@ impl Workflows {
|
|
|
337
340
|
if !was_sent {
|
|
338
341
|
if is_empty_completion {
|
|
339
342
|
// Empty complete which is likely an evict reply, we can just ignore.
|
|
340
|
-
return Ok(
|
|
343
|
+
return Ok(());
|
|
341
344
|
}
|
|
342
345
|
panic!(
|
|
343
346
|
"A non-empty completion was not processed. Workflow processing may have \
|
|
@@ -345,9 +348,18 @@ impl Workflows {
|
|
|
345
348
|
);
|
|
346
349
|
}
|
|
347
350
|
|
|
348
|
-
let completion_outcome = rx
|
|
349
|
-
|
|
350
|
-
|
|
351
|
+
let completion_outcome = if let Ok(c) = rx.await {
|
|
352
|
+
c
|
|
353
|
+
} else {
|
|
354
|
+
dbg_panic!("Send half of activation complete response channel went missing");
|
|
355
|
+
self.request_eviction(
|
|
356
|
+
run_id,
|
|
357
|
+
"Send half of activation complete response channel went missing",
|
|
358
|
+
EvictionReason::Fatal,
|
|
359
|
+
);
|
|
360
|
+
return Ok(());
|
|
361
|
+
};
|
|
362
|
+
|
|
351
363
|
let mut wft_from_complete = None;
|
|
352
364
|
let wft_report_status = match completion_outcome.outcome {
|
|
353
365
|
ActivationCompleteOutcome::ReportWFTSuccess(report) => match report {
|
|
@@ -460,9 +472,10 @@ impl Workflows {
|
|
|
460
472
|
run_id,
|
|
461
473
|
wft_report_status,
|
|
462
474
|
wft_from_complete: maybe_pwft,
|
|
475
|
+
is_autocomplete,
|
|
463
476
|
});
|
|
464
477
|
|
|
465
|
-
Ok(
|
|
478
|
+
Ok(())
|
|
466
479
|
}
|
|
467
480
|
|
|
468
481
|
/// Tell workflow that a local activity has finished with the provided result
|
|
@@ -932,6 +945,7 @@ struct PostActivationMsg {
|
|
|
932
945
|
run_id: String,
|
|
933
946
|
wft_report_status: WFTReportStatus,
|
|
934
947
|
wft_from_complete: Option<(PreparedWFT, HistoryPaginator)>,
|
|
948
|
+
is_autocomplete: bool,
|
|
935
949
|
}
|
|
936
950
|
#[derive(Debug, Clone)]
|
|
937
951
|
#[cfg_attr(
|
|
@@ -338,37 +338,39 @@ impl WFStream {
|
|
|
338
338
|
|
|
339
339
|
// If we reported to server, we always want to mark it complete.
|
|
340
340
|
let maybe_t = self.complete_wft(run_id, report.wft_report_status);
|
|
341
|
-
// Delete the activation
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
.
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
if let Some(
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
341
|
+
// Delete the activation, but only if the report came from lang, or we know the outstanding
|
|
342
|
+
// activation is expected to be completed internally.
|
|
343
|
+
if let Some(activation) = self.runs.get_mut(run_id).and_then(|rh| {
|
|
344
|
+
rh.delete_activation(|act| {
|
|
345
|
+
!report.is_autocomplete || matches!(act, OutstandingActivation::Autocomplete)
|
|
346
|
+
})
|
|
347
|
+
}) {
|
|
348
|
+
// Evict the run if the activation contained an eviction
|
|
349
|
+
let mut applied_buffered_poll_for_this_run = false;
|
|
350
|
+
if activation.has_eviction() {
|
|
351
|
+
debug!(run_id=%run_id, "Evicting run");
|
|
352
|
+
|
|
353
|
+
if let Some(mut rh) = self.runs.remove(run_id) {
|
|
354
|
+
if let Some(buff) = rh.take_buffered_wft() {
|
|
355
|
+
// Don't try to apply a buffered poll for this run if we just got a new WFT
|
|
356
|
+
// from completing, because by definition that buffered poll is now an
|
|
357
|
+
// out-of-date WFT.
|
|
358
|
+
if wft_from_complete.is_none() {
|
|
359
|
+
res = self.instantiate_or_update(buff);
|
|
360
|
+
applied_buffered_poll_for_this_run = true;
|
|
361
|
+
}
|
|
360
362
|
}
|
|
361
363
|
}
|
|
362
|
-
}
|
|
363
364
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
365
|
+
// Attempt to apply a buffered poll for some *other* run, if we didn't have a wft
|
|
366
|
+
// from complete or a buffered poll for *this* run.
|
|
367
|
+
if wft_from_complete.is_none() && !applied_buffered_poll_for_this_run {
|
|
368
|
+
if let Some(buff) = self.buffered_polls_need_cache_slot.pop_front() {
|
|
369
|
+
res = self.instantiate_or_update(buff);
|
|
370
|
+
}
|
|
369
371
|
}
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
+
};
|
|
373
|
+
}
|
|
372
374
|
|
|
373
375
|
if let Some((wft, pag)) = wft_from_complete {
|
|
374
376
|
debug!(run_id=%wft.execution.run_id, "New WFT from completion");
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: Publish docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
|
|
8
|
+
env:
|
|
9
|
+
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
|
|
10
|
+
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
publish:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- name: Checkout repo
|
|
18
|
+
uses: actions/checkout@v3
|
|
19
|
+
- name: Generate docs
|
|
20
|
+
run: |
|
|
21
|
+
docker run -v $(pwd)/docs:/out -v $(pwd)/:/protos pseudomuto/protoc-gen-doc --doc_opt=html,index.html $(find temporal/api -type f -name "*.proto")
|
|
22
|
+
- name: Deploy
|
|
23
|
+
run: npx vercel deploy docs/ --prod --token=${{ secrets.VERCEL_TOKEN }}
|
|
@@ -29,7 +29,7 @@ $(PROTO_OUT):
|
|
|
29
29
|
mkdir $(PROTO_OUT)
|
|
30
30
|
|
|
31
31
|
##### Compile proto files for go #####
|
|
32
|
-
grpc: buf-lint api-linter
|
|
32
|
+
grpc: buf-lint api-linter gogo-grpc fix-path
|
|
33
33
|
|
|
34
34
|
go-grpc: clean $(PROTO_OUT)
|
|
35
35
|
printf $(COLOR) "Compile for go-gRPC..."
|
|
@@ -121,3 +121,20 @@ message MeteringMetadata {
|
|
|
121
121
|
// aip.dev/not-precedent: Negative values make no sense to represent. --)
|
|
122
122
|
uint32 nonfirst_local_activity_execution_attempts = 13;
|
|
123
123
|
}
|
|
124
|
+
|
|
125
|
+
// Identifies the version(s) of a worker that processed a task
|
|
126
|
+
message WorkerVersionStamp {
|
|
127
|
+
// An opaque whole-worker identifier
|
|
128
|
+
string build_id = 1;
|
|
129
|
+
// Set if the worker used a dynamically loadable bundle to process
|
|
130
|
+
// the task. The bundle could be a WASM blob, JS bundle, etc.
|
|
131
|
+
string bundle_id = 2;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Identifies the version(s) that a worker is compatible with when polling or identifying itself
|
|
135
|
+
message WorkerVersionCapabilities {
|
|
136
|
+
// An opaque whole-worker identifier
|
|
137
|
+
string build_id = 1;
|
|
138
|
+
|
|
139
|
+
// Later, may include info like "I can process WASM and/or JS bundles"
|
|
140
|
+
}
|
|
@@ -108,6 +108,8 @@ enum SignalExternalWorkflowExecutionFailedCause {
|
|
|
108
108
|
SIGNAL_EXTERNAL_WORKFLOW_EXECUTION_FAILED_CAUSE_UNSPECIFIED = 0;
|
|
109
109
|
SIGNAL_EXTERNAL_WORKFLOW_EXECUTION_FAILED_CAUSE_EXTERNAL_WORKFLOW_EXECUTION_NOT_FOUND = 1;
|
|
110
110
|
SIGNAL_EXTERNAL_WORKFLOW_EXECUTION_FAILED_CAUSE_NAMESPACE_NOT_FOUND = 2;
|
|
111
|
+
// Signal count limit is per workflow and controlled by server dynamic config "history.maximumSignalsPerExecution"
|
|
112
|
+
SIGNAL_EXTERNAL_WORKFLOW_EXECUTION_FAILED_CAUSE_SIGNAL_COUNT_LIMIT_EXCEEDED = 3;
|
|
111
113
|
}
|
|
112
114
|
|
|
113
115
|
enum ResourceExhaustedCause {
|
|
@@ -193,9 +193,10 @@ message WorkflowTaskCompletedEventAttributes {
|
|
|
193
193
|
string identity = 3;
|
|
194
194
|
// Binary ID of the worker who completed this task
|
|
195
195
|
string binary_checksum = 4;
|
|
196
|
-
//
|
|
197
|
-
// is
|
|
198
|
-
|
|
196
|
+
// Version info of the worker who processed this workflow task, or missing if worker is not
|
|
197
|
+
// using versioning. If present, the `build_id` field within is also used as `binary_checksum`,
|
|
198
|
+
// which may be omitted in that case (it may also be populated to preserve compatibility).
|
|
199
|
+
temporal.api.common.v1.WorkerVersionStamp worker_version = 5;
|
|
199
200
|
// Data the SDK wishes to record for itself, but server need not interpret, and does not
|
|
200
201
|
// directly impact workflow state.
|
|
201
202
|
temporal.api.sdk.v1.WorkflowTaskCompletedMetadata sdk_metadata = 6;
|
|
@@ -409,6 +410,8 @@ message WorkflowExecutionSignaledEventAttributes {
|
|
|
409
410
|
// Headers that were passed by the sender of the signal and copied by temporal
|
|
410
411
|
// server into the workflow task.
|
|
411
412
|
temporal.api.common.v1.Header header = 4;
|
|
413
|
+
// Indicates the signal did not generate a new workflow task when received.
|
|
414
|
+
bool skip_generate_workflow_task = 5;
|
|
412
415
|
}
|
|
413
416
|
|
|
414
417
|
message WorkflowExecutionTerminatedEventAttributes {
|
|
@@ -29,7 +29,7 @@ option java_package = "io.temporal.api.protocol.v1";
|
|
|
29
29
|
option java_multiple_files = true;
|
|
30
30
|
option java_outer_classname = "MessageProto";
|
|
31
31
|
option ruby_package = "Temporalio::Api::Protocol::V1";
|
|
32
|
-
option csharp_namespace = "
|
|
32
|
+
option csharp_namespace = "Temporalio.Api.Protocol.V1";
|
|
33
33
|
|
|
34
34
|
import "google/protobuf/any.proto";
|
|
35
35
|
|
|
@@ -38,6 +38,7 @@ import "google/protobuf/wrappers.proto";
|
|
|
38
38
|
import "dependencies/gogoproto/gogo.proto";
|
|
39
39
|
|
|
40
40
|
import "temporal/api/enums/v1/task_queue.proto";
|
|
41
|
+
import "temporal/api/common/v1/message.proto";
|
|
41
42
|
|
|
42
43
|
// See https://docs.temporal.io/docs/concepts/task-queues/
|
|
43
44
|
message TaskQueue {
|
|
@@ -71,13 +72,12 @@ message TaskQueuePartitionMetadata {
|
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
message PollerInfo {
|
|
74
|
-
// Unix Nano
|
|
75
75
|
google.protobuf.Timestamp last_access_time = 1 [(gogoproto.stdtime) = true];
|
|
76
76
|
string identity = 2;
|
|
77
77
|
double rate_per_second = 3;
|
|
78
|
-
// If a worker has
|
|
79
|
-
//
|
|
80
|
-
|
|
78
|
+
// If a worker has opted into the worker versioning feature while polling, its capabilities will
|
|
79
|
+
// appear here.
|
|
80
|
+
temporal.api.common.v1.WorkerVersionCapabilities worker_version_capabilities = 4;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
message StickyExecutionAttributes {
|
|
@@ -87,22 +87,12 @@ message StickyExecutionAttributes {
|
|
|
87
87
|
google.protobuf.Duration schedule_to_start_timeout = 2 [(gogoproto.stdduration) = true];
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
// Used by the worker versioning APIs, represents
|
|
91
|
-
//
|
|
92
|
-
message
|
|
93
|
-
|
|
94
|
-
//
|
|
95
|
-
|
|
96
|
-
//
|
|
97
|
-
|
|
90
|
+
// Used by the worker versioning APIs, represents an ordering of one or more versions which are
|
|
91
|
+
// considered to be compatible with each other. Currently the versions are always worker build ids.
|
|
92
|
+
message CompatibleVersionSet {
|
|
93
|
+
// A unique identifier for this version set. Users don't need to understand or care about this
|
|
94
|
+
// value, but it has value for debugging purposes.
|
|
95
|
+
string version_set_id = 1;
|
|
96
|
+
// All the compatible versions, ordered from oldest to newest
|
|
97
|
+
repeated string build_ids = 2;
|
|
98
98
|
}
|
|
99
|
-
|
|
100
|
-
// Used by the worker versioning APIs, represents a specific version of something
|
|
101
|
-
// Currently, that's just a whole-worker id. In the future, if we support
|
|
102
|
-
// WASM workflow bundle based versioning, for example, then the inside of this
|
|
103
|
-
// message may become a oneof of different version types.
|
|
104
|
-
message VersionId {
|
|
105
|
-
// An opaque whole-worker identifier
|
|
106
|
-
string worker_build_id = 1;
|
|
107
|
-
}
|
|
108
|
-
|
|
@@ -35,8 +35,8 @@ import "temporal/api/common/v1/message.proto";
|
|
|
35
35
|
import "temporal/api/enums/v1/update.proto";
|
|
36
36
|
import "temporal/api/failure/v1/message.proto";
|
|
37
37
|
|
|
38
|
-
//
|
|
39
|
-
// call to wait before returning control to the caller.
|
|
38
|
+
// Specifies to the gRPC server how long the client wants the an update-related
|
|
39
|
+
// RPC call to wait before returning control to the caller.
|
|
40
40
|
message WaitPolicy {
|
|
41
41
|
|
|
42
42
|
// Indicates the update lifecycle stage that the gRPC call should wait for
|
|
@@ -57,6 +57,8 @@ message WorkflowExecutionInfo {
|
|
|
57
57
|
string task_queue = 13;
|
|
58
58
|
int64 state_transition_count = 14;
|
|
59
59
|
int64 history_size_bytes = 15;
|
|
60
|
+
// If set, the most recent worker version stamp that appeared in a workflow task completion
|
|
61
|
+
temporal.api.common.v1.WorkerVersionStamp most_recent_worker_version_stamp = 16;
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
message WorkflowExecutionConfig {
|