@temporalio/core-bridge 1.1.0 → 1.4.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 +765 -128
- package/Cargo.toml +2 -2
- package/common.js +7 -3
- package/index.d.ts +118 -5
- package/index.js +2 -6
- package/package.json +2 -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/scripts/build.js +4 -3
- package/sdk-core/.buildkite/docker/Dockerfile +2 -1
- package/sdk-core/.buildkite/pipeline.yml +2 -0
- package/sdk-core/.cargo/config.toml +1 -1
- package/sdk-core/ARCHITECTURE.md +2 -2
- package/sdk-core/README.md +12 -0
- package/sdk-core/bridge-ffi/Cargo.toml +2 -2
- package/sdk-core/bridge-ffi/src/lib.rs +2 -2
- package/sdk-core/client/Cargo.toml +7 -5
- package/sdk-core/client/src/lib.rs +354 -226
- package/sdk-core/client/src/metrics.rs +13 -11
- package/sdk-core/client/src/raw.rs +352 -107
- package/sdk-core/client/src/retry.rs +188 -147
- package/sdk-core/client/src/workflow_handle/mod.rs +1 -1
- package/sdk-core/core/Cargo.toml +28 -15
- package/sdk-core/core/src/core_tests/activity_tasks.rs +98 -33
- package/sdk-core/core/src/core_tests/child_workflows.rs +125 -3
- package/sdk-core/core/src/core_tests/local_activities.rs +6 -6
- package/sdk-core/core/src/core_tests/workers.rs +3 -2
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +70 -2
- package/sdk-core/core/src/ephemeral_server/mod.rs +515 -0
- package/sdk-core/core/src/lib.rs +62 -28
- package/sdk-core/core/src/pollers/mod.rs +2 -0
- package/sdk-core/core/src/pollers/poll_buffer.rs +4 -4
- package/sdk-core/core/src/replay/mod.rs +3 -3
- package/sdk-core/core/src/retry_logic.rs +10 -9
- package/sdk-core/core/src/telemetry/metrics.rs +48 -39
- package/sdk-core/core/src/telemetry/mod.rs +46 -12
- package/sdk-core/core/src/telemetry/prometheus_server.rs +17 -13
- package/sdk-core/core/src/test_help/mod.rs +18 -8
- package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +10 -10
- package/sdk-core/core/src/worker/activities/local_activities.rs +13 -13
- package/sdk-core/core/src/worker/activities.rs +6 -12
- package/sdk-core/core/src/worker/client/mocks.rs +1 -0
- package/sdk-core/core/src/worker/client.rs +193 -64
- package/sdk-core/core/src/worker/mod.rs +14 -19
- package/sdk-core/core/src/worker/workflow/driven_workflow.rs +3 -0
- package/sdk-core/core/src/worker/workflow/history_update.rs +5 -5
- package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +133 -85
- package/sdk-core/core/src/worker/workflow/machines/mod.rs +3 -2
- package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +160 -105
- package/sdk-core/core/src/worker/workflow/managed_run.rs +2 -1
- package/sdk-core/core/src/worker/workflow/mod.rs +62 -58
- package/sdk-core/core/src/worker/workflow/run_cache.rs +5 -3
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +7 -5
- package/sdk-core/core-api/Cargo.toml +3 -3
- package/sdk-core/core-api/src/errors.rs +3 -11
- package/sdk-core/core-api/src/worker.rs +7 -0
- package/sdk-core/protos/api_upstream/.buildkite/Dockerfile +1 -1
- package/sdk-core/protos/api_upstream/.github/CODEOWNERS +1 -1
- package/sdk-core/protos/api_upstream/.github/PULL_REQUEST_TEMPLATE.md +2 -6
- package/sdk-core/protos/api_upstream/.github/workflows/trigger-api-go-update.yml +29 -0
- package/sdk-core/protos/api_upstream/Makefile +2 -2
- package/sdk-core/protos/api_upstream/buf.yaml +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/batch/v1/message.proto +86 -0
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +26 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +46 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +7 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +14 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +51 -0
- package/sdk-core/protos/api_upstream/temporal/api/failure/v1/message.proto +18 -0
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +57 -1
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +1 -3
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +4 -2
- package/sdk-core/protos/api_upstream/temporal/api/replication/v1/message.proto +11 -0
- package/sdk-core/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +23 -0
- package/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +46 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +1 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +172 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +30 -0
- package/sdk-core/protos/grpc/health/v1/health.proto +63 -0
- package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +18 -15
- package/sdk-core/protos/testsrv_upstream/Makefile +80 -0
- package/sdk-core/protos/testsrv_upstream/api-linter.yaml +38 -0
- package/sdk-core/protos/testsrv_upstream/buf.yaml +13 -0
- package/sdk-core/protos/testsrv_upstream/dependencies/gogoproto/gogo.proto +141 -0
- package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/request_response.proto +63 -0
- package/sdk-core/protos/testsrv_upstream/temporal/api/testservice/v1/service.proto +90 -0
- package/sdk-core/sdk/Cargo.toml +2 -2
- package/sdk-core/sdk/src/lib.rs +2 -2
- package/sdk-core/sdk/src/workflow_context/options.rs +36 -8
- package/sdk-core/sdk/src/workflow_context.rs +30 -6
- package/sdk-core/sdk/src/workflow_future.rs +4 -4
- package/sdk-core/sdk-core-protos/Cargo.toml +5 -5
- package/sdk-core/sdk-core-protos/build.rs +9 -1
- package/sdk-core/sdk-core-protos/src/history_builder.rs +6 -1
- package/sdk-core/sdk-core-protos/src/lib.rs +93 -32
- package/sdk-core/test-utils/Cargo.toml +3 -3
- package/sdk-core/test-utils/src/canned_histories.rs +58 -0
- package/sdk-core/test-utils/src/lib.rs +35 -12
- package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +128 -0
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +55 -5
- package/sdk-core/tests/integ_tests/polling_tests.rs +2 -1
- package/sdk-core/tests/integ_tests/queries_tests.rs +5 -5
- package/sdk-core/tests/integ_tests/visibility_tests.rs +93 -0
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +93 -10
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +14 -14
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +2 -6
- package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +12 -12
- package/sdk-core/tests/integ_tests/workflow_tests/signals.rs +12 -1
- package/sdk-core/tests/integ_tests/workflow_tests/timers.rs +3 -3
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +8 -2
- package/sdk-core/tests/integ_tests/workflow_tests.rs +19 -4
- package/sdk-core/tests/load_tests.rs +2 -1
- package/sdk-core/tests/main.rs +17 -0
- package/sdk-core/tests/runner.rs +93 -0
- package/src/conversions.rs +157 -94
- package/src/helpers.rs +190 -0
- package/src/lib.rs +10 -912
- package/src/runtime.rs +436 -0
- package/src/testing.rs +67 -0
- package/src/worker.rs +465 -0
|
@@ -24,7 +24,7 @@ use crate::{
|
|
|
24
24
|
telemetry::VecDisplayer,
|
|
25
25
|
worker::{
|
|
26
26
|
activities::{ActivitiesFromWFTsHandle, PermittedTqResp},
|
|
27
|
-
client::
|
|
27
|
+
client::WorkerClient,
|
|
28
28
|
workflow::{
|
|
29
29
|
managed_run::{ManagedRun, WorkflowManager},
|
|
30
30
|
wft_poller::validate_wft,
|
|
@@ -32,7 +32,7 @@ use crate::{
|
|
|
32
32
|
},
|
|
33
33
|
LocalActRequest, LocalActivityResolution,
|
|
34
34
|
},
|
|
35
|
-
MetricsContext,
|
|
35
|
+
MetricsContext,
|
|
36
36
|
};
|
|
37
37
|
use futures::{stream::BoxStream, Stream, StreamExt};
|
|
38
38
|
use std::{
|
|
@@ -58,6 +58,7 @@ use temporal_sdk_core_protos::{
|
|
|
58
58
|
},
|
|
59
59
|
temporal::api::{
|
|
60
60
|
command::v1::{command::Attributes, Command as ProtoCommand, Command},
|
|
61
|
+
common::v1::{Memo, RetryPolicy, SearchAttributes},
|
|
61
62
|
enums::v1::WorkflowTaskFailedCause,
|
|
62
63
|
taskqueue::v1::StickyExecutionAttributes,
|
|
63
64
|
workflowservice::v1::PollActivityTaskQueueResponse,
|
|
@@ -77,12 +78,14 @@ use tokio_util::sync::CancellationToken;
|
|
|
77
78
|
use tracing::Span;
|
|
78
79
|
|
|
79
80
|
pub(crate) const LEGACY_QUERY_ID: &str = "legacy_query";
|
|
81
|
+
const MAX_EAGER_ACTIVITY_RESERVATIONS_PER_WORKFLOW_TASK: usize = 3;
|
|
80
82
|
|
|
81
83
|
type Result<T, E = WFMachinesError> = result::Result<T, E>;
|
|
82
84
|
type BoxedActivationStream = BoxStream<'static, Result<ActivationOrAuto, PollWfError>>;
|
|
83
85
|
|
|
84
86
|
/// Centralizes all state related to workflows and workflow tasks
|
|
85
87
|
pub(crate) struct Workflows {
|
|
88
|
+
task_queue: String,
|
|
86
89
|
local_tx: UnboundedSender<LocalInput>,
|
|
87
90
|
processing_task: tokio::sync::Mutex<Option<JoinHandle<()>>>,
|
|
88
91
|
activation_stream: tokio::sync::Mutex<(
|
|
@@ -90,7 +93,7 @@ pub(crate) struct Workflows {
|
|
|
90
93
|
// Used to indicate polling may begin
|
|
91
94
|
Option<oneshot::Sender<()>>,
|
|
92
95
|
)>,
|
|
93
|
-
client: Arc<
|
|
96
|
+
client: Arc<dyn WorkerClient>,
|
|
94
97
|
/// Will be populated when this worker is using a cache and should complete WFTs with a sticky
|
|
95
98
|
/// queue.
|
|
96
99
|
sticky_attrs: Option<StickyExecutionAttributes>,
|
|
@@ -103,13 +106,15 @@ pub(super) struct WorkflowBasics {
|
|
|
103
106
|
pub max_outstanding_wfts: usize,
|
|
104
107
|
pub shutdown_token: CancellationToken,
|
|
105
108
|
pub metrics: MetricsContext,
|
|
109
|
+
pub namespace: String,
|
|
110
|
+
pub task_queue: String,
|
|
106
111
|
}
|
|
107
112
|
|
|
108
113
|
impl Workflows {
|
|
109
114
|
pub(super) fn new(
|
|
110
115
|
basics: WorkflowBasics,
|
|
111
116
|
sticky_attrs: Option<StickyExecutionAttributes>,
|
|
112
|
-
client: Arc<
|
|
117
|
+
client: Arc<dyn WorkerClient>,
|
|
113
118
|
wft_stream: impl Stream<Item = Result<ValidPollWFTQResponse, tonic::Status>> + Send + 'static,
|
|
114
119
|
local_activity_request_sink: impl Fn(Vec<LocalActRequest>) -> Vec<LocalActivityResolution>
|
|
115
120
|
+ Send
|
|
@@ -119,6 +124,7 @@ impl Workflows {
|
|
|
119
124
|
) -> Self {
|
|
120
125
|
let (local_tx, local_rx) = unbounded_channel();
|
|
121
126
|
let shutdown_tok = basics.shutdown_token.clone();
|
|
127
|
+
let task_queue = basics.task_queue.clone();
|
|
122
128
|
let mut stream = WFStream::build(
|
|
123
129
|
basics,
|
|
124
130
|
wft_stream,
|
|
@@ -151,6 +157,7 @@ impl Workflows {
|
|
|
151
157
|
}
|
|
152
158
|
});
|
|
153
159
|
Self {
|
|
160
|
+
task_queue,
|
|
154
161
|
local_tx,
|
|
155
162
|
processing_task: tokio::sync::Mutex::new(Some(processing_task)),
|
|
156
163
|
activation_stream: tokio::sync::Mutex::new((
|
|
@@ -263,14 +270,14 @@ impl Workflows {
|
|
|
263
270
|
);
|
|
264
271
|
Ok(())
|
|
265
272
|
})
|
|
266
|
-
.await
|
|
273
|
+
.await;
|
|
267
274
|
true
|
|
268
275
|
}
|
|
269
276
|
ServerCommandsWithWorkflowInfo {
|
|
270
277
|
task_token,
|
|
271
278
|
action: ActivationAction::RespondLegacyQuery { result },
|
|
272
279
|
} => {
|
|
273
|
-
self.respond_legacy_query(task_token, result).await
|
|
280
|
+
self.respond_legacy_query(task_token, *result).await;
|
|
274
281
|
true
|
|
275
282
|
}
|
|
276
283
|
},
|
|
@@ -282,13 +289,13 @@ impl Workflows {
|
|
|
282
289
|
.fail_workflow_task(tt, cause, failure.failure.map(Into::into))
|
|
283
290
|
.await
|
|
284
291
|
})
|
|
285
|
-
.await
|
|
292
|
+
.await;
|
|
286
293
|
true
|
|
287
294
|
}
|
|
288
295
|
FailedActivationWFTReport::ReportLegacyQueryFailure(task_token, failure) => {
|
|
289
296
|
warn!(run_id=%run_id, failure=?failure, "Failing legacy query request");
|
|
290
297
|
self.respond_legacy_query(task_token, legacy_query_failure(failure))
|
|
291
|
-
.await
|
|
298
|
+
.await;
|
|
292
299
|
true
|
|
293
300
|
}
|
|
294
301
|
},
|
|
@@ -350,47 +357,34 @@ impl Workflows {
|
|
|
350
357
|
self.send_local(msg);
|
|
351
358
|
}
|
|
352
359
|
|
|
353
|
-
/// Handle server errors from either completing or failing a workflow task.
|
|
354
|
-
///
|
|
355
|
-
async fn handle_wft_reporting_errs<T, Fut>(
|
|
356
|
-
&self,
|
|
357
|
-
run_id: &str,
|
|
358
|
-
completer: impl FnOnce() -> Fut,
|
|
359
|
-
) -> Result<(), CompleteWfError>
|
|
360
|
+
/// Handle server errors from either completing or failing a workflow task. Un-handleable errors
|
|
361
|
+
/// trigger a workflow eviction and are logged.
|
|
362
|
+
async fn handle_wft_reporting_errs<T, Fut>(&self, run_id: &str, completer: impl FnOnce() -> Fut)
|
|
360
363
|
where
|
|
361
364
|
Fut: Future<Output = Result<T, tonic::Status>>,
|
|
362
365
|
{
|
|
363
366
|
let mut should_evict = None;
|
|
364
|
-
let
|
|
365
|
-
|
|
366
|
-
|
|
367
|
+
if let Err(err) = completer().await {
|
|
368
|
+
match err.code() {
|
|
369
|
+
// Silence unhandled command errors since the lang SDK cannot do anything
|
|
370
|
+
// about them besides poll again, which it will do anyway.
|
|
371
|
+
tonic::Code::InvalidArgument if err.message() == "UnhandledCommand" => {
|
|
372
|
+
debug!(error = %err, run_id, "Unhandled command response when completing");
|
|
373
|
+
should_evict = Some(EvictionReason::UnhandledCommand);
|
|
374
|
+
}
|
|
375
|
+
tonic::Code::NotFound => {
|
|
376
|
+
warn!(error = %err, run_id, "Task not found when completing");
|
|
377
|
+
should_evict = Some(EvictionReason::TaskNotFound);
|
|
378
|
+
}
|
|
379
|
+
_ => {
|
|
367
380
|
warn!(error= %err, "Network error while completing workflow activation");
|
|
368
381
|
should_evict = Some(EvictionReason::Fatal);
|
|
369
|
-
Ok(())
|
|
370
|
-
} else {
|
|
371
|
-
match err.code() {
|
|
372
|
-
// Silence unhandled command errors since the lang SDK cannot do anything
|
|
373
|
-
// about them besides poll again, which it will do anyway.
|
|
374
|
-
tonic::Code::InvalidArgument if err.message() == "UnhandledCommand" => {
|
|
375
|
-
debug!(error = %err, run_id, "Unhandled command response when completing");
|
|
376
|
-
should_evict = Some(EvictionReason::UnhandledCommand);
|
|
377
|
-
Ok(())
|
|
378
|
-
}
|
|
379
|
-
tonic::Code::NotFound => {
|
|
380
|
-
warn!(error = %err, run_id, "Task not found when completing");
|
|
381
|
-
should_evict = Some(EvictionReason::TaskNotFound);
|
|
382
|
-
Ok(())
|
|
383
|
-
}
|
|
384
|
-
_ => Err(err),
|
|
385
|
-
}
|
|
386
382
|
}
|
|
387
383
|
}
|
|
388
|
-
|
|
389
|
-
};
|
|
384
|
+
}
|
|
390
385
|
if let Some(reason) = should_evict {
|
|
391
386
|
self.request_eviction(run_id, "Error reporting WFT to server", reason);
|
|
392
387
|
}
|
|
393
|
-
res.map_err(Into::into)
|
|
394
388
|
}
|
|
395
389
|
|
|
396
390
|
/// Sends a message to the workflow processing stream. Returns true if the message was sent
|
|
@@ -471,10 +465,22 @@ impl Workflows {
|
|
|
471
465
|
{
|
|
472
466
|
// If request_eager_execution was already false, that means lang explicitly
|
|
473
467
|
// told us it didn't want to eagerly execute for some reason. So, we only
|
|
474
|
-
// ever turn *off* eager execution if a slot is not available
|
|
468
|
+
// ever turn *off* eager execution if a slot is not available or the activity
|
|
469
|
+
// is scheduled on a different task queue.
|
|
475
470
|
if attrs.request_eager_execution {
|
|
476
|
-
|
|
477
|
-
|
|
471
|
+
let same_task_queue = attrs
|
|
472
|
+
.task_queue
|
|
473
|
+
.as_ref()
|
|
474
|
+
.map(|q| q.name == self.task_queue)
|
|
475
|
+
.unwrap_or_default();
|
|
476
|
+
if same_task_queue
|
|
477
|
+
&& reserved.len() < MAX_EAGER_ACTIVITY_RESERVATIONS_PER_WORKFLOW_TASK
|
|
478
|
+
{
|
|
479
|
+
if let Some(p) = at_handle.reserve_slot() {
|
|
480
|
+
reserved.push(p);
|
|
481
|
+
} else {
|
|
482
|
+
attrs.request_eager_execution = false;
|
|
483
|
+
}
|
|
478
484
|
} else {
|
|
479
485
|
attrs.request_eager_execution = false;
|
|
480
486
|
}
|
|
@@ -486,22 +492,15 @@ impl Workflows {
|
|
|
486
492
|
}
|
|
487
493
|
|
|
488
494
|
/// Wraps responding to legacy queries. Handles ignore-able failures.
|
|
489
|
-
async fn respond_legacy_query(
|
|
490
|
-
&self,
|
|
491
|
-
tt: TaskToken,
|
|
492
|
-
res: QueryResult,
|
|
493
|
-
) -> Result<(), tonic::Status> {
|
|
495
|
+
async fn respond_legacy_query(&self, tt: TaskToken, res: QueryResult) {
|
|
494
496
|
match self.client.respond_legacy_query(tt, res).await {
|
|
495
|
-
Ok(_) =>
|
|
496
|
-
Err(e) if should_swallow_net_error(&e) => {
|
|
497
|
-
warn!(error= %e, "Network error while responding to legacy query");
|
|
498
|
-
Ok(())
|
|
499
|
-
}
|
|
497
|
+
Ok(_) => {}
|
|
500
498
|
Err(e) if e.code() == tonic::Code::NotFound => {
|
|
501
499
|
warn!(error=?e, "Query not found when attempting to respond to it");
|
|
502
|
-
Ok(())
|
|
503
500
|
}
|
|
504
|
-
Err(e) =>
|
|
501
|
+
Err(e) => {
|
|
502
|
+
warn!(error= %e, "Network error while responding to legacy query");
|
|
503
|
+
}
|
|
505
504
|
}
|
|
506
505
|
}
|
|
507
506
|
}
|
|
@@ -794,7 +793,7 @@ pub(crate) enum ActivationAction {
|
|
|
794
793
|
force_new_wft: bool,
|
|
795
794
|
},
|
|
796
795
|
/// We should respond to a legacy query request
|
|
797
|
-
RespondLegacyQuery { result: QueryResult },
|
|
796
|
+
RespondLegacyQuery { result: Box<QueryResult> },
|
|
798
797
|
}
|
|
799
798
|
|
|
800
799
|
#[derive(Debug, Eq, PartialEq, Hash)]
|
|
@@ -847,6 +846,7 @@ struct ActivationCompleteResult {
|
|
|
847
846
|
}
|
|
848
847
|
/// What needs to be done after calling [Workflows::activation_completed]
|
|
849
848
|
#[derive(Debug)]
|
|
849
|
+
#[allow(clippy::large_enum_variant)]
|
|
850
850
|
enum ActivationCompleteOutcome {
|
|
851
851
|
/// The WFT must be reported as successful to the server using the contained information.
|
|
852
852
|
ReportWFTSuccess(ServerCommandsWithWorkflowInfo),
|
|
@@ -917,6 +917,7 @@ fn validate_completion(
|
|
|
917
917
|
}
|
|
918
918
|
|
|
919
919
|
#[derive(Debug)]
|
|
920
|
+
#[allow(clippy::large_enum_variant)]
|
|
920
921
|
enum ValidatedCompletion {
|
|
921
922
|
Success {
|
|
922
923
|
run_id: String,
|
|
@@ -944,6 +945,7 @@ struct RunAction {
|
|
|
944
945
|
trace_span: Span,
|
|
945
946
|
}
|
|
946
947
|
#[derive(Debug)]
|
|
948
|
+
#[allow(clippy::large_enum_variant)]
|
|
947
949
|
enum RunActions {
|
|
948
950
|
NewIncomingWFT(NewIncomingWFT),
|
|
949
951
|
ActivationCompletion(RunActivationCompletion),
|
|
@@ -984,6 +986,7 @@ struct RunUpdateResponse {
|
|
|
984
986
|
span: Span,
|
|
985
987
|
}
|
|
986
988
|
#[derive(Debug, derive_more::Display)]
|
|
989
|
+
#[allow(clippy::large_enum_variant)]
|
|
987
990
|
enum RunUpdateResponseKind {
|
|
988
991
|
Good(GoodRunUpdate),
|
|
989
992
|
Fail(FailRunUpdate),
|
|
@@ -1068,7 +1071,7 @@ pub enum WFCommand {
|
|
|
1068
1071
|
CancelWorkflow(CancelWorkflowExecution),
|
|
1069
1072
|
SetPatchMarker(SetPatchMarker),
|
|
1070
1073
|
AddChildWorkflow(StartChildWorkflowExecution),
|
|
1071
|
-
|
|
1074
|
+
CancelChild(CancelChildWorkflowExecution),
|
|
1072
1075
|
RequestCancelExternalWorkflow(RequestCancelExternalWorkflowExecution),
|
|
1073
1076
|
SignalExternalWorkflow(SignalExternalWorkflowExecution),
|
|
1074
1077
|
CancelSignalWorkflow(CancelSignalWorkflow),
|
|
@@ -1106,9 +1109,7 @@ impl TryFrom<WorkflowCommand> for WFCommand {
|
|
|
1106
1109
|
Ok(Self::SignalExternalWorkflow(s))
|
|
1107
1110
|
}
|
|
1108
1111
|
workflow_command::Variant::CancelSignalWorkflow(s) => Ok(Self::CancelSignalWorkflow(s)),
|
|
1109
|
-
workflow_command::Variant::
|
|
1110
|
-
Ok(Self::CancelUnstartedChild(s))
|
|
1111
|
-
}
|
|
1112
|
+
workflow_command::Variant::CancelChildWorkflowExecution(s) => Ok(Self::CancelChild(s)),
|
|
1112
1113
|
workflow_command::Variant::ScheduleLocalActivity(s) => Ok(Self::AddLocalActivity(s)),
|
|
1113
1114
|
workflow_command::Variant::RequestCancelLocalActivity(s) => {
|
|
1114
1115
|
Ok(Self::RequestCancelLocalActivity(s))
|
|
@@ -1136,6 +1137,9 @@ enum CommandID {
|
|
|
1136
1137
|
pub struct WorkflowStartedInfo {
|
|
1137
1138
|
workflow_task_timeout: Option<Duration>,
|
|
1138
1139
|
workflow_execution_timeout: Option<Duration>,
|
|
1140
|
+
memo: Option<Memo>,
|
|
1141
|
+
search_attrs: Option<SearchAttributes>,
|
|
1142
|
+
retry_policy: Option<RetryPolicy>,
|
|
1139
1143
|
}
|
|
1140
1144
|
|
|
1141
1145
|
type LocalActivityRequestSink =
|
|
@@ -7,7 +7,7 @@ use crate::{
|
|
|
7
7
|
MetricsContext,
|
|
8
8
|
};
|
|
9
9
|
use lru::LruCache;
|
|
10
|
-
use std::time::Instant;
|
|
10
|
+
use std::{num::NonZeroUsize, time::Instant};
|
|
11
11
|
use tokio::sync::mpsc::UnboundedSender;
|
|
12
12
|
|
|
13
13
|
pub(super) struct RunCache {
|
|
@@ -40,7 +40,9 @@ impl RunCache {
|
|
|
40
40
|
max: max_cache_size,
|
|
41
41
|
namespace,
|
|
42
42
|
run_update_tx,
|
|
43
|
-
runs: LruCache::new(
|
|
43
|
+
runs: LruCache::new(
|
|
44
|
+
NonZeroUsize::new(lru_size).expect("LRU size is guaranteed positive"),
|
|
45
|
+
),
|
|
44
46
|
local_activity_request_sink,
|
|
45
47
|
metrics,
|
|
46
48
|
}
|
|
@@ -132,7 +134,7 @@ impl RunCache {
|
|
|
132
134
|
self.runs.iter().map(|(_, v)| v)
|
|
133
135
|
}
|
|
134
136
|
pub fn is_full(&self) -> bool {
|
|
135
|
-
self.runs.cap() == self.runs.len()
|
|
137
|
+
self.runs.cap().get() == self.runs.len()
|
|
136
138
|
}
|
|
137
139
|
pub fn len(&self) -> usize {
|
|
138
140
|
self.runs.len()
|
|
@@ -6,7 +6,7 @@ use crate::{
|
|
|
6
6
|
workflow::{history_update::NextPageToken, run_cache::RunCache, *},
|
|
7
7
|
LocalActRequest, LocalActivityResolution, LEGACY_QUERY_ID,
|
|
8
8
|
},
|
|
9
|
-
MetricsContext,
|
|
9
|
+
MetricsContext,
|
|
10
10
|
};
|
|
11
11
|
use futures::{stream, stream::PollNext, Stream, StreamExt};
|
|
12
12
|
use std::{collections::VecDeque, fmt::Debug, future, sync::Arc, time::Instant};
|
|
@@ -36,7 +36,7 @@ pub(crate) struct WFStream {
|
|
|
36
36
|
buffered_polls_need_cache_slot: VecDeque<PermittedWFT>,
|
|
37
37
|
|
|
38
38
|
/// Client for accessing server for history pagination etc.
|
|
39
|
-
client: Arc<
|
|
39
|
+
client: Arc<dyn WorkerClient>,
|
|
40
40
|
|
|
41
41
|
/// Ensures we stay at or below this worker's maximum concurrent workflow task limit
|
|
42
42
|
wft_semaphore: MeteredSemaphore,
|
|
@@ -118,7 +118,7 @@ impl WFStream {
|
|
|
118
118
|
basics: WorkflowBasics,
|
|
119
119
|
external_wfts: impl Stream<Item = Result<ValidPollWFTQResponse, tonic::Status>> + Send + 'static,
|
|
120
120
|
local_rx: impl Stream<Item = LocalInput> + Send + 'static,
|
|
121
|
-
client: Arc<
|
|
121
|
+
client: Arc<dyn WorkerClient>,
|
|
122
122
|
local_activity_request_sink: impl Fn(Vec<LocalActRequest>) -> Vec<LocalActivityResolution>
|
|
123
123
|
+ Send
|
|
124
124
|
+ Sync
|
|
@@ -157,7 +157,7 @@ impl WFStream {
|
|
|
157
157
|
buffered_polls_need_cache_slot: Default::default(),
|
|
158
158
|
runs: RunCache::new(
|
|
159
159
|
basics.max_cached_workflows,
|
|
160
|
-
|
|
160
|
+
basics.namespace.clone(),
|
|
161
161
|
run_update_tx,
|
|
162
162
|
Arc::new(local_activity_request_sink),
|
|
163
163
|
basics.metrics.clone(),
|
|
@@ -539,7 +539,9 @@ impl WFStream {
|
|
|
539
539
|
&run_id,
|
|
540
540
|
ActivationCompleteOutcome::ReportWFTSuccess(ServerCommandsWithWorkflowInfo {
|
|
541
541
|
task_token,
|
|
542
|
-
action: ActivationAction::RespondLegacyQuery {
|
|
542
|
+
action: ActivationAction::RespondLegacyQuery {
|
|
543
|
+
result: Box::new(qr),
|
|
544
|
+
},
|
|
543
545
|
}),
|
|
544
546
|
resp_chan,
|
|
545
547
|
);
|
|
@@ -17,10 +17,10 @@ anyhow = "1.0"
|
|
|
17
17
|
async-trait = "0.1"
|
|
18
18
|
derive_builder = "0.11"
|
|
19
19
|
log = "0.4"
|
|
20
|
-
opentelemetry = "0.
|
|
21
|
-
prost-types = "0.
|
|
20
|
+
opentelemetry = "0.18"
|
|
21
|
+
prost-types = "0.11"
|
|
22
22
|
thiserror = "1.0"
|
|
23
|
-
tonic = "0.
|
|
23
|
+
tonic = "0.8"
|
|
24
24
|
|
|
25
25
|
[dependencies.temporal-sdk-core-protos]
|
|
26
26
|
path = "../sdk-core-protos"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//! Error types exposed by public APIs
|
|
2
2
|
|
|
3
|
-
use prost_types::
|
|
3
|
+
use prost_types::TimestampError;
|
|
4
4
|
use temporal_sdk_core_protos::coresdk::{
|
|
5
5
|
activity_result::ActivityExecutionResult,
|
|
6
6
|
workflow_activation::remove_from_cache::EvictionReason,
|
|
@@ -50,10 +50,6 @@ pub enum CompleteWfError {
|
|
|
50
50
|
/// The run associated with the completion
|
|
51
51
|
run_id: String,
|
|
52
52
|
},
|
|
53
|
-
/// Unhandled error when calling the temporal server. Core will attempt to retry any non-fatal
|
|
54
|
-
/// errors, so lang should consider this fatal.
|
|
55
|
-
#[error("Unhandled grpc error when completing workflow task: {0:?}")]
|
|
56
|
-
TonicError(#[from] tonic::Status),
|
|
57
53
|
}
|
|
58
54
|
|
|
59
55
|
/// Errors thrown by [crate::Worker::complete_activity_task]
|
|
@@ -67,10 +63,6 @@ pub enum CompleteActivityError {
|
|
|
67
63
|
/// The completion, which may not be included to avoid unnecessary copies.
|
|
68
64
|
completion: Option<ActivityExecutionResult>,
|
|
69
65
|
},
|
|
70
|
-
/// Unhandled error when calling the temporal server. Core will attempt to retry any non-fatal
|
|
71
|
-
/// errors, so lang should consider this fatal.
|
|
72
|
-
#[error("Unhandled grpc error when completing activity: {0:?}")]
|
|
73
|
-
TonicError(#[from] tonic::Status),
|
|
74
66
|
}
|
|
75
67
|
|
|
76
68
|
/// Errors thrown inside of workflow machines
|
|
@@ -96,8 +88,8 @@ impl WFMachinesError {
|
|
|
96
88
|
}
|
|
97
89
|
}
|
|
98
90
|
|
|
99
|
-
impl From<
|
|
100
|
-
fn from(_:
|
|
91
|
+
impl From<TimestampError> for WFMachinesError {
|
|
92
|
+
fn from(_: TimestampError) -> Self {
|
|
101
93
|
Self::Fatal("Could not decode timestamp".to_string())
|
|
102
94
|
}
|
|
103
95
|
}
|
|
@@ -88,6 +88,13 @@ pub struct WorkerConfig {
|
|
|
88
88
|
/// the options to fail.
|
|
89
89
|
#[builder(default)]
|
|
90
90
|
pub max_worker_activities_per_second: Option<f64>,
|
|
91
|
+
|
|
92
|
+
/// # UNDER DEVELOPMENT
|
|
93
|
+
/// If set to true this worker will opt-in to the whole-worker versioning feature.
|
|
94
|
+
/// `worker_build_id` will be used as the version.
|
|
95
|
+
/// todo: link to feature docs
|
|
96
|
+
#[builder(default = "false")]
|
|
97
|
+
pub use_worker_versioning: bool,
|
|
91
98
|
}
|
|
92
99
|
|
|
93
100
|
impl WorkerConfig {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
FROM temporalio/base-ci-builder:1.
|
|
1
|
+
FROM temporalio/base-ci-builder:1.5.0
|
|
2
2
|
WORKDIR /temporal
|
|
@@ -6,10 +6,6 @@
|
|
|
6
6
|
**Why?**
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
<!--
|
|
10
|
-
**
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
<!-- Assuming the worst case, what can be broken when deploying this change to production? -->
|
|
14
|
-
**Potential risks**
|
|
9
|
+
<!-- Are there any breaking changes on binary or code level? -->
|
|
10
|
+
**Breaking changes**
|
|
15
11
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: 'Trigger api-go Update'
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
notify:
|
|
11
|
+
name: 'Trigger api-go update'
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
|
|
14
|
+
defaults:
|
|
15
|
+
run:
|
|
16
|
+
shell: bash
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- name: Dispatch api-go Github Action
|
|
20
|
+
env:
|
|
21
|
+
PAT: ${{ secrets.COMMANDER_DATA_TOKEN }}
|
|
22
|
+
PARENT_REPO: temporalio/api-go
|
|
23
|
+
PARENT_BRANCH: ${{ toJSON('master') }}
|
|
24
|
+
WORKFLOW_ID: update-proto.yml
|
|
25
|
+
COMMIT_AUTHOR: ${{ toJSON(github.event.head_commit.author.name) }}
|
|
26
|
+
COMMIT_AUTHOR_EMAIL: ${{ toJSON(github.event.head_commit.author.email) }}
|
|
27
|
+
COMMIT_MESSAGE: ${{ toJSON(github.event.head_commit.message) }}
|
|
28
|
+
run: |
|
|
29
|
+
curl -fL -X POST -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ env.PAT }}" https://api.github.com/repos/${{ env.PARENT_REPO }}/actions/workflows/${{ env.WORKFLOW_ID }}/dispatches -d '{"ref":'"$PARENT_BRANCH"', "inputs":{"commit_author":'"$COMMIT_AUTHOR"', "commit_author_email":'"$COMMIT_AUTHOR_EMAIL"', "commit_message":'"$COMMIT_MESSAGE"'}}'
|
|
@@ -33,11 +33,11 @@ grpc: buf-lint api-linter buf-breaking gogo-grpc fix-path
|
|
|
33
33
|
|
|
34
34
|
go-grpc: clean $(PROTO_OUT)
|
|
35
35
|
printf $(COLOR) "Compile for go-gRPC..."
|
|
36
|
-
$(foreach PROTO_DIR,$(PROTO_DIRS),protoc $(PROTO_IMPORTS) --go_out=plugins=grpc,paths=source_relative:$(PROTO_OUT) $(PROTO_DIR)*.proto;)
|
|
36
|
+
$(foreach PROTO_DIR,$(PROTO_DIRS),protoc --fatal_warnings $(PROTO_IMPORTS) --go_out=plugins=grpc,paths=source_relative:$(PROTO_OUT) $(PROTO_DIR)*.proto;)
|
|
37
37
|
|
|
38
38
|
gogo-grpc: clean $(PROTO_OUT)
|
|
39
39
|
printf $(COLOR) "Compile for gogo-gRPC..."
|
|
40
|
-
$(foreach PROTO_DIR,$(PROTO_DIRS),protoc $(PROTO_IMPORTS) --gogoslick_out=Mgoogle/protobuf/wrappers.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/duration.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/descriptor.proto=github.com/golang/protobuf/protoc-gen-go/descriptor,Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types,plugins=grpc,paths=source_relative:$(PROTO_OUT) $(PROTO_DIR)*.proto;)
|
|
40
|
+
$(foreach PROTO_DIR,$(PROTO_DIRS),protoc --fatal_warnings $(PROTO_IMPORTS) --gogoslick_out=Mgoogle/protobuf/wrappers.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/duration.proto=github.com/gogo/protobuf/types,Mgoogle/protobuf/descriptor.proto=github.com/golang/protobuf/protoc-gen-go/descriptor,Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types,plugins=grpc,paths=source_relative:$(PROTO_OUT) $(PROTO_DIR)*.proto;)
|
|
41
41
|
|
|
42
42
|
fix-path:
|
|
43
43
|
mv -f $(PROTO_OUT)/temporal/api/* $(PROTO_OUT) && rm -rf $(PROTO_OUT)/temporal
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// The MIT License
|
|
2
|
+
//
|
|
3
|
+
// Copyright (c) 2020 Temporal Technologies Inc. All rights reserved.
|
|
4
|
+
//
|
|
5
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
// of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
// in the Software without restriction, including without limitation the rights
|
|
8
|
+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
// copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
// furnished to do so, subject to the following conditions:
|
|
11
|
+
//
|
|
12
|
+
// The above copyright notice and this permission notice shall be included in
|
|
13
|
+
// all copies or substantial portions of the Software.
|
|
14
|
+
//
|
|
15
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
// THE SOFTWARE.
|
|
22
|
+
|
|
23
|
+
syntax = "proto3";
|
|
24
|
+
|
|
25
|
+
package temporal.api.batch.v1;
|
|
26
|
+
|
|
27
|
+
option go_package = "go.temporal.io/api/batch/v1;batch";
|
|
28
|
+
option java_package = "io.temporal.api.batch.v1";
|
|
29
|
+
option java_multiple_files = true;
|
|
30
|
+
option java_outer_classname = "MessageProto";
|
|
31
|
+
option ruby_package = "Temporal::Api::Batch::V1";
|
|
32
|
+
option csharp_namespace = "Temporal.Api.Batch.V1";
|
|
33
|
+
|
|
34
|
+
import "dependencies/gogoproto/gogo.proto";
|
|
35
|
+
import "google/protobuf/timestamp.proto";
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
import "temporal/api/common/v1/message.proto";
|
|
39
|
+
import "temporal/api/enums/v1/batch_operation.proto";
|
|
40
|
+
|
|
41
|
+
message BatchOperationInfo {
|
|
42
|
+
// Batch job ID
|
|
43
|
+
string job_id = 1;
|
|
44
|
+
// Batch operation state
|
|
45
|
+
temporal.api.enums.v1.BatchOperationState state = 2;
|
|
46
|
+
// Batch operation start time
|
|
47
|
+
google.protobuf.Timestamp start_time = 3 [(gogoproto.stdtime) = true];
|
|
48
|
+
// Batch operation close time
|
|
49
|
+
google.protobuf.Timestamp close_time = 4 [(gogoproto.stdtime) = true];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// BatchOperationTermination sends terminate requests to batch workflows.
|
|
53
|
+
// Keep the parameter in sync with temporal.api.workflowservice.v1.TerminateWorkflowExecutionRequest.
|
|
54
|
+
// Ignore first_execution_run_id because this is used for single workflow operation.
|
|
55
|
+
message BatchOperationTermination {
|
|
56
|
+
// Reason of terminate workflows
|
|
57
|
+
string reason = 1;
|
|
58
|
+
// Serialized value(s) to provide to the termination event
|
|
59
|
+
temporal.api.common.v1.Payloads details = 2;
|
|
60
|
+
// The identity of the worker/client
|
|
61
|
+
string identity = 3;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// BatchOperationSignal sends signals to batch workflows.
|
|
65
|
+
// Keep the parameter in sync with temporal.api.workflowservice.v1.SignalWorkflowExecutionRequest.
|
|
66
|
+
message BatchOperationSignal {
|
|
67
|
+
// The workflow author-defined name of the signal to send to the workflow
|
|
68
|
+
string signal = 1;
|
|
69
|
+
// Serialized value(s) to provide with the signal
|
|
70
|
+
temporal.api.common.v1.Payloads input = 2;
|
|
71
|
+
// Headers that are passed with the signal to the processing workflow.
|
|
72
|
+
// These can include things like auth or tracing tokens.
|
|
73
|
+
temporal.api.common.v1.Header header = 3;
|
|
74
|
+
// The identity of the worker/client
|
|
75
|
+
string identity = 4;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// BatchOperationCancellation sends cancel requests to batch workflows.
|
|
79
|
+
// Keep the parameter in sync with temporal.api.workflowservice.v1.RequestCancelWorkflowExecutionRequest.
|
|
80
|
+
// Ignore first_execution_run_id because this is used for single workflow operation.
|
|
81
|
+
message BatchOperationCancellation {
|
|
82
|
+
// Reason of cancel workflows
|
|
83
|
+
string reason = 1;
|
|
84
|
+
// The identity of the worker/client
|
|
85
|
+
string identity = 2;
|
|
86
|
+
}
|
|
@@ -37,6 +37,7 @@ import "dependencies/gogoproto/gogo.proto";
|
|
|
37
37
|
|
|
38
38
|
import "temporal/api/enums/v1/workflow.proto";
|
|
39
39
|
import "temporal/api/enums/v1/command_type.proto";
|
|
40
|
+
import "temporal/api/enums/v1/update.proto";
|
|
40
41
|
import "temporal/api/common/v1/message.proto";
|
|
41
42
|
import "temporal/api/failure/v1/message.proto";
|
|
42
43
|
import "temporal/api/taskqueue/v1/message.proto";
|
|
@@ -213,6 +214,29 @@ message StartChildWorkflowExecutionCommandAttributes {
|
|
|
213
214
|
temporal.api.common.v1.SearchAttributes search_attributes = 16;
|
|
214
215
|
}
|
|
215
216
|
|
|
217
|
+
message AcceptWorkflowUpdateCommandAttributes {
|
|
218
|
+
// A unique identifier for an update within a given workflow context
|
|
219
|
+
string update_id = 1;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
message CompleteWorkflowUpdateCommandAttributes {
|
|
223
|
+
// A unique identifier for an update within a given workflow context
|
|
224
|
+
string update_id = 1;
|
|
225
|
+
|
|
226
|
+
// Whether the server should attempt to bypass making this update rejection
|
|
227
|
+
// durable in history. This field is only consulted when the result field
|
|
228
|
+
// indicates failure. Leaving this field in its default state (i.e.
|
|
229
|
+
// UPDATE_WORKFLOW_REJECTION_DURABILITY_PREFERENCE_UNSPECIFIED) will result
|
|
230
|
+
// in making the rejection durable.
|
|
231
|
+
temporal.api.enums.v1.WorkflowUpdateDurabilityPreference durability_preference = 2;
|
|
232
|
+
|
|
233
|
+
// The success or failure output of the update
|
|
234
|
+
oneof result {
|
|
235
|
+
temporal.api.common.v1.Payloads success = 3;
|
|
236
|
+
temporal.api.failure.v1.Failure failure = 4;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
216
240
|
message Command {
|
|
217
241
|
temporal.api.enums.v1.CommandType command_type = 1;
|
|
218
242
|
oneof attributes {
|
|
@@ -229,5 +253,7 @@ message Command {
|
|
|
229
253
|
StartChildWorkflowExecutionCommandAttributes start_child_workflow_execution_command_attributes = 12;
|
|
230
254
|
SignalExternalWorkflowExecutionCommandAttributes signal_external_workflow_execution_command_attributes = 13;
|
|
231
255
|
UpsertWorkflowSearchAttributesCommandAttributes upsert_workflow_search_attributes_command_attributes = 14;
|
|
256
|
+
AcceptWorkflowUpdateCommandAttributes accept_workflow_update_command_attributes = 15;
|
|
257
|
+
CompleteWorkflowUpdateCommandAttributes complete_workflow_update_command_attributes = 16;
|
|
232
258
|
}
|
|
233
259
|
}
|