@temporalio/core-bridge 1.15.0 → 1.16.1
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 +172 -70
- package/lib/native.d.ts +1 -1
- package/package.json +2 -2
- package/releases/aarch64-apple-darwin/index.node +0 -0
- package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
- package/releases/x86_64-apple-darwin/index.node +0 -0
- package/releases/x86_64-pc-windows-msvc/index.node +0 -0
- package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
- package/sdk-core/.github/workflows/per-pr.yml +6 -6
- package/sdk-core/AGENTS.md +41 -30
- package/sdk-core/Cargo.toml +3 -0
- package/sdk-core/README.md +15 -9
- package/sdk-core/crates/client/Cargo.toml +4 -0
- package/sdk-core/crates/client/README.md +139 -0
- package/sdk-core/crates/client/src/async_activity_handle.rs +297 -0
- package/sdk-core/crates/client/src/callback_based.rs +7 -0
- package/sdk-core/crates/client/src/errors.rs +294 -0
- package/sdk-core/crates/client/src/{raw.rs → grpc.rs} +280 -159
- package/sdk-core/crates/client/src/lib.rs +920 -1326
- package/sdk-core/crates/client/src/metrics.rs +24 -33
- package/sdk-core/crates/client/src/options_structs.rs +457 -0
- package/sdk-core/crates/client/src/replaceable.rs +5 -4
- package/sdk-core/crates/client/src/request_extensions.rs +8 -9
- package/sdk-core/crates/client/src/retry.rs +99 -54
- package/sdk-core/crates/client/src/{worker/mod.rs → worker.rs} +1 -1
- package/sdk-core/crates/client/src/workflow_handle.rs +826 -0
- package/sdk-core/crates/common/Cargo.toml +61 -2
- package/sdk-core/crates/common/build.rs +742 -12
- package/sdk-core/crates/common/protos/api_upstream/.github/workflows/ci.yml +2 -0
- package/sdk-core/crates/common/protos/api_upstream/Makefile +2 -1
- package/sdk-core/crates/common/protos/api_upstream/buf.yaml +0 -3
- package/sdk-core/crates/common/protos/api_upstream/cmd/check-path-conflicts/main.go +137 -0
- package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv2.json +1166 -770
- package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv3.yaml +1243 -750
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/deployment/v1/message.proto +2 -2
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/workflow.proto +4 -3
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/failure/v1/message.proto +1 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/history/v1/message.proto +4 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -0
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/nexus/v1/message.proto +16 -1
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +64 -6
- package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +88 -33
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/nexus/nexus.proto +4 -2
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +4 -0
- package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +5 -5
- package/sdk-core/crates/common/src/activity_definition.rs +20 -0
- package/sdk-core/crates/common/src/data_converters.rs +770 -0
- package/sdk-core/crates/common/src/envconfig.rs +5 -0
- package/sdk-core/crates/common/src/lib.rs +15 -211
- package/sdk-core/crates/common/src/payload_visitor.rs +648 -0
- package/sdk-core/crates/common/src/priority.rs +110 -0
- package/sdk-core/crates/common/src/protos/canned_histories.rs +3 -0
- package/sdk-core/crates/common/src/protos/history_builder.rs +45 -0
- package/sdk-core/crates/common/src/protos/history_info.rs +2 -0
- package/sdk-core/crates/common/src/protos/mod.rs +122 -27
- package/sdk-core/crates/common/src/protos/task_token.rs +3 -3
- package/sdk-core/crates/common/src/protos/utilities.rs +11 -0
- package/sdk-core/crates/{sdk-core → common}/src/telemetry/log_export.rs +5 -7
- package/sdk-core/crates/common/src/telemetry/metrics/core.rs +125 -0
- package/sdk-core/crates/common/src/telemetry/metrics.rs +268 -223
- package/sdk-core/crates/{sdk-core → common}/src/telemetry/otel.rs +8 -13
- package/sdk-core/crates/{sdk-core → common}/src/telemetry/prometheus_meter.rs +49 -50
- package/sdk-core/crates/{sdk-core → common}/src/telemetry/prometheus_server.rs +2 -3
- package/sdk-core/crates/common/src/telemetry.rs +264 -4
- package/sdk-core/crates/common/src/worker.rs +68 -603
- package/sdk-core/crates/common/src/workflow_definition.rs +60 -0
- package/sdk-core/crates/macros/Cargo.toml +5 -1
- package/sdk-core/crates/macros/src/activities_definitions.rs +585 -0
- package/sdk-core/crates/macros/src/fsm_impl.rs +507 -0
- package/sdk-core/crates/macros/src/lib.rs +138 -512
- package/sdk-core/crates/macros/src/macro_utils.rs +106 -0
- package/sdk-core/crates/macros/src/workflow_definitions.rs +1224 -0
- package/sdk-core/crates/sdk/Cargo.toml +19 -6
- package/sdk-core/crates/sdk/README.md +415 -0
- package/sdk-core/crates/sdk/src/activities.rs +417 -0
- package/sdk-core/crates/sdk/src/interceptors.rs +1 -1
- package/sdk-core/crates/sdk/src/lib.rs +757 -442
- package/sdk-core/crates/sdk/src/workflow_context/options.rs +45 -35
- package/sdk-core/crates/sdk/src/workflow_context.rs +1033 -289
- package/sdk-core/crates/sdk/src/workflow_future.rs +277 -213
- package/sdk-core/crates/sdk/src/workflows.rs +711 -0
- package/sdk-core/crates/sdk-core/Cargo.toml +57 -64
- package/sdk-core/crates/sdk-core/benches/workflow_replay_bench.rs +41 -35
- package/sdk-core/crates/sdk-core/machine_coverage/ActivityMachine_Coverage.puml +1 -1
- package/sdk-core/crates/sdk-core/src/abstractions.rs +6 -10
- package/sdk-core/crates/sdk-core/src/core_tests/activity_tasks.rs +6 -5
- package/sdk-core/crates/sdk-core/src/core_tests/mod.rs +13 -15
- package/sdk-core/crates/sdk-core/src/core_tests/queries.rs +21 -25
- package/sdk-core/crates/sdk-core/src/core_tests/replay_flag.rs +7 -10
- package/sdk-core/crates/sdk-core/src/core_tests/updates.rs +14 -17
- package/sdk-core/crates/sdk-core/src/core_tests/workers.rs +493 -26
- package/sdk-core/crates/sdk-core/src/core_tests/workflow_tasks.rs +4 -8
- package/sdk-core/crates/sdk-core/src/ephemeral_server/mod.rs +7 -7
- package/sdk-core/crates/sdk-core/src/histfetch.rs +20 -10
- package/sdk-core/crates/sdk-core/src/lib.rs +41 -111
- package/sdk-core/crates/sdk-core/src/pollers/mod.rs +4 -9
- package/sdk-core/crates/sdk-core/src/pollers/poll_buffer.rs +118 -19
- package/sdk-core/crates/sdk-core/src/protosext/mod.rs +2 -2
- package/sdk-core/crates/sdk-core/src/replay/mod.rs +14 -5
- package/sdk-core/crates/sdk-core/src/telemetry/metrics.rs +179 -196
- package/sdk-core/crates/sdk-core/src/telemetry/mod.rs +3 -280
- package/sdk-core/crates/sdk-core/src/test_help/integ_helpers.rs +6 -9
- package/sdk-core/crates/sdk-core/src/test_help/unit_helpers.rs +3 -6
- package/sdk-core/crates/sdk-core/src/worker/activities/local_activities.rs +11 -14
- package/sdk-core/crates/sdk-core/src/worker/activities.rs +16 -19
- package/sdk-core/crates/sdk-core/src/worker/client/mocks.rs +9 -5
- package/sdk-core/crates/sdk-core/src/worker/client.rs +103 -81
- package/sdk-core/crates/sdk-core/src/worker/heartbeat.rs +7 -11
- package/sdk-core/crates/sdk-core/src/worker/mod.rs +1124 -229
- package/sdk-core/crates/sdk-core/src/worker/nexus.rs +145 -23
- package/sdk-core/crates/sdk-core/src/worker/slot_provider.rs +2 -2
- package/sdk-core/crates/sdk-core/src/worker/tuner/fixed_size.rs +2 -2
- package/sdk-core/crates/sdk-core/src/worker/tuner/resource_based.rs +13 -13
- package/sdk-core/crates/sdk-core/src/worker/tuner.rs +28 -8
- package/sdk-core/crates/sdk-core/src/worker/workflow/driven_workflow.rs +9 -3
- package/sdk-core/crates/sdk-core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +21 -22
- package/sdk-core/crates/sdk-core/src/worker/workflow/machines/workflow_machines.rs +19 -4
- package/sdk-core/crates/sdk-core/src/worker/workflow/managed_run.rs +14 -18
- package/sdk-core/crates/sdk-core/src/worker/workflow/mod.rs +4 -6
- package/sdk-core/crates/sdk-core/src/worker/workflow/run_cache.rs +4 -7
- package/sdk-core/crates/sdk-core/src/worker/workflow/wft_extraction.rs +2 -4
- package/sdk-core/crates/sdk-core/src/worker/workflow/wft_poller.rs +8 -9
- package/sdk-core/crates/sdk-core/src/worker/workflow/workflow_stream.rs +1 -3
- package/sdk-core/crates/sdk-core/tests/activities_procmacro.rs +6 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/basic_pass.rs +54 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/invalid_self_type_fail.rs +18 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/invalid_self_type_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/missing_context_fail.rs +14 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/missing_context_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/multi_arg_pass.rs +48 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/no_input_pass.rs +14 -0
- package/sdk-core/crates/sdk-core/tests/activities_trybuild/no_return_type_pass.rs +19 -0
- package/sdk-core/crates/sdk-core/tests/cloud_tests.rs +14 -5
- package/sdk-core/crates/sdk-core/tests/common/activity_functions.rs +55 -0
- package/sdk-core/crates/sdk-core/tests/common/mod.rs +241 -196
- package/sdk-core/crates/sdk-core/tests/common/workflows.rs +41 -28
- package/sdk-core/crates/sdk-core/tests/global_metric_tests.rs +3 -5
- package/sdk-core/crates/sdk-core/tests/heavy_tests/fuzzy_workflow.rs +73 -64
- package/sdk-core/crates/sdk-core/tests/heavy_tests.rs +298 -252
- package/sdk-core/crates/sdk-core/tests/integ_tests/async_activity_client_tests.rs +230 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/client_tests.rs +94 -57
- package/sdk-core/crates/sdk-core/tests/integ_tests/data_converter_tests.rs +381 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +16 -12
- package/sdk-core/crates/sdk-core/tests/integ_tests/heartbeat_tests.rs +48 -40
- package/sdk-core/crates/sdk-core/tests/integ_tests/metrics_tests.rs +327 -255
- package/sdk-core/crates/sdk-core/tests/integ_tests/pagination_tests.rs +50 -45
- package/sdk-core/crates/sdk-core/tests/integ_tests/polling_tests.rs +147 -126
- package/sdk-core/crates/sdk-core/tests/integ_tests/queries_tests.rs +103 -89
- package/sdk-core/crates/sdk-core/tests/integ_tests/update_tests.rs +609 -453
- package/sdk-core/crates/sdk-core/tests/integ_tests/visibility_tests.rs +80 -62
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_heartbeat_tests.rs +360 -231
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_tests.rs +248 -185
- package/sdk-core/crates/sdk-core/tests/integ_tests/worker_versioning_tests.rs +52 -43
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_client_tests.rs +180 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/activities.rs +428 -315
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +82 -56
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +56 -28
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +364 -243
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/client_interactions.rs +552 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +101 -42
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +243 -147
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/eager.rs +98 -28
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +1475 -1036
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +73 -41
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +397 -238
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/patches.rs +414 -189
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/queries.rs +415 -0
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/replay.rs +96 -36
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/resets.rs +154 -137
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/signals.rs +183 -105
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +85 -38
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/timers.rs +142 -40
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +73 -54
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests.rs +363 -226
- package/sdk-core/crates/sdk-core/tests/main.rs +17 -15
- package/sdk-core/crates/sdk-core/tests/manual_tests.rs +207 -152
- package/sdk-core/crates/sdk-core/tests/shared_tests/mod.rs +65 -34
- package/sdk-core/crates/sdk-core/tests/shared_tests/priority.rs +107 -84
- package/sdk-core/crates/sdk-core/tests/workflows_procmacro.rs +6 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/async_query_fail.rs +26 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/async_query_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/basic_pass.rs +49 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/minimal_pass.rs +21 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/mut_query_fail.rs +26 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/mut_query_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/sync_run_fail.rs +21 -0
- package/sdk-core/crates/sdk-core/tests/workflows_trybuild/sync_run_fail.stderr +5 -0
- package/sdk-core/crates/sdk-core-c-bridge/Cargo.toml +7 -1
- package/sdk-core/crates/sdk-core-c-bridge/include/temporal-sdk-core-c-bridge.h +14 -14
- package/sdk-core/crates/sdk-core-c-bridge/src/client.rs +83 -74
- package/sdk-core/crates/sdk-core-c-bridge/src/metric.rs +9 -14
- package/sdk-core/crates/sdk-core-c-bridge/src/runtime.rs +1 -2
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/context.rs +13 -13
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/mod.rs +6 -6
- package/sdk-core/crates/sdk-core-c-bridge/src/tests/utils.rs +3 -4
- package/sdk-core/crates/sdk-core-c-bridge/src/worker.rs +62 -75
- package/sdk-core/rustfmt.toml +2 -1
- package/src/client.rs +205 -318
- package/src/metrics.rs +22 -30
- package/src/runtime.rs +4 -5
- package/src/worker.rs +16 -19
- package/ts/native.ts +1 -1
- package/sdk-core/crates/client/src/workflow_handle/mod.rs +0 -212
- package/sdk-core/crates/common/src/errors.rs +0 -85
- package/sdk-core/crates/common/tests/worker_task_types_test.rs +0 -129
- package/sdk-core/crates/sdk/src/activity_context.rs +0 -238
- package/sdk-core/crates/sdk/src/app_data.rs +0 -37
- package/sdk-core/crates/sdk-core/tests/integ_tests/activity_functions.rs +0 -5
- package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +0 -61
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
use crate::common::CoreWfStarter;
|
|
2
|
+
use rstest::rstest;
|
|
3
|
+
use std::{sync::Arc, time::Duration};
|
|
4
|
+
use temporalio_client::{ActivityIdentifier, WorkflowStartOptions};
|
|
5
|
+
use temporalio_common::protos::{
|
|
6
|
+
coresdk::{AsJsonPayloadExt, workflow_commands::ActivityCancellationType},
|
|
7
|
+
temporal::api::{
|
|
8
|
+
common::v1::RetryPolicy,
|
|
9
|
+
failure::v1::{ApplicationFailureInfo, Failure, failure::FailureInfo},
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
use temporalio_macros::{activities, workflow, workflow_methods};
|
|
13
|
+
use temporalio_sdk::{
|
|
14
|
+
ActivityExecutionError, ActivityOptions, CancellableFuture, WorkflowContext, WorkflowResult,
|
|
15
|
+
activities::{ActivityContext, ActivityError},
|
|
16
|
+
};
|
|
17
|
+
use tokio::sync::mpsc;
|
|
18
|
+
|
|
19
|
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
|
20
|
+
enum Outcome {
|
|
21
|
+
Success,
|
|
22
|
+
Failure,
|
|
23
|
+
Cancellation,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
27
|
+
enum IdentifierType {
|
|
28
|
+
TaskToken,
|
|
29
|
+
ById,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
#[rstest]
|
|
33
|
+
#[tokio::test]
|
|
34
|
+
async fn async_activity_completions(
|
|
35
|
+
#[values(Outcome::Success, Outcome::Failure, Outcome::Cancellation)] outcome: Outcome,
|
|
36
|
+
#[values(IdentifierType::TaskToken, IdentifierType::ById)] identifier_type: IdentifierType,
|
|
37
|
+
) {
|
|
38
|
+
let wf_name = format!("async_activity_{outcome:?}_{identifier_type:?}");
|
|
39
|
+
let mut starter = CoreWfStarter::new(&wf_name);
|
|
40
|
+
// Speeds up cancel test
|
|
41
|
+
starter.set_core_cfg_mutator(|wc| wc.max_heartbeat_throttle_interval = Duration::from_secs(1));
|
|
42
|
+
let async_response = "agence";
|
|
43
|
+
|
|
44
|
+
#[derive(Clone)]
|
|
45
|
+
struct SharedActivityInfo {
|
|
46
|
+
task_token: Vec<u8>,
|
|
47
|
+
workflow_id: String,
|
|
48
|
+
run_id: String,
|
|
49
|
+
activity_id: String,
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
let (info_tx, mut info_rx) = mpsc::channel::<SharedActivityInfo>(1);
|
|
53
|
+
|
|
54
|
+
struct AsyncActivities {
|
|
55
|
+
info_tx: mpsc::Sender<SharedActivityInfo>,
|
|
56
|
+
}
|
|
57
|
+
#[activities]
|
|
58
|
+
impl AsyncActivities {
|
|
59
|
+
#[activity]
|
|
60
|
+
async fn complete_async_activity(
|
|
61
|
+
self: Arc<Self>,
|
|
62
|
+
ctx: ActivityContext,
|
|
63
|
+
expected_outcome: Outcome,
|
|
64
|
+
) -> Result<String, ActivityError> {
|
|
65
|
+
// For cancellation, wait until the workflow has requested cancellation
|
|
66
|
+
if expected_outcome == Outcome::Cancellation {
|
|
67
|
+
tokio::select! {
|
|
68
|
+
_ = async {
|
|
69
|
+
loop {
|
|
70
|
+
ctx.record_heartbeat(vec![]);
|
|
71
|
+
tokio::time::sleep(Duration::from_millis(500)).await;
|
|
72
|
+
}
|
|
73
|
+
} => (),
|
|
74
|
+
_ = ctx.cancelled() => (),
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
let activity_info = ctx.info();
|
|
79
|
+
let wf_exec = activity_info.workflow_execution.as_ref().unwrap();
|
|
80
|
+
let info = SharedActivityInfo {
|
|
81
|
+
task_token: activity_info.task_token.clone(),
|
|
82
|
+
workflow_id: wf_exec.workflow_id.clone(),
|
|
83
|
+
run_id: wf_exec.run_id.clone(),
|
|
84
|
+
activity_id: activity_info.activity_id.clone(),
|
|
85
|
+
};
|
|
86
|
+
let _ = self.info_tx.send(info).await;
|
|
87
|
+
Err(ActivityError::WillCompleteAsync)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
starter
|
|
92
|
+
.sdk_config
|
|
93
|
+
.register_activities(AsyncActivities { info_tx });
|
|
94
|
+
|
|
95
|
+
let mut worker = starter.worker().await;
|
|
96
|
+
let client = starter.get_client().await;
|
|
97
|
+
|
|
98
|
+
#[workflow]
|
|
99
|
+
#[derive(Default)]
|
|
100
|
+
struct AsyncCompletionWorkflow;
|
|
101
|
+
|
|
102
|
+
#[workflow_methods]
|
|
103
|
+
impl AsyncCompletionWorkflow {
|
|
104
|
+
#[run]
|
|
105
|
+
async fn run(
|
|
106
|
+
ctx: &mut WorkflowContext<Self>,
|
|
107
|
+
expected_outcome: Outcome,
|
|
108
|
+
) -> WorkflowResult<()> {
|
|
109
|
+
let async_response = "agence";
|
|
110
|
+
let activity_future = ctx.start_activity(
|
|
111
|
+
AsyncActivities::complete_async_activity,
|
|
112
|
+
expected_outcome,
|
|
113
|
+
ActivityOptions {
|
|
114
|
+
start_to_close_timeout: Some(Duration::from_secs(30)),
|
|
115
|
+
retry_policy: Some(RetryPolicy {
|
|
116
|
+
maximum_attempts: 1,
|
|
117
|
+
..Default::default()
|
|
118
|
+
}),
|
|
119
|
+
cancellation_type: ActivityCancellationType::WaitCancellationCompleted,
|
|
120
|
+
..Default::default()
|
|
121
|
+
},
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
// For cancellation, wait a bit to let the activity start, then request cancel
|
|
125
|
+
if expected_outcome == Outcome::Cancellation {
|
|
126
|
+
ctx.timer(Duration::from_millis(1)).await;
|
|
127
|
+
activity_future.cancel();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
let activity_result = activity_future.await;
|
|
131
|
+
|
|
132
|
+
match expected_outcome {
|
|
133
|
+
Outcome::Success => {
|
|
134
|
+
assert_eq!(activity_result.expect("expected success"), async_response);
|
|
135
|
+
}
|
|
136
|
+
Outcome::Failure => {
|
|
137
|
+
let err = activity_result.expect_err("expected failure");
|
|
138
|
+
if let ActivityExecutionError::Failed(failure) = err {
|
|
139
|
+
// The failure we sent is wrapped as the cause
|
|
140
|
+
let cause = failure.cause.expect("cause should be present");
|
|
141
|
+
assert_eq!(cause.message, "async failure reason");
|
|
142
|
+
} else {
|
|
143
|
+
panic!("expected Failed, got {err:?}");
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
Outcome::Cancellation => {
|
|
147
|
+
let err = activity_result.expect_err("expected cancellation");
|
|
148
|
+
assert!(
|
|
149
|
+
matches!(err, ActivityExecutionError::Cancelled(_)),
|
|
150
|
+
"expected Cancelled, got {err:?}"
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
Ok(())
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
worker.register_workflow::<AsyncCompletionWorkflow>();
|
|
159
|
+
|
|
160
|
+
let completion_task = tokio::spawn(async move {
|
|
161
|
+
let info = info_rx.recv().await.expect("should receive activity info");
|
|
162
|
+
|
|
163
|
+
eprintln!(
|
|
164
|
+
"DEBUG: Received activity info - task_token_len={}, workflow_id={}, run_id={}, activity_id={}",
|
|
165
|
+
info.task_token.len(),
|
|
166
|
+
info.workflow_id,
|
|
167
|
+
info.run_id,
|
|
168
|
+
info.activity_id
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
let identifier = match identifier_type {
|
|
172
|
+
IdentifierType::TaskToken => {
|
|
173
|
+
eprintln!("DEBUG: Using TaskToken identifier");
|
|
174
|
+
ActivityIdentifier::TaskToken(info.task_token.into())
|
|
175
|
+
}
|
|
176
|
+
IdentifierType::ById => {
|
|
177
|
+
eprintln!("DEBUG: Using ById identifier");
|
|
178
|
+
ActivityIdentifier::by_id(info.workflow_id, info.run_id, info.activity_id)
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
let handle = client.get_async_activity_handle(identifier);
|
|
183
|
+
eprintln!("DEBUG: Calling {:?} on handle", outcome);
|
|
184
|
+
|
|
185
|
+
let result = match outcome {
|
|
186
|
+
Outcome::Success => {
|
|
187
|
+
handle
|
|
188
|
+
.complete(Some(async_response.as_json_payload().unwrap().into()))
|
|
189
|
+
.await
|
|
190
|
+
}
|
|
191
|
+
Outcome::Failure => {
|
|
192
|
+
handle
|
|
193
|
+
.fail(
|
|
194
|
+
Failure {
|
|
195
|
+
message: "async failure reason".to_string(),
|
|
196
|
+
failure_info: Some(FailureInfo::ApplicationFailureInfo(
|
|
197
|
+
ApplicationFailureInfo {
|
|
198
|
+
r#type: "TestFailure".to_string(),
|
|
199
|
+
..Default::default()
|
|
200
|
+
},
|
|
201
|
+
)),
|
|
202
|
+
..Default::default()
|
|
203
|
+
},
|
|
204
|
+
None,
|
|
205
|
+
)
|
|
206
|
+
.await
|
|
207
|
+
}
|
|
208
|
+
Outcome::Cancellation => handle.report_cancelation(None).await,
|
|
209
|
+
};
|
|
210
|
+
if let Err(e) = &result {
|
|
211
|
+
eprintln!(
|
|
212
|
+
"ERROR: async activity completion failed: {e:?} (outcome={outcome:?}, identifier={identifier_type:?})"
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
result.expect("async activity completion should succeed");
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
let task_queue = starter.get_task_queue().to_owned();
|
|
219
|
+
worker
|
|
220
|
+
.submit_workflow(
|
|
221
|
+
AsyncCompletionWorkflow::run,
|
|
222
|
+
outcome,
|
|
223
|
+
WorkflowStartOptions::new(task_queue, wf_name).build(),
|
|
224
|
+
)
|
|
225
|
+
.await
|
|
226
|
+
.unwrap();
|
|
227
|
+
|
|
228
|
+
worker.run_until_done().await.unwrap();
|
|
229
|
+
completion_task.await.unwrap();
|
|
230
|
+
}
|
|
@@ -18,13 +18,13 @@ use std::{
|
|
|
18
18
|
time::Duration,
|
|
19
19
|
};
|
|
20
20
|
use temporalio_client::{
|
|
21
|
-
Namespace, RETRYABLE_ERROR_CODES, RetryOptions,
|
|
22
|
-
proxy::HttpConnectProxyOptions,
|
|
21
|
+
Connection, Namespace, RETRYABLE_ERROR_CODES, RetryOptions, UntypedWorkflow,
|
|
22
|
+
grpc::WorkflowService, proxy::HttpConnectProxyOptions,
|
|
23
23
|
};
|
|
24
24
|
use temporalio_common::protos::temporal::api::{
|
|
25
25
|
cloud::cloudservice::v1::GetNamespaceRequest,
|
|
26
26
|
workflowservice::v1::{
|
|
27
|
-
DescribeNamespaceRequest, GetWorkflowExecutionHistoryRequest,
|
|
27
|
+
DescribeNamespaceRequest, GetWorkflowExecutionHistoryRequest, ListNamespacesRequest,
|
|
28
28
|
RespondActivityTaskCanceledResponse,
|
|
29
29
|
},
|
|
30
30
|
};
|
|
@@ -42,7 +42,12 @@ async fn can_use_retry_client() {
|
|
|
42
42
|
let mut core = CoreWfStarter::new("retry_client");
|
|
43
43
|
let retry_client = core.get_client().await;
|
|
44
44
|
for _ in 0..10 {
|
|
45
|
-
|
|
45
|
+
WorkflowService::list_namespaces(
|
|
46
|
+
&mut retry_client.clone(),
|
|
47
|
+
ListNamespacesRequest::default().into_request(),
|
|
48
|
+
)
|
|
49
|
+
.await
|
|
50
|
+
.unwrap();
|
|
46
51
|
tokio::time::sleep(Duration::from_millis(10)).await;
|
|
47
52
|
}
|
|
48
53
|
}
|
|
@@ -50,8 +55,8 @@ async fn can_use_retry_client() {
|
|
|
50
55
|
#[tokio::test]
|
|
51
56
|
async fn can_use_retry_raw_client() {
|
|
52
57
|
let opts = get_integ_server_options();
|
|
53
|
-
let mut
|
|
54
|
-
|
|
58
|
+
let mut connection = Connection::connect(opts).await.unwrap();
|
|
59
|
+
connection
|
|
55
60
|
.describe_namespace(
|
|
56
61
|
DescribeNamespaceRequest {
|
|
57
62
|
namespace: NAMESPACE.to_string(),
|
|
@@ -66,18 +71,18 @@ async fn can_use_retry_raw_client() {
|
|
|
66
71
|
#[tokio::test]
|
|
67
72
|
async fn calls_get_system_info() {
|
|
68
73
|
let opts = get_integ_server_options();
|
|
69
|
-
let
|
|
70
|
-
assert!(
|
|
74
|
+
let connection = Connection::connect(opts).await.unwrap();
|
|
75
|
+
assert!(connection.capabilities().is_some());
|
|
71
76
|
}
|
|
72
77
|
|
|
73
78
|
#[tokio::test]
|
|
74
79
|
async fn per_call_timeout_respected_whole_client() {
|
|
75
80
|
let opts = get_integ_server_options();
|
|
76
|
-
let mut
|
|
81
|
+
let mut connection = Connection::connect(opts).await.unwrap();
|
|
77
82
|
let mut hm = HashMap::new();
|
|
78
83
|
hm.insert("grpc-timeout".to_string(), "0S".to_string());
|
|
79
|
-
|
|
80
|
-
let err =
|
|
84
|
+
connection.set_headers(hm).unwrap();
|
|
85
|
+
let err = connection
|
|
81
86
|
.describe_namespace(
|
|
82
87
|
DescribeNamespaceRequest {
|
|
83
88
|
namespace: NAMESPACE.to_string(),
|
|
@@ -93,14 +98,14 @@ async fn per_call_timeout_respected_whole_client() {
|
|
|
93
98
|
#[tokio::test]
|
|
94
99
|
async fn per_call_timeout_respected_one_call() {
|
|
95
100
|
let opts = get_integ_server_options();
|
|
96
|
-
let mut
|
|
101
|
+
let mut connection = Connection::connect(opts).await.unwrap();
|
|
97
102
|
|
|
98
103
|
let mut req = Request::new(DescribeNamespaceRequest {
|
|
99
104
|
namespace: NAMESPACE.to_string(),
|
|
100
105
|
..Default::default()
|
|
101
106
|
});
|
|
102
107
|
req.set_timeout(Duration::from_millis(0));
|
|
103
|
-
let res =
|
|
108
|
+
let res = connection.describe_namespace(req).await;
|
|
104
109
|
assert_matches!(
|
|
105
110
|
res.unwrap_err().code(),
|
|
106
111
|
Code::DeadlineExceeded | Code::Cancelled
|
|
@@ -113,14 +118,13 @@ async fn timeouts_respected_one_call_fake_server() {
|
|
|
113
118
|
let header_rx = &mut fs.header_rx;
|
|
114
119
|
|
|
115
120
|
let mut opts = get_integ_server_options();
|
|
116
|
-
|
|
117
|
-
.parse()
|
|
121
|
+
opts.target = format!("http://localhost:{}", fs.addr.port())
|
|
122
|
+
.parse::<url::Url>()
|
|
118
123
|
.unwrap();
|
|
119
|
-
opts.
|
|
120
|
-
opts.skip_get_system_info = true;
|
|
124
|
+
opts.set_skip_get_system_info(true);
|
|
121
125
|
opts.retry_options = RetryOptions::no_retries();
|
|
122
126
|
|
|
123
|
-
let mut
|
|
127
|
+
let mut connection = Connection::connect(opts).await.unwrap();
|
|
124
128
|
|
|
125
129
|
macro_rules! call_client {
|
|
126
130
|
($client:ident, $trx:ident, $client_fn:ident, $msg:expr) => {
|
|
@@ -134,13 +138,13 @@ async fn timeouts_respected_one_call_fake_server() {
|
|
|
134
138
|
}
|
|
135
139
|
|
|
136
140
|
call_client!(
|
|
137
|
-
|
|
141
|
+
connection,
|
|
138
142
|
header_rx,
|
|
139
143
|
get_workflow_execution_history,
|
|
140
144
|
Default::default()
|
|
141
145
|
);
|
|
142
146
|
call_client!(
|
|
143
|
-
|
|
147
|
+
connection,
|
|
144
148
|
header_rx,
|
|
145
149
|
get_workflow_execution_history,
|
|
146
150
|
GetWorkflowExecutionHistoryRequest {
|
|
@@ -150,13 +154,13 @@ async fn timeouts_respected_one_call_fake_server() {
|
|
|
150
154
|
}
|
|
151
155
|
);
|
|
152
156
|
call_client!(
|
|
153
|
-
|
|
157
|
+
connection,
|
|
154
158
|
header_rx,
|
|
155
159
|
update_workflow_execution,
|
|
156
160
|
Default::default()
|
|
157
161
|
);
|
|
158
162
|
call_client!(
|
|
159
|
-
|
|
163
|
+
connection,
|
|
160
164
|
header_rx,
|
|
161
165
|
poll_workflow_execution_update,
|
|
162
166
|
Default::default()
|
|
@@ -185,14 +189,15 @@ async fn non_retryable_errors() {
|
|
|
185
189
|
.await;
|
|
186
190
|
|
|
187
191
|
let mut opts = get_integ_server_options();
|
|
188
|
-
|
|
189
|
-
.parse()
|
|
192
|
+
opts.target = format!("http://localhost:{}", fs.addr.port())
|
|
193
|
+
.parse::<url::Url>()
|
|
190
194
|
.unwrap();
|
|
191
|
-
opts.
|
|
192
|
-
|
|
193
|
-
let
|
|
195
|
+
opts.set_skip_get_system_info(true);
|
|
196
|
+
let connection = Connection::connect(opts).await.unwrap();
|
|
197
|
+
let client_opts = temporalio_client::ClientOptions::new("ns").build();
|
|
198
|
+
let client = temporalio_client::Client::new(connection, client_opts).unwrap();
|
|
194
199
|
|
|
195
|
-
let result = client.
|
|
200
|
+
let result = client.count_workflows("whatever", Default::default()).await;
|
|
196
201
|
|
|
197
202
|
// Expecting an error after a single attempt, since there was a non-retryable error.
|
|
198
203
|
assert!(result.is_err());
|
|
@@ -225,17 +230,18 @@ async fn retryable_errors() {
|
|
|
225
230
|
.await;
|
|
226
231
|
|
|
227
232
|
let mut opts = get_integ_server_options();
|
|
228
|
-
|
|
229
|
-
.parse()
|
|
233
|
+
opts.target = format!("http://localhost:{}", fs.addr.port())
|
|
234
|
+
.parse::<url::Url>()
|
|
230
235
|
.unwrap();
|
|
231
|
-
opts.
|
|
232
|
-
|
|
233
|
-
let
|
|
236
|
+
opts.set_skip_get_system_info(true);
|
|
237
|
+
let connection = Connection::connect(opts).await.unwrap();
|
|
238
|
+
let client_opts = temporalio_client::ClientOptions::new("ns").build();
|
|
239
|
+
let client = temporalio_client::Client::new(connection, client_opts).unwrap();
|
|
234
240
|
|
|
235
|
-
let result = client.
|
|
241
|
+
let result = client.count_workflows("whatever", Default::default()).await;
|
|
236
242
|
|
|
237
243
|
// Expecting successful response after retries
|
|
238
|
-
assert!(result.is_ok());
|
|
244
|
+
assert!(result.is_ok(), "{:?}", result);
|
|
239
245
|
let mut all_calls = vec![];
|
|
240
246
|
fs.header_rx.recv_many(&mut all_calls, 9999).await;
|
|
241
247
|
// Should be 4 attempts
|
|
@@ -269,27 +275,38 @@ async fn namespace_header_attached_to_relevant_calls() {
|
|
|
269
275
|
.unwrap();
|
|
270
276
|
});
|
|
271
277
|
|
|
278
|
+
let namespace = "namespace";
|
|
272
279
|
let mut opts = get_integ_server_options();
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
280
|
+
opts.target = format!("http://localhost:{}", addr.port())
|
|
281
|
+
.parse::<url::Url>()
|
|
282
|
+
.unwrap();
|
|
283
|
+
opts.set_skip_get_system_info(true);
|
|
276
284
|
opts.retry_options = RetryOptions::no_retries();
|
|
277
|
-
|
|
278
|
-
let
|
|
279
|
-
let client =
|
|
285
|
+
let connection = Connection::connect(opts).await.unwrap();
|
|
286
|
+
let client_opts = temporalio_client::ClientOptions::new(namespace).build();
|
|
287
|
+
let client = temporalio_client::Client::new(connection, client_opts).unwrap();
|
|
280
288
|
|
|
281
289
|
let _ = client
|
|
282
|
-
.
|
|
290
|
+
.get_workflow_handle::<UntypedWorkflow>("hi")
|
|
291
|
+
.fetch_history(Default::default())
|
|
283
292
|
.await;
|
|
284
293
|
let val = header_rx.recv().await.unwrap();
|
|
285
294
|
assert_eq!(namespace, val);
|
|
286
|
-
let _ =
|
|
295
|
+
let _ = WorkflowService::list_namespaces(
|
|
296
|
+
&mut client.clone(),
|
|
297
|
+
ListNamespacesRequest::default().into_request(),
|
|
298
|
+
)
|
|
299
|
+
.await;
|
|
287
300
|
let val = header_rx.recv().await.unwrap();
|
|
288
301
|
// List namespaces is not namespace-specific
|
|
289
302
|
assert_eq!("", val);
|
|
290
|
-
let _ =
|
|
291
|
-
.
|
|
292
|
-
.
|
|
303
|
+
let _ = WorkflowService::describe_namespace(
|
|
304
|
+
&mut client.clone(),
|
|
305
|
+
Namespace::Name("Other".to_string())
|
|
306
|
+
.into_describe_namespace_request()
|
|
307
|
+
.into_request(),
|
|
308
|
+
)
|
|
309
|
+
.await;
|
|
293
310
|
let val = header_rx.recv().await.unwrap();
|
|
294
311
|
assert_eq!("Other", val);
|
|
295
312
|
|
|
@@ -313,15 +330,17 @@ async fn cloud_ops_test() {
|
|
|
313
330
|
let namespace =
|
|
314
331
|
env::var("TEMPORAL_CLIENT_CLOUD_NAMESPACE").expect("namespace env var must exist");
|
|
315
332
|
let mut opts = get_integ_server_options();
|
|
316
|
-
opts.
|
|
333
|
+
opts.target = "https://saas-api.tmprl.cloud:443"
|
|
334
|
+
.parse::<url::Url>()
|
|
335
|
+
.unwrap();
|
|
317
336
|
opts.api_key = Some(api_key);
|
|
318
337
|
opts.headers = Some({
|
|
319
338
|
let mut hm = HashMap::new();
|
|
320
339
|
hm.insert("temporal-cloud-api-version".to_string(), api_version);
|
|
321
340
|
hm
|
|
322
341
|
});
|
|
323
|
-
let
|
|
324
|
-
let mut cloud_client =
|
|
342
|
+
let connection = Connection::connect(opts).await.unwrap();
|
|
343
|
+
let mut cloud_client = connection.cloud_service();
|
|
325
344
|
let res = cloud_client
|
|
326
345
|
.get_namespace(
|
|
327
346
|
GetNamespaceRequest {
|
|
@@ -353,14 +372,20 @@ async fn http_proxy() {
|
|
|
353
372
|
// General client options
|
|
354
373
|
let mut opts = get_integ_server_options();
|
|
355
374
|
opts.retry_options = RetryOptions::no_retries();
|
|
356
|
-
opts.
|
|
375
|
+
opts.set_skip_get_system_info(true);
|
|
357
376
|
|
|
358
377
|
// Connect client with no proxy and make call and confirm reached
|
|
359
|
-
opts.
|
|
378
|
+
opts.target = format!("http://127.0.0.1:{}", server.addr.port())
|
|
360
379
|
.parse()
|
|
361
380
|
.unwrap();
|
|
362
|
-
let
|
|
363
|
-
let
|
|
381
|
+
let connection = Connection::connect(opts.clone()).await.unwrap();
|
|
382
|
+
let client_opts = temporalio_client::ClientOptions::new("my-namespace").build();
|
|
383
|
+
let client = temporalio_client::Client::new(connection, client_opts).unwrap();
|
|
384
|
+
let _ = WorkflowService::list_namespaces(
|
|
385
|
+
&mut client.clone(),
|
|
386
|
+
ListNamespacesRequest::default().into_request(),
|
|
387
|
+
)
|
|
388
|
+
.await;
|
|
364
389
|
assert!(call_count.load(Ordering::SeqCst) == 1);
|
|
365
390
|
assert!(tcp_proxy.hit_count() == 0);
|
|
366
391
|
|
|
@@ -369,8 +394,14 @@ async fn http_proxy() {
|
|
|
369
394
|
target_addr: tcp_proxy_addr.to_string(),
|
|
370
395
|
basic_auth: None,
|
|
371
396
|
});
|
|
372
|
-
let
|
|
373
|
-
let
|
|
397
|
+
let connection = Connection::connect(opts.clone()).await.unwrap();
|
|
398
|
+
let client_opts = temporalio_client::ClientOptions::new("my-namespace").build();
|
|
399
|
+
let proxied_client = temporalio_client::Client::new(connection, client_opts).unwrap();
|
|
400
|
+
let _ = WorkflowService::list_namespaces(
|
|
401
|
+
&mut proxied_client.clone(),
|
|
402
|
+
ListNamespacesRequest::default().into_request(),
|
|
403
|
+
)
|
|
404
|
+
.await;
|
|
374
405
|
assert!(call_count.load(Ordering::SeqCst) == 2);
|
|
375
406
|
assert!(tcp_proxy.hit_count() == 1);
|
|
376
407
|
|
|
@@ -391,8 +422,14 @@ async fn http_proxy() {
|
|
|
391
422
|
target_addr: format!("unix:{}", sock_path.to_str().unwrap()),
|
|
392
423
|
basic_auth: None,
|
|
393
424
|
});
|
|
394
|
-
let
|
|
395
|
-
let
|
|
425
|
+
let connection = Connection::connect(opts.clone()).await.unwrap();
|
|
426
|
+
let client_opts = temporalio_client::ClientOptions::new("my-namespace").build();
|
|
427
|
+
let proxied_client = temporalio_client::Client::new(connection, client_opts).unwrap();
|
|
428
|
+
let _ = WorkflowService::list_namespaces(
|
|
429
|
+
&mut proxied_client.clone(),
|
|
430
|
+
ListNamespacesRequest::default().into_request(),
|
|
431
|
+
)
|
|
432
|
+
.await;
|
|
396
433
|
assert!(call_count.load(Ordering::SeqCst) == 3);
|
|
397
434
|
assert!(unix_proxy.hit_count() == 1);
|
|
398
435
|
|