@temporalio/core-bridge 0.23.0 → 1.0.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 +118 -15
- package/Cargo.toml +2 -1
- package/LICENSE.md +1 -1
- package/README.md +1 -1
- package/index.d.ts +47 -18
- package/package.json +7 -7
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/releases/x86_64-apple-darwin/index.node +0 -0
- package/releases/x86_64-pc-windows-msvc/index.node +0 -0
- package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
- package/sdk-core/.buildkite/docker/docker-compose.yaml +4 -2
- package/sdk-core/ARCHITECTURE.md +9 -7
- package/sdk-core/README.md +5 -1
- package/sdk-core/arch_docs/diagrams/workflow_internals.svg +1 -0
- package/sdk-core/bridge-ffi/src/wrappers.rs +0 -3
- package/sdk-core/client/src/lib.rs +26 -8
- package/sdk-core/client/src/raw.rs +166 -54
- package/sdk-core/client/src/retry.rs +9 -4
- package/sdk-core/client/src/workflow_handle/mod.rs +4 -2
- package/sdk-core/core/Cargo.toml +2 -0
- package/sdk-core/core/src/abstractions.rs +137 -16
- package/sdk-core/core/src/core_tests/activity_tasks.rs +258 -63
- package/sdk-core/core/src/core_tests/child_workflows.rs +1 -2
- package/sdk-core/core/src/core_tests/determinism.rs +2 -2
- package/sdk-core/core/src/core_tests/local_activities.rs +8 -7
- package/sdk-core/core/src/core_tests/queries.rs +146 -60
- package/sdk-core/core/src/core_tests/replay_flag.rs +1 -1
- package/sdk-core/core/src/core_tests/workers.rs +39 -23
- package/sdk-core/core/src/core_tests/workflow_cancels.rs +1 -1
- package/sdk-core/core/src/core_tests/workflow_tasks.rs +387 -280
- package/sdk-core/core/src/lib.rs +6 -4
- package/sdk-core/core/src/pollers/poll_buffer.rs +16 -10
- package/sdk-core/core/src/protosext/mod.rs +6 -6
- package/sdk-core/core/src/retry_logic.rs +1 -1
- package/sdk-core/core/src/telemetry/metrics.rs +21 -7
- package/sdk-core/core/src/telemetry/mod.rs +18 -4
- package/sdk-core/core/src/test_help/mod.rs +341 -109
- package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +18 -9
- package/sdk-core/core/src/worker/activities/local_activities.rs +19 -16
- package/sdk-core/core/src/worker/activities.rs +156 -29
- package/sdk-core/core/src/worker/client.rs +1 -0
- package/sdk-core/core/src/worker/mod.rs +132 -659
- package/sdk-core/core/src/{workflow → worker/workflow}/bridge.rs +1 -1
- package/sdk-core/core/src/{workflow → worker/workflow}/driven_workflow.rs +1 -1
- package/sdk-core/core/src/{workflow → worker/workflow}/history_update.rs +16 -2
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/activity_state_machine.rs +39 -4
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/cancel_external_state_machine.rs +5 -2
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/cancel_workflow_state_machine.rs +1 -1
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/child_workflow_state_machine.rs +2 -4
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/complete_workflow_state_machine.rs +0 -0
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/continue_as_new_workflow_state_machine.rs +1 -1
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/fail_workflow_state_machine.rs +0 -0
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/local_activity_state_machine.rs +2 -5
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/mod.rs +1 -1
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/mutable_side_effect_state_machine.rs +0 -0
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/patch_state_machine.rs +1 -1
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/side_effect_state_machine.rs +0 -0
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/signal_external_state_machine.rs +4 -2
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/timer_state_machine.rs +1 -2
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/transition_coverage.rs +1 -1
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/upsert_search_attributes_state_machine.rs +5 -7
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/workflow_machines/local_acts.rs +2 -2
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/workflow_machines.rs +40 -16
- package/sdk-core/core/src/{workflow → worker/workflow}/machines/workflow_task_state_machine.rs +0 -0
- package/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +198 -0
- package/sdk-core/core/src/worker/workflow/managed_run.rs +627 -0
- package/sdk-core/core/src/worker/workflow/mod.rs +1115 -0
- package/sdk-core/core/src/worker/workflow/run_cache.rs +143 -0
- package/sdk-core/core/src/worker/workflow/wft_poller.rs +88 -0
- package/sdk-core/core/src/worker/workflow/workflow_stream.rs +936 -0
- package/sdk-core/core-api/src/errors.rs +3 -10
- package/sdk-core/core-api/src/lib.rs +2 -1
- package/sdk-core/core-api/src/worker.rs +26 -2
- package/sdk-core/etc/dynamic-config.yaml +2 -0
- package/sdk-core/integ-with-otel.sh +1 -1
- package/sdk-core/protos/api_upstream/Makefile +4 -4
- package/sdk-core/protos/api_upstream/api-linter.yaml +2 -0
- package/sdk-core/protos/api_upstream/buf.yaml +8 -9
- package/sdk-core/protos/api_upstream/temporal/api/cluster/v1/message.proto +83 -0
- package/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +7 -1
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/cluster.proto +40 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +3 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/reset.proto +3 -1
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/schedule.proto +60 -0
- package/sdk-core/protos/api_upstream/temporal/api/enums/v1/workflow.proto +3 -0
- package/sdk-core/protos/api_upstream/temporal/api/errordetails/v1/message.proto +32 -4
- package/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +69 -19
- package/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +13 -0
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +163 -0
- package/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +97 -0
- package/sdk-core/protos/api_upstream/temporal/api/schedule/v1/message.proto +300 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflow/v1/message.proto +25 -0
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +180 -3
- package/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +53 -3
- package/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +2 -2
- package/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +6 -5
- package/sdk-core/protos/local/temporal/sdk/core/bridge/bridge.proto +0 -1
- package/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +2 -1
- package/sdk-core/protos/local/temporal/sdk/core/common/common.proto +0 -64
- package/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +2 -1
- package/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +11 -8
- package/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +30 -25
- package/sdk-core/sdk/src/activity_context.rs +12 -5
- package/sdk-core/sdk/src/app_data.rs +37 -0
- package/sdk-core/sdk/src/lib.rs +76 -43
- package/sdk-core/sdk/src/workflow_context/options.rs +8 -6
- package/sdk-core/sdk/src/workflow_context.rs +14 -19
- package/sdk-core/sdk/src/workflow_future.rs +11 -6
- package/sdk-core/sdk-core-protos/src/history_builder.rs +19 -5
- package/sdk-core/sdk-core-protos/src/history_info.rs +11 -6
- package/sdk-core/sdk-core-protos/src/lib.rs +74 -176
- package/sdk-core/test-utils/src/lib.rs +85 -72
- package/sdk-core/tests/integ_tests/heartbeat_tests.rs +11 -9
- package/sdk-core/tests/integ_tests/polling_tests.rs +12 -0
- package/sdk-core/tests/integ_tests/queries_tests.rs +39 -22
- package/sdk-core/tests/integ_tests/workflow_tests/activities.rs +49 -4
- package/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +61 -0
- package/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +74 -13
- package/sdk-core/tests/integ_tests/workflow_tests/replay.rs +19 -0
- package/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -1
- package/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +6 -3
- package/sdk-core/tests/integ_tests/workflow_tests.rs +10 -23
- package/sdk-core/tests/load_tests.rs +8 -3
- package/sdk-core/tests/main.rs +2 -1
- package/src/conversions.rs +47 -39
- package/src/errors.rs +10 -21
- package/src/lib.rs +342 -325
- package/sdk-core/core/src/pending_activations.rs +0 -173
- package/sdk-core/core/src/worker/wft_delivery.rs +0 -81
- package/sdk-core/core/src/workflow/mod.rs +0 -478
- package/sdk-core/core/src/workflow/workflow_tasks/cache_manager.rs +0 -194
- package/sdk-core/core/src/workflow/workflow_tasks/concurrency_manager.rs +0 -418
- package/sdk-core/core/src/workflow/workflow_tasks/mod.rs +0 -989
package/sdk-core/sdk/src/lib.rs
CHANGED
|
@@ -8,16 +8,25 @@
|
|
|
8
8
|
//!
|
|
9
9
|
//! An example of running an activity worker:
|
|
10
10
|
//! ```no_run
|
|
11
|
-
//! use std::{
|
|
12
|
-
//! use temporal_sdk::{sdk_client_options,
|
|
13
|
-
//! use temporal_sdk_core::{init_worker, Url};
|
|
14
|
-
//! use temporal_sdk_core_api::worker::
|
|
11
|
+
//! use std::{str::FromStr, sync::Arc};
|
|
12
|
+
//! use temporal_sdk::{sdk_client_options, ActContext, Worker};
|
|
13
|
+
//! use temporal_sdk_core::{init_worker, telemetry_init, TelemetryOptionsBuilder, Url};
|
|
14
|
+
//! use temporal_sdk_core_api::worker::WorkerConfigBuilder;
|
|
15
15
|
//!
|
|
16
16
|
//! #[tokio::main]
|
|
17
17
|
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
18
18
|
//! let server_options = sdk_client_options(Url::from_str("http://localhost:7233")?).build()?;
|
|
19
|
-
//!
|
|
20
|
-
//! let
|
|
19
|
+
//!
|
|
20
|
+
//! let client = server_options.connect("default", None, None).await?;
|
|
21
|
+
//!
|
|
22
|
+
//! let telemetry_options = TelemetryOptionsBuilder::default().build()?;
|
|
23
|
+
//! telemetry_init(&telemetry_options)?;
|
|
24
|
+
//!
|
|
25
|
+
//! let worker_config = WorkerConfigBuilder::default()
|
|
26
|
+
//! .namespace("default")
|
|
27
|
+
//! .task_queue("task_queue")
|
|
28
|
+
//! .build()?;
|
|
29
|
+
//!
|
|
21
30
|
//! let core_worker = init_worker(worker_config, client);
|
|
22
31
|
//!
|
|
23
32
|
//! let mut worker = Worker::new_from_core(Arc::new(core_worker), "task_queue");
|
|
@@ -25,7 +34,9 @@
|
|
|
25
34
|
//! "echo_activity",
|
|
26
35
|
//! |_ctx: ActContext, echo_me: String| async move { Ok(echo_me) },
|
|
27
36
|
//! );
|
|
37
|
+
//!
|
|
28
38
|
//! worker.run().await?;
|
|
39
|
+
//!
|
|
29
40
|
//! Ok(())
|
|
30
41
|
//! }
|
|
31
42
|
//! ```
|
|
@@ -34,6 +45,7 @@
|
|
|
34
45
|
extern crate tracing;
|
|
35
46
|
|
|
36
47
|
mod activity_context;
|
|
48
|
+
mod app_data;
|
|
37
49
|
mod conversions;
|
|
38
50
|
pub mod interceptors;
|
|
39
51
|
mod payload_converter;
|
|
@@ -51,9 +63,9 @@ use crate::{
|
|
|
51
63
|
interceptors::WorkerInterceptor,
|
|
52
64
|
workflow_context::{ChildWfCommon, PendingChildWorkflow},
|
|
53
65
|
};
|
|
54
|
-
use anyhow::{anyhow, bail};
|
|
66
|
+
use anyhow::{anyhow, bail, Context};
|
|
67
|
+
use app_data::AppData;
|
|
55
68
|
use futures::{future::BoxFuture, FutureExt, StreamExt, TryFutureExt, TryStreamExt};
|
|
56
|
-
use once_cell::sync::OnceCell;
|
|
57
69
|
use std::{
|
|
58
70
|
cell::RefCell,
|
|
59
71
|
collections::HashMap,
|
|
@@ -72,7 +84,7 @@ use temporal_sdk_core_protos::{
|
|
|
72
84
|
activity_result::{ActivityExecutionResult, ActivityResolution},
|
|
73
85
|
activity_task::{activity_task, ActivityTask},
|
|
74
86
|
child_workflow::ChildWorkflowResult,
|
|
75
|
-
common::
|
|
87
|
+
common::NamespacedWorkflowExecution,
|
|
76
88
|
workflow_activation::{
|
|
77
89
|
resolve_child_workflow_execution_start::Status as ChildWorkflowStartStatus,
|
|
78
90
|
workflow_activation_job::Variant, WorkflowActivation, WorkflowActivationJob,
|
|
@@ -81,7 +93,7 @@ use temporal_sdk_core_protos::{
|
|
|
81
93
|
workflow_completion::WorkflowActivationCompletion,
|
|
82
94
|
ActivityTaskCompletion, AsJsonPayloadExt, FromJsonPayloadExt,
|
|
83
95
|
},
|
|
84
|
-
temporal::api::failure::v1::Failure,
|
|
96
|
+
temporal::api::{common::v1::Payload, failure::v1::Failure},
|
|
85
97
|
TaskToken,
|
|
86
98
|
};
|
|
87
99
|
use tokio::{
|
|
@@ -103,8 +115,7 @@ pub fn sdk_client_options(url: impl Into<Url>) -> ClientOptionsBuilder {
|
|
|
103
115
|
builder
|
|
104
116
|
.target_url(url)
|
|
105
117
|
.client_name("rust-sdk".to_string())
|
|
106
|
-
.client_version(VERSION.to_string())
|
|
107
|
-
.worker_binary_id(binary_id().to_string());
|
|
118
|
+
.client_version(VERSION.to_string());
|
|
108
119
|
|
|
109
120
|
builder
|
|
110
121
|
}
|
|
@@ -115,6 +126,7 @@ pub struct Worker {
|
|
|
115
126
|
common: CommonWorker,
|
|
116
127
|
workflow_half: WorkflowHalf,
|
|
117
128
|
activity_half: ActivityHalf,
|
|
129
|
+
app_data: Option<AppData>,
|
|
118
130
|
}
|
|
119
131
|
|
|
120
132
|
struct CommonWorker {
|
|
@@ -146,8 +158,7 @@ struct ActivityHalf {
|
|
|
146
158
|
}
|
|
147
159
|
|
|
148
160
|
impl Worker {
|
|
149
|
-
|
|
150
|
-
/// Create a new rust worker from a core worker
|
|
161
|
+
/// Create a new Rust SDK worker from a core worker
|
|
151
162
|
pub fn new_from_core(worker: Arc<dyn CoreWorker>, task_queue: impl Into<String>) -> Self {
|
|
152
163
|
Self {
|
|
153
164
|
common: CommonWorker {
|
|
@@ -163,6 +174,7 @@ impl Worker {
|
|
|
163
174
|
activity_fns: Default::default(),
|
|
164
175
|
task_tokens_to_cancels: Default::default(),
|
|
165
176
|
},
|
|
177
|
+
app_data: Some(Default::default()),
|
|
166
178
|
}
|
|
167
179
|
}
|
|
168
180
|
|
|
@@ -206,11 +218,21 @@ impl Worker {
|
|
|
206
218
|
);
|
|
207
219
|
}
|
|
208
220
|
|
|
221
|
+
/// Insert Custom App Context for Workflows and Activities
|
|
222
|
+
pub fn insert_app_data<T: Send + Sync + 'static>(&mut self, data: T) {
|
|
223
|
+
self.app_data.as_mut().map(|a| a.insert(data));
|
|
224
|
+
}
|
|
225
|
+
|
|
209
226
|
/// Runs the worker. Eventually resolves after the worker has been explicitly shut down,
|
|
210
227
|
/// or may return early with an error in the event of some unresolvable problem.
|
|
211
228
|
pub async fn run(&mut self) -> Result<(), anyhow::Error> {
|
|
212
229
|
let shutdown_token = CancellationToken::new();
|
|
213
|
-
let (common, wf_half, act_half) = self.split_apart();
|
|
230
|
+
let (common, wf_half, act_half, app_data) = self.split_apart();
|
|
231
|
+
let safe_app_data = Arc::new(
|
|
232
|
+
app_data
|
|
233
|
+
.take()
|
|
234
|
+
.ok_or_else(|| anyhow!("app_data should exist on run"))?,
|
|
235
|
+
);
|
|
214
236
|
let (wf_future_tx, wf_future_rx) = unbounded_channel();
|
|
215
237
|
let (completions_tx, completions_rx) = unbounded_channel();
|
|
216
238
|
let wf_future_joiner = async {
|
|
@@ -225,15 +247,17 @@ impl Worker {
|
|
|
225
247
|
let wf_half = &*wf_half;
|
|
226
248
|
async move {
|
|
227
249
|
join_handle.await??;
|
|
250
|
+
info!(run_id=%run_id, "Removing workflow from cache");
|
|
228
251
|
wf_half.workflows.borrow_mut().remove(&run_id);
|
|
229
252
|
Ok(())
|
|
230
253
|
}
|
|
231
254
|
},
|
|
232
255
|
)
|
|
233
256
|
.await
|
|
257
|
+
.context("Workflow futures encountered an error")
|
|
234
258
|
};
|
|
235
259
|
let wf_completion_processor = async {
|
|
236
|
-
|
|
260
|
+
UnboundedReceiverStream::new(completions_rx)
|
|
237
261
|
.map(Ok)
|
|
238
262
|
.try_for_each_concurrent(None, |completion| async {
|
|
239
263
|
if let Some(ref i) = common.worker_interceptor {
|
|
@@ -241,9 +265,9 @@ impl Worker {
|
|
|
241
265
|
}
|
|
242
266
|
common.worker.complete_workflow_activation(completion).await
|
|
243
267
|
})
|
|
244
|
-
.map_err(
|
|
245
|
-
.await
|
|
246
|
-
|
|
268
|
+
.map_err(anyhow::Error::from)
|
|
269
|
+
.await
|
|
270
|
+
.context("Workflow completions processor encountered an error")
|
|
247
271
|
};
|
|
248
272
|
tokio::try_join!(
|
|
249
273
|
// Workflow polling loop
|
|
@@ -287,9 +311,12 @@ impl Worker {
|
|
|
287
311
|
if matches!(activity, Err(PollActivityError::ShutDown)) {
|
|
288
312
|
break;
|
|
289
313
|
}
|
|
290
|
-
act_half.activity_task_handler(
|
|
291
|
-
|
|
292
|
-
|
|
314
|
+
act_half.activity_task_handler(
|
|
315
|
+
common.worker.clone(),
|
|
316
|
+
safe_app_data.clone(),
|
|
317
|
+
common.task_queue.clone(),
|
|
318
|
+
activity?
|
|
319
|
+
)?;
|
|
293
320
|
},
|
|
294
321
|
_ = shutdown_token.cancelled() => { break }
|
|
295
322
|
}
|
|
@@ -306,6 +333,10 @@ impl Worker {
|
|
|
306
333
|
i.on_shutdown(self);
|
|
307
334
|
}
|
|
308
335
|
self.common.worker.shutdown().await;
|
|
336
|
+
self.app_data = Some(
|
|
337
|
+
Arc::try_unwrap(safe_app_data)
|
|
338
|
+
.map_err(|_| anyhow!("some references of AppData exist on worker shutdown"))?,
|
|
339
|
+
);
|
|
309
340
|
Ok(())
|
|
310
341
|
}
|
|
311
342
|
|
|
@@ -327,11 +358,19 @@ impl Worker {
|
|
|
327
358
|
self.workflow_half.workflows.borrow().len()
|
|
328
359
|
}
|
|
329
360
|
|
|
330
|
-
fn split_apart(
|
|
361
|
+
fn split_apart(
|
|
362
|
+
&mut self,
|
|
363
|
+
) -> (
|
|
364
|
+
&mut CommonWorker,
|
|
365
|
+
&mut WorkflowHalf,
|
|
366
|
+
&mut ActivityHalf,
|
|
367
|
+
&mut Option<AppData>,
|
|
368
|
+
) {
|
|
331
369
|
(
|
|
332
370
|
&mut self.common,
|
|
333
371
|
&mut self.workflow_half,
|
|
334
372
|
&mut self.activity_half,
|
|
373
|
+
&mut self.app_data,
|
|
335
374
|
)
|
|
336
375
|
}
|
|
337
376
|
}
|
|
@@ -398,7 +437,11 @@ impl WorkflowHalf {
|
|
|
398
437
|
.send(activation)
|
|
399
438
|
.expect("Workflow should exist if we're sending it an activation");
|
|
400
439
|
} else {
|
|
401
|
-
bail!(
|
|
440
|
+
bail!(
|
|
441
|
+
"Got activation {:?} for unknown workflow {}",
|
|
442
|
+
activation,
|
|
443
|
+
run_id
|
|
444
|
+
);
|
|
402
445
|
};
|
|
403
446
|
|
|
404
447
|
Ok(res)
|
|
@@ -410,6 +453,7 @@ impl ActivityHalf {
|
|
|
410
453
|
fn activity_task_handler(
|
|
411
454
|
&mut self,
|
|
412
455
|
worker: Arc<dyn CoreWorker>,
|
|
456
|
+
app_data: Arc<AppData>,
|
|
413
457
|
task_queue: String,
|
|
414
458
|
activity: ActivityTask,
|
|
415
459
|
) -> Result<(), anyhow::Error> {
|
|
@@ -430,8 +474,14 @@ impl ActivityHalf {
|
|
|
430
474
|
self.task_tokens_to_cancels
|
|
431
475
|
.insert(task_token.clone().into(), ct.clone());
|
|
432
476
|
|
|
433
|
-
let (ctx, arg) =
|
|
434
|
-
|
|
477
|
+
let (ctx, arg) = ActContext::new(
|
|
478
|
+
worker.clone(),
|
|
479
|
+
app_data,
|
|
480
|
+
ct,
|
|
481
|
+
task_queue,
|
|
482
|
+
task_token.clone(),
|
|
483
|
+
start,
|
|
484
|
+
);
|
|
435
485
|
tokio::spawn(async move {
|
|
436
486
|
let output = (act_fn.act_func)(ctx, arg).await;
|
|
437
487
|
let result = match output {
|
|
@@ -713,20 +763,3 @@ where
|
|
|
713
763
|
Arc::new(wrapper)
|
|
714
764
|
}
|
|
715
765
|
}
|
|
716
|
-
|
|
717
|
-
/// Reads own binary, hashes it, and returns b64 str version of that hash
|
|
718
|
-
fn binary_id() -> &'static str {
|
|
719
|
-
use sha2::{Digest, Sha256};
|
|
720
|
-
use std::{env, fs, io};
|
|
721
|
-
|
|
722
|
-
static INSTANCE: OnceCell<String> = OnceCell::new();
|
|
723
|
-
INSTANCE.get_or_init(|| {
|
|
724
|
-
let exe_path = env::current_exe().expect("Cannot read own binary to determine binary id");
|
|
725
|
-
let mut exe_file =
|
|
726
|
-
fs::File::open(exe_path).expect("Cannot read own binary to determine binary id");
|
|
727
|
-
let mut hasher = Sha256::new();
|
|
728
|
-
io::copy(&mut exe_file, &mut hasher).expect("Copying data into binary hasher works");
|
|
729
|
-
let hash = hasher.finalize();
|
|
730
|
-
base64::encode(hash)
|
|
731
|
-
})
|
|
732
|
-
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
use std::{collections::HashMap, time::Duration};
|
|
2
|
-
use temporal_sdk_core_protos::
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
use temporal_sdk_core_protos::{
|
|
3
|
+
coresdk::{
|
|
4
|
+
child_workflow::ChildWorkflowCancellationType,
|
|
5
|
+
workflow_commands::{
|
|
6
|
+
ActivityCancellationType, ScheduleActivity, ScheduleLocalActivity,
|
|
7
|
+
StartChildWorkflowExecution,
|
|
8
|
+
},
|
|
8
9
|
},
|
|
10
|
+
temporal::api::common::v1::{Payload, RetryPolicy},
|
|
9
11
|
};
|
|
10
12
|
|
|
11
13
|
// TODO: Before release, probably best to avoid using proto types entirely here. They're awkward.
|
|
@@ -25,17 +25,20 @@ use std::{
|
|
|
25
25
|
task::Poll,
|
|
26
26
|
time::{Duration, SystemTime},
|
|
27
27
|
};
|
|
28
|
-
use temporal_sdk_core_protos::
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
28
|
+
use temporal_sdk_core_protos::{
|
|
29
|
+
coresdk::{
|
|
30
|
+
activity_result::{activity_resolution, ActivityResolution},
|
|
31
|
+
child_workflow::ChildWorkflowResult,
|
|
32
|
+
common::NamespacedWorkflowExecution,
|
|
33
|
+
workflow_activation::resolve_child_workflow_execution_start::Status as ChildWorkflowStartStatus,
|
|
34
|
+
workflow_commands::{
|
|
35
|
+
request_cancel_external_workflow_execution as cancel_we,
|
|
36
|
+
signal_external_workflow_execution as sig_we, workflow_command,
|
|
37
|
+
RequestCancelExternalWorkflowExecution, SetPatchMarker,
|
|
38
|
+
SignalExternalWorkflowExecution, StartTimer, UpsertWorkflowSearchAttributes,
|
|
39
|
+
},
|
|
38
40
|
},
|
|
41
|
+
temporal::api::common::v1::Payload,
|
|
39
42
|
};
|
|
40
43
|
use tokio::sync::{mpsc, oneshot, watch};
|
|
41
44
|
use tokio_stream::wrappers::UnboundedReceiverStream;
|
|
@@ -59,7 +62,6 @@ struct WfCtxProtectedDat {
|
|
|
59
62
|
next_child_workflow_sequence_number: u32,
|
|
60
63
|
next_cancel_external_wf_sequence_number: u32,
|
|
61
64
|
next_signal_external_wf_sequence_number: u32,
|
|
62
|
-
next_upsert_search_attrs_sequence_number: u32,
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
impl WfCtxProtectedDat {
|
|
@@ -88,11 +90,6 @@ impl WfCtxProtectedDat {
|
|
|
88
90
|
self.next_signal_external_wf_sequence_number += 1;
|
|
89
91
|
seq
|
|
90
92
|
}
|
|
91
|
-
fn next_upsert_search_attrs_wf_seq(&mut self) -> u32 {
|
|
92
|
-
let seq = self.next_upsert_search_attrs_sequence_number;
|
|
93
|
-
self.next_upsert_search_attrs_sequence_number += 1;
|
|
94
|
-
seq
|
|
95
|
-
}
|
|
96
93
|
}
|
|
97
94
|
|
|
98
95
|
#[derive(Clone, Debug, Default)]
|
|
@@ -130,7 +127,6 @@ impl WfContext {
|
|
|
130
127
|
next_child_workflow_sequence_number: 1,
|
|
131
128
|
next_cancel_external_wf_sequence_number: 1,
|
|
132
129
|
next_signal_external_wf_sequence_number: 1,
|
|
133
|
-
next_upsert_search_attrs_sequence_number: 1,
|
|
134
130
|
}),
|
|
135
131
|
},
|
|
136
132
|
rx,
|
|
@@ -289,9 +285,8 @@ impl WfContext {
|
|
|
289
285
|
/// Add or create a set of search attributes
|
|
290
286
|
pub fn upsert_search_attributes(&self, attr_iter: impl IntoIterator<Item = (String, Payload)>) {
|
|
291
287
|
self.send(RustWfCmd::NewNonblockingCmd(
|
|
292
|
-
workflow_command::Variant::
|
|
288
|
+
workflow_command::Variant::UpsertWorkflowSearchAttributes(
|
|
293
289
|
UpsertWorkflowSearchAttributes {
|
|
294
|
-
seq: self.seq_nums.write().next_upsert_search_attrs_wf_seq(),
|
|
295
290
|
search_attributes: HashMap::from_iter(attr_iter.into_iter()),
|
|
296
291
|
},
|
|
297
292
|
),
|
|
@@ -17,7 +17,6 @@ use std::{
|
|
|
17
17
|
};
|
|
18
18
|
use temporal_sdk_core_protos::{
|
|
19
19
|
coresdk::{
|
|
20
|
-
common::Payload,
|
|
21
20
|
workflow_activation::{
|
|
22
21
|
workflow_activation_job::Variant, FireTimer, NotifyHasPatch, ResolveActivity,
|
|
23
22
|
ResolveChildWorkflowExecution, ResolveChildWorkflowExecutionStart, WorkflowActivation,
|
|
@@ -33,7 +32,7 @@ use temporal_sdk_core_protos::{
|
|
|
33
32
|
},
|
|
34
33
|
workflow_completion::WorkflowActivationCompletion,
|
|
35
34
|
},
|
|
36
|
-
temporal::api::failure::v1::Failure,
|
|
35
|
+
temporal::api::{common::v1::Payload, failure::v1::Failure},
|
|
37
36
|
utilities::TryIntoOrNone,
|
|
38
37
|
};
|
|
39
38
|
use tokio::sync::{
|
|
@@ -123,11 +122,10 @@ impl WorkflowFuture {
|
|
|
123
122
|
UnblockEvent::CancelExternal(seq, _) => CommandID::CancelExternal(seq),
|
|
124
123
|
};
|
|
125
124
|
let unblocker = self.command_status.remove(&cmd_id);
|
|
126
|
-
unblocker
|
|
125
|
+
let _ = unblocker
|
|
127
126
|
.ok_or_else(|| anyhow!("Command {:?} not found to unblock!", cmd_id))?
|
|
128
127
|
.unblocker
|
|
129
|
-
.send(event)
|
|
130
|
-
.expect("Receive half of unblock channel must exist");
|
|
128
|
+
.send(event);
|
|
131
129
|
Ok(())
|
|
132
130
|
}
|
|
133
131
|
|
|
@@ -238,7 +236,14 @@ impl Future for WorkflowFuture {
|
|
|
238
236
|
'activations: loop {
|
|
239
237
|
// WF must always receive an activation first before responding with commands
|
|
240
238
|
let activation = match self.incoming_activations.poll_recv(cx) {
|
|
241
|
-
Poll::Ready(a) => a
|
|
239
|
+
Poll::Ready(a) => match a {
|
|
240
|
+
Some(act) => act,
|
|
241
|
+
None => {
|
|
242
|
+
return Poll::Ready(Err(anyhow!(
|
|
243
|
+
"Workflow future's activation channel was lost!"
|
|
244
|
+
)))
|
|
245
|
+
}
|
|
246
|
+
},
|
|
242
247
|
Poll::Pending => return Poll::Pending,
|
|
243
248
|
};
|
|
244
249
|
|
|
@@ -3,7 +3,7 @@ use crate::{
|
|
|
3
3
|
coresdk::{
|
|
4
4
|
common::{
|
|
5
5
|
build_has_change_marker_details, build_local_activity_marker_details,
|
|
6
|
-
NamespacedWorkflowExecution,
|
|
6
|
+
NamespacedWorkflowExecution,
|
|
7
7
|
},
|
|
8
8
|
external_data::LocalActivityMarkerData,
|
|
9
9
|
IntoPayloadsExt,
|
|
@@ -116,6 +116,20 @@ impl TestHistoryBuilder {
|
|
|
116
116
|
self.build_and_push_event(EventType::WorkflowExecutionCompleted, attrs.into());
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
pub fn add_workflow_execution_terminated(&mut self) {
|
|
120
|
+
let attrs = WorkflowExecutionTerminatedEventAttributes {
|
|
121
|
+
..Default::default()
|
|
122
|
+
};
|
|
123
|
+
self.build_and_push_event(EventType::WorkflowExecutionTerminated, attrs.into());
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
pub fn add_workflow_execution_timed_out(&mut self) {
|
|
127
|
+
let attrs = WorkflowExecutionTimedOutEventAttributes {
|
|
128
|
+
..Default::default()
|
|
129
|
+
};
|
|
130
|
+
self.build_and_push_event(EventType::WorkflowExecutionTimedOut, attrs.into());
|
|
131
|
+
}
|
|
132
|
+
|
|
119
133
|
pub fn add_workflow_execution_failed(&mut self) {
|
|
120
134
|
let attrs = WorkflowExecutionFailedEventAttributes {
|
|
121
135
|
workflow_task_completed_event_id: self.previous_task_completed_id,
|
|
@@ -170,7 +184,7 @@ impl TestHistoryBuilder {
|
|
|
170
184
|
&mut self,
|
|
171
185
|
scheduled_event_id: i64,
|
|
172
186
|
started_event_id: i64,
|
|
173
|
-
payload:
|
|
187
|
+
payload: Payload,
|
|
174
188
|
) {
|
|
175
189
|
self.add(
|
|
176
190
|
EventType::ActivityTaskCompleted,
|
|
@@ -254,7 +268,7 @@ impl TestHistoryBuilder {
|
|
|
254
268
|
&mut self,
|
|
255
269
|
seq: u32,
|
|
256
270
|
activity_id: &str,
|
|
257
|
-
payload: Option<
|
|
271
|
+
payload: Option<Payload>,
|
|
258
272
|
failure: Option<Failure>,
|
|
259
273
|
complete_time: Option<Timestamp>,
|
|
260
274
|
) {
|
|
@@ -283,7 +297,7 @@ impl TestHistoryBuilder {
|
|
|
283
297
|
&mut self,
|
|
284
298
|
seq: u32,
|
|
285
299
|
activity_id: &str,
|
|
286
|
-
payload:
|
|
300
|
+
payload: Payload,
|
|
287
301
|
) {
|
|
288
302
|
self.add_local_activity_marker(seq, activity_id, Some(payload), None, None);
|
|
289
303
|
}
|
|
@@ -292,7 +306,7 @@ impl TestHistoryBuilder {
|
|
|
292
306
|
&mut self,
|
|
293
307
|
seq: u32,
|
|
294
308
|
activity_id: &str,
|
|
295
|
-
payload:
|
|
309
|
+
payload: Payload,
|
|
296
310
|
complete_time: Timestamp,
|
|
297
311
|
) {
|
|
298
312
|
self.add_local_activity_marker(seq, activity_id, Some(payload), None, Some(complete_time));
|
|
@@ -60,9 +60,14 @@ impl HistoryInfo {
|
|
|
60
60
|
let next_is_completed = next_event.map_or(false, |ne| {
|
|
61
61
|
ne.event_type == EventType::WorkflowTaskCompleted as i32
|
|
62
62
|
});
|
|
63
|
-
let
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
let next_is_failed_or_timeout_or_term = next_event.map_or(false, |ne| {
|
|
64
|
+
matches!(
|
|
65
|
+
ne.event_type(),
|
|
66
|
+
EventType::WorkflowTaskFailed
|
|
67
|
+
| EventType::WorkflowTaskTimedOut
|
|
68
|
+
| EventType::WorkflowExecutionTerminated
|
|
69
|
+
| EventType::WorkflowExecutionTimedOut
|
|
70
|
+
)
|
|
66
71
|
});
|
|
67
72
|
|
|
68
73
|
if next_event.is_none() || next_is_completed {
|
|
@@ -84,10 +89,10 @@ impl HistoryInfo {
|
|
|
84
89
|
wf_type,
|
|
85
90
|
});
|
|
86
91
|
}
|
|
87
|
-
} else if next_event.is_some() && !
|
|
92
|
+
} else if next_event.is_some() && !next_is_failed_or_timeout_or_term {
|
|
88
93
|
bail!(
|
|
89
|
-
"Invalid history! Event {
|
|
90
|
-
completed, failed, or timed out"
|
|
94
|
+
"Invalid history! Event {next_event:?} should be WFT \
|
|
95
|
+
completed, failed, or timed out - or WE terminated."
|
|
91
96
|
);
|
|
92
97
|
}
|
|
93
98
|
}
|