@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
package/sdk-core/README.md
CHANGED
|
@@ -7,6 +7,20 @@ Core SDK that can be used as a base for other Temporal SDKs. It is currently use
|
|
|
7
7
|
- [.NET SDK](https://github.com/temporalio/sdk-dotnet/)
|
|
8
8
|
- [Ruby SDK](https://github.com/temporalio/sdk-ruby/)
|
|
9
9
|
|
|
10
|
+
# Temporal Rust SDK
|
|
11
|
+
|
|
12
|
+
[](https://crates.io/crates/temporalio-sdk)
|
|
13
|
+
[](https://docs.rs/temporalio-sdk)
|
|
14
|
+
|
|
15
|
+
Currently prerelease, see more in the [SDK README.md](crates/sdk/README.md)
|
|
16
|
+
|
|
17
|
+
# Temporal Rust Client
|
|
18
|
+
|
|
19
|
+
[](https://crates.io/crates/temporalio-client)
|
|
20
|
+
[](https://docs.rs/temporalio-client)
|
|
21
|
+
|
|
22
|
+
Currently prerelease, see more in the [client README.md](crates/client/README.md)
|
|
23
|
+
|
|
10
24
|
# Documentation
|
|
11
25
|
|
|
12
26
|
Core SDK documentation can be generated with `cargo doc`, output will be placed in the
|
|
@@ -90,7 +104,7 @@ equivalent.
|
|
|
90
104
|
This repo uses a subtree for upstream protobuf files. The path `crates/common/protos/api_upstream`
|
|
91
105
|
is a subtree. To update it, use:
|
|
92
106
|
|
|
93
|
-
`git pull --squash --rebase=false -s subtree -
|
|
107
|
+
`git pull --squash --rebase=false -s subtree -X subtree=crates/common/protos/api_upstream ssh://git@github.com/temporalio/api.git master --allow-unrelated-histories`
|
|
94
108
|
|
|
95
109
|
Do not question why this git command is the way it is. It is not our place to interpret git's ways.
|
|
96
110
|
This same approach can be taken for updating `crates/common/protos/api_cloud_upstream` from the
|
|
@@ -127,11 +141,3 @@ Any error which is returned from a public interface should be well-typed, and we
|
|
|
127
141
|
|
|
128
142
|
Errors returned from things only used in testing are free to use
|
|
129
143
|
[anyhow](https://github.com/dtolnay/anyhow) for less verbosity.
|
|
130
|
-
|
|
131
|
-
# The Rust "SDK"
|
|
132
|
-
|
|
133
|
-
This repo contains a *prototype* Rust sdk in the `sdk/` directory. This SDK should be considered
|
|
134
|
-
pre-alpha in terms of its API surface. Since it's still using Core underneath, it is generally
|
|
135
|
-
functional. We do not currently have any firm plans to productionize this SDK. If you want to write
|
|
136
|
-
workflows and activities in Rust, feel free to use it - but be aware that the API may change at any
|
|
137
|
-
time without warning and we do not provide any support guarantees.
|
|
@@ -9,9 +9,11 @@ homepage = "https://temporal.io/"
|
|
|
9
9
|
repository = "https://github.com/temporalio/sdk-core"
|
|
10
10
|
keywords = ["temporal", "workflow"]
|
|
11
11
|
categories = ["development-tools"]
|
|
12
|
+
readme = "README.md"
|
|
12
13
|
|
|
13
14
|
[features]
|
|
14
15
|
telemetry = ["dep:opentelemetry"]
|
|
16
|
+
core-based-sdk = []
|
|
15
17
|
|
|
16
18
|
[dependencies]
|
|
17
19
|
anyhow = "1.0"
|
|
@@ -42,10 +44,12 @@ rand = "0.9.2"
|
|
|
42
44
|
|
|
43
45
|
[dependencies.temporalio-common]
|
|
44
46
|
path = "../common"
|
|
47
|
+
version = "0.1"
|
|
45
48
|
|
|
46
49
|
[dev-dependencies]
|
|
47
50
|
assert_matches = "1"
|
|
48
51
|
mockall = "0.13"
|
|
52
|
+
prost = "0.14"
|
|
49
53
|
rstest = "0.26"
|
|
50
54
|
|
|
51
55
|
[lints]
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Temporal Rust Client
|
|
2
|
+
|
|
3
|
+
[](https://crates.io/crates/temporalio-client)
|
|
4
|
+
[](https://docs.rs/temporalio-client)
|
|
5
|
+
|
|
6
|
+
This crate provides a Rust client for interacting with the Temporal service. It can be used
|
|
7
|
+
standalone to start and manage workflows, or together with the
|
|
8
|
+
[`temporalio-sdk`](https://crates.io/crates/temporalio-sdk) crate to run workers.
|
|
9
|
+
|
|
10
|
+
⚠️ **This crate is under active development and should be considered prerelease.** The API can and
|
|
11
|
+
will continue to evolve.
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
### Connecting and Starting Workflows
|
|
16
|
+
|
|
17
|
+
```rust
|
|
18
|
+
use temporalio_client::{
|
|
19
|
+
Client, ClientOptions, Connection, ConnectionOptions,
|
|
20
|
+
WorkflowOptions, GetWorkflowResultOptions,
|
|
21
|
+
};
|
|
22
|
+
use temporalio_sdk_core::{Url, CoreRuntime, RuntimeOptions};
|
|
23
|
+
use std::str::FromStr;
|
|
24
|
+
|
|
25
|
+
#[tokio::main]
|
|
26
|
+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
27
|
+
let connection = Connection::connect(
|
|
28
|
+
ConnectionOptions::new(Url::from_str("http://localhost:7233")?)
|
|
29
|
+
.identity("my-client".to_string())
|
|
30
|
+
.build()
|
|
31
|
+
).await?;
|
|
32
|
+
|
|
33
|
+
// "default" is your namespace
|
|
34
|
+
let client = Client::new(connection, ClientOptions::new("default").build());
|
|
35
|
+
|
|
36
|
+
// Start a workflow
|
|
37
|
+
let handle = client.start_workflow(
|
|
38
|
+
GreetingWorkflow::run,
|
|
39
|
+
"World".to_string(),
|
|
40
|
+
WorkflowOptions::new("my-task-queue", "greeting-workflow-1").build()
|
|
41
|
+
).await?;
|
|
42
|
+
|
|
43
|
+
// Wait for the result
|
|
44
|
+
let result = handle.get_result(GetWorkflowResultOptions::default()).await?;
|
|
45
|
+
|
|
46
|
+
Ok(())
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Signals, Queries, and Updates
|
|
51
|
+
|
|
52
|
+
Once you have a workflow handle, you can interact with the running workflow:
|
|
53
|
+
|
|
54
|
+
```rust
|
|
55
|
+
use temporalio_client::{
|
|
56
|
+
SignalOptions, QueryOptions, UpdateOptions,
|
|
57
|
+
StartUpdateOptions, WorkflowUpdateWaitStage,
|
|
58
|
+
UntypedSignal,
|
|
59
|
+
};
|
|
60
|
+
use temporalio_common::data_converters::{PayloadConverter, RawValue};
|
|
61
|
+
|
|
62
|
+
// Get a handle to an existing workflow (or use one from start_workflow)
|
|
63
|
+
let handle = client.get_workflow_handle::<MyWorkflow>("workflow-id");
|
|
64
|
+
|
|
65
|
+
// --- Signals (fire-and-forget messages) ---
|
|
66
|
+
handle.signal(MyWorkflow::push_value, 42, SignalOptions::default()).await?;
|
|
67
|
+
|
|
68
|
+
// --- Queries (read workflow state) ---
|
|
69
|
+
let values = handle
|
|
70
|
+
.query(MyWorkflow::get_values, (), QueryOptions::default())
|
|
71
|
+
.await?;
|
|
72
|
+
|
|
73
|
+
// --- Updates (modify state and get a result) ---
|
|
74
|
+
let values = handle
|
|
75
|
+
.execute_update(MyWorkflow::add_wait_return, 100, UpdateOptions::default())
|
|
76
|
+
.await?;
|
|
77
|
+
|
|
78
|
+
// Start an update and wait for acceptance only
|
|
79
|
+
let update_handle = handle
|
|
80
|
+
.start_update(
|
|
81
|
+
MyWorkflow::add_wait_return,
|
|
82
|
+
50,
|
|
83
|
+
StartUpdateOptions::builder()
|
|
84
|
+
.wait_for_stage(WorkflowUpdateWaitStage::Accepted)
|
|
85
|
+
.build()
|
|
86
|
+
)
|
|
87
|
+
.await?;
|
|
88
|
+
update_handle.get_result().await?;
|
|
89
|
+
|
|
90
|
+
// --- Untyped interactions (when types aren't known at compile time) ---
|
|
91
|
+
let pc = PayloadConverter::serde_json();
|
|
92
|
+
handle
|
|
93
|
+
.signal(
|
|
94
|
+
UntypedSignal::new("increment"),
|
|
95
|
+
RawValue::from_value(&25i32, &pc),
|
|
96
|
+
SignalOptions::default(),
|
|
97
|
+
)
|
|
98
|
+
.await?;
|
|
99
|
+
// UntypedQuery and UntypedUpdate work similarly
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Cancelling and Terminating Workflows
|
|
103
|
+
|
|
104
|
+
```rust
|
|
105
|
+
use temporalio_client::{CancelWorkflowOptions, TerminateWorkflowOptions};
|
|
106
|
+
|
|
107
|
+
// Request cancellation (workflow can handle this gracefully)
|
|
108
|
+
handle.cancel(CancelWorkflowOptions::builder().reason("No longer needed").build()).await?;
|
|
109
|
+
|
|
110
|
+
// Terminate immediately (workflow cannot intercept this)
|
|
111
|
+
handle.terminate(TerminateWorkflowOptions::builder().reason("Emergency shutdown").build()).await?;
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Listing Workflows
|
|
115
|
+
|
|
116
|
+
```rust
|
|
117
|
+
use temporalio_client::ListWorkflowsOptions;
|
|
118
|
+
use futures_util::StreamExt;
|
|
119
|
+
|
|
120
|
+
let mut stream = client.list_workflows(
|
|
121
|
+
"WorkflowType = 'GreetingWorkflow'",
|
|
122
|
+
ListWorkflowsOptions::builder().limit(10).build()
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
while let Some(result) = stream.next().await {
|
|
126
|
+
let execution = result?;
|
|
127
|
+
println!("Workflow: {} ({})", execution.id(), execution.workflow_type());
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Raw gRPC Access
|
|
132
|
+
|
|
133
|
+
For operations not covered by the high-level API, access the underlying gRPC service clients
|
|
134
|
+
directly:
|
|
135
|
+
|
|
136
|
+
```rust
|
|
137
|
+
let mut workflowf_service = client.connection().workflow_service();
|
|
138
|
+
let mut operator_service = client.connection().operator_service();
|
|
139
|
+
```
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
//! Handle for completing activities asynchronously via a client.
|
|
2
|
+
|
|
3
|
+
use crate::{NamespacedClient, errors::AsyncActivityError, grpc::WorkflowService};
|
|
4
|
+
use temporalio_common::protos::{
|
|
5
|
+
TaskToken,
|
|
6
|
+
temporal::api::{
|
|
7
|
+
common::v1::Payloads,
|
|
8
|
+
failure::v1::Failure,
|
|
9
|
+
workflowservice::v1::{
|
|
10
|
+
RecordActivityTaskHeartbeatByIdRequest, RecordActivityTaskHeartbeatByIdResponse,
|
|
11
|
+
RecordActivityTaskHeartbeatRequest, RecordActivityTaskHeartbeatResponse,
|
|
12
|
+
RespondActivityTaskCanceledByIdRequest, RespondActivityTaskCanceledRequest,
|
|
13
|
+
RespondActivityTaskCompletedByIdRequest, RespondActivityTaskCompletedRequest,
|
|
14
|
+
RespondActivityTaskFailedByIdRequest, RespondActivityTaskFailedRequest,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
use tonic::IntoRequest;
|
|
19
|
+
|
|
20
|
+
/// Identifies an async activity for completion outside a worker.
|
|
21
|
+
#[derive(Debug, Clone)]
|
|
22
|
+
pub enum ActivityIdentifier {
|
|
23
|
+
/// Identify activity by its task token
|
|
24
|
+
TaskToken(TaskToken),
|
|
25
|
+
/// Identify activity by workflow and activity IDs.
|
|
26
|
+
ById {
|
|
27
|
+
/// ID of the workflow that scheduled this activity.
|
|
28
|
+
workflow_id: String,
|
|
29
|
+
/// Run ID of the workflow (optional - if not provided, targets the latest run).
|
|
30
|
+
run_id: String,
|
|
31
|
+
/// ID of the activity to complete.
|
|
32
|
+
activity_id: String,
|
|
33
|
+
},
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
impl ActivityIdentifier {
|
|
37
|
+
/// Create an identifier from a task token.
|
|
38
|
+
pub fn from_task_token(token: TaskToken) -> Self {
|
|
39
|
+
Self::TaskToken(token)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/// Create an identifier from workflow and activity IDs. Use an empty run id to target the
|
|
43
|
+
/// latest workflow execution.
|
|
44
|
+
pub fn by_id(
|
|
45
|
+
workflow_id: impl Into<String>,
|
|
46
|
+
run_id: impl Into<String>,
|
|
47
|
+
activity_id: impl Into<String>,
|
|
48
|
+
) -> Self {
|
|
49
|
+
Self::ById {
|
|
50
|
+
workflow_id: workflow_id.into(),
|
|
51
|
+
run_id: run_id.into(),
|
|
52
|
+
activity_id: activity_id.into(),
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/// Handle for completing activities asynchronously (outside the worker).
|
|
58
|
+
pub struct AsyncActivityHandle<CT> {
|
|
59
|
+
client: CT,
|
|
60
|
+
identifier: ActivityIdentifier,
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
impl<CT> AsyncActivityHandle<CT> {
|
|
64
|
+
/// Create a new async activity handle.
|
|
65
|
+
pub fn new(client: CT, identifier: ActivityIdentifier) -> Self {
|
|
66
|
+
Self { client, identifier }
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/// Get the identifier for this activity.
|
|
70
|
+
pub fn identifier(&self) -> &ActivityIdentifier {
|
|
71
|
+
&self.identifier
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/// Get a reference to the underlying client.
|
|
75
|
+
pub fn client(&self) -> &CT {
|
|
76
|
+
&self.client
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
impl<CT: WorkflowService + NamespacedClient + Clone> AsyncActivityHandle<CT> {
|
|
81
|
+
/// Complete the activity with a successful result.
|
|
82
|
+
pub async fn complete(&self, result: Option<Payloads>) -> Result<(), AsyncActivityError> {
|
|
83
|
+
match &self.identifier {
|
|
84
|
+
ActivityIdentifier::TaskToken(token) => {
|
|
85
|
+
WorkflowService::respond_activity_task_completed(
|
|
86
|
+
&mut self.client.clone(),
|
|
87
|
+
RespondActivityTaskCompletedRequest {
|
|
88
|
+
task_token: token.0.clone(),
|
|
89
|
+
result,
|
|
90
|
+
identity: self.client.identity(),
|
|
91
|
+
namespace: self.client.namespace(),
|
|
92
|
+
..Default::default()
|
|
93
|
+
}
|
|
94
|
+
.into_request(),
|
|
95
|
+
)
|
|
96
|
+
.await
|
|
97
|
+
.map_err(AsyncActivityError::from_status)?;
|
|
98
|
+
}
|
|
99
|
+
ActivityIdentifier::ById {
|
|
100
|
+
workflow_id,
|
|
101
|
+
run_id,
|
|
102
|
+
activity_id,
|
|
103
|
+
} => {
|
|
104
|
+
WorkflowService::respond_activity_task_completed_by_id(
|
|
105
|
+
&mut self.client.clone(),
|
|
106
|
+
RespondActivityTaskCompletedByIdRequest {
|
|
107
|
+
namespace: self.client.namespace(),
|
|
108
|
+
workflow_id: workflow_id.clone(),
|
|
109
|
+
run_id: run_id.clone(),
|
|
110
|
+
activity_id: activity_id.clone(),
|
|
111
|
+
result,
|
|
112
|
+
identity: self.client.identity(),
|
|
113
|
+
}
|
|
114
|
+
.into_request(),
|
|
115
|
+
)
|
|
116
|
+
.await
|
|
117
|
+
.map_err(AsyncActivityError::from_status)?;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
Ok(())
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/// Fail the activity with a failure.
|
|
124
|
+
pub async fn fail(
|
|
125
|
+
&self,
|
|
126
|
+
failure: Failure,
|
|
127
|
+
last_heartbeat_details: Option<Payloads>,
|
|
128
|
+
) -> Result<(), AsyncActivityError> {
|
|
129
|
+
match &self.identifier {
|
|
130
|
+
ActivityIdentifier::TaskToken(token) => {
|
|
131
|
+
WorkflowService::respond_activity_task_failed(
|
|
132
|
+
&mut self.client.clone(),
|
|
133
|
+
RespondActivityTaskFailedRequest {
|
|
134
|
+
task_token: token.0.clone(),
|
|
135
|
+
failure: Some(failure),
|
|
136
|
+
identity: self.client.identity(),
|
|
137
|
+
namespace: self.client.namespace(),
|
|
138
|
+
last_heartbeat_details,
|
|
139
|
+
..Default::default()
|
|
140
|
+
}
|
|
141
|
+
.into_request(),
|
|
142
|
+
)
|
|
143
|
+
.await
|
|
144
|
+
.map_err(AsyncActivityError::from_status)?;
|
|
145
|
+
}
|
|
146
|
+
ActivityIdentifier::ById {
|
|
147
|
+
workflow_id,
|
|
148
|
+
run_id,
|
|
149
|
+
activity_id,
|
|
150
|
+
} => {
|
|
151
|
+
WorkflowService::respond_activity_task_failed_by_id(
|
|
152
|
+
&mut self.client.clone(),
|
|
153
|
+
RespondActivityTaskFailedByIdRequest {
|
|
154
|
+
namespace: self.client.namespace(),
|
|
155
|
+
workflow_id: workflow_id.clone(),
|
|
156
|
+
run_id: run_id.clone(),
|
|
157
|
+
activity_id: activity_id.clone(),
|
|
158
|
+
failure: Some(failure),
|
|
159
|
+
identity: self.client.identity(),
|
|
160
|
+
last_heartbeat_details,
|
|
161
|
+
}
|
|
162
|
+
.into_request(),
|
|
163
|
+
)
|
|
164
|
+
.await
|
|
165
|
+
.map_err(AsyncActivityError::from_status)?;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
Ok(())
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/// Reports the activity as canceled.
|
|
172
|
+
pub async fn report_cancelation(
|
|
173
|
+
&self,
|
|
174
|
+
details: Option<Payloads>,
|
|
175
|
+
) -> Result<(), AsyncActivityError> {
|
|
176
|
+
match &self.identifier {
|
|
177
|
+
ActivityIdentifier::TaskToken(token) => {
|
|
178
|
+
WorkflowService::respond_activity_task_canceled(
|
|
179
|
+
&mut self.client.clone(),
|
|
180
|
+
RespondActivityTaskCanceledRequest {
|
|
181
|
+
task_token: token.0.clone(),
|
|
182
|
+
details,
|
|
183
|
+
identity: self.client.identity(),
|
|
184
|
+
namespace: self.client.namespace(),
|
|
185
|
+
..Default::default()
|
|
186
|
+
}
|
|
187
|
+
.into_request(),
|
|
188
|
+
)
|
|
189
|
+
.await
|
|
190
|
+
.map_err(AsyncActivityError::from_status)?;
|
|
191
|
+
}
|
|
192
|
+
ActivityIdentifier::ById {
|
|
193
|
+
workflow_id,
|
|
194
|
+
run_id,
|
|
195
|
+
activity_id,
|
|
196
|
+
} => {
|
|
197
|
+
WorkflowService::respond_activity_task_canceled_by_id(
|
|
198
|
+
&mut self.client.clone(),
|
|
199
|
+
RespondActivityTaskCanceledByIdRequest {
|
|
200
|
+
namespace: self.client.namespace(),
|
|
201
|
+
workflow_id: workflow_id.clone(),
|
|
202
|
+
run_id: run_id.clone(),
|
|
203
|
+
activity_id: activity_id.clone(),
|
|
204
|
+
details,
|
|
205
|
+
identity: self.client.identity(),
|
|
206
|
+
..Default::default()
|
|
207
|
+
}
|
|
208
|
+
.into_request(),
|
|
209
|
+
)
|
|
210
|
+
.await
|
|
211
|
+
.map_err(AsyncActivityError::from_status)?;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
Ok(())
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/// Record a heartbeat for the activity.
|
|
218
|
+
///
|
|
219
|
+
/// Heartbeats let the server know the activity is still running and can carry
|
|
220
|
+
/// progress information. The response indicates if cancellation has been requested.
|
|
221
|
+
pub async fn heartbeat(
|
|
222
|
+
&self,
|
|
223
|
+
details: Option<Payloads>,
|
|
224
|
+
) -> Result<ActivityHeartbeatResponse, AsyncActivityError> {
|
|
225
|
+
match &self.identifier {
|
|
226
|
+
ActivityIdentifier::TaskToken(token) => {
|
|
227
|
+
let resp = WorkflowService::record_activity_task_heartbeat(
|
|
228
|
+
&mut self.client.clone(),
|
|
229
|
+
RecordActivityTaskHeartbeatRequest {
|
|
230
|
+
task_token: token.0.clone(),
|
|
231
|
+
details,
|
|
232
|
+
identity: self.client.identity(),
|
|
233
|
+
namespace: self.client.namespace(),
|
|
234
|
+
}
|
|
235
|
+
.into_request(),
|
|
236
|
+
)
|
|
237
|
+
.await
|
|
238
|
+
.map_err(AsyncActivityError::from_status)?
|
|
239
|
+
.into_inner();
|
|
240
|
+
Ok(ActivityHeartbeatResponse::from(resp))
|
|
241
|
+
}
|
|
242
|
+
ActivityIdentifier::ById {
|
|
243
|
+
workflow_id,
|
|
244
|
+
run_id,
|
|
245
|
+
activity_id,
|
|
246
|
+
} => {
|
|
247
|
+
let resp = WorkflowService::record_activity_task_heartbeat_by_id(
|
|
248
|
+
&mut self.client.clone(),
|
|
249
|
+
RecordActivityTaskHeartbeatByIdRequest {
|
|
250
|
+
namespace: self.client.namespace(),
|
|
251
|
+
workflow_id: workflow_id.clone(),
|
|
252
|
+
run_id: run_id.clone(),
|
|
253
|
+
activity_id: activity_id.clone(),
|
|
254
|
+
details,
|
|
255
|
+
identity: self.client.identity(),
|
|
256
|
+
}
|
|
257
|
+
.into_request(),
|
|
258
|
+
)
|
|
259
|
+
.await
|
|
260
|
+
.map_err(AsyncActivityError::from_status)?
|
|
261
|
+
.into_inner();
|
|
262
|
+
Ok(ActivityHeartbeatResponse::from(resp))
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/// Response from a heartbeat call.
|
|
269
|
+
#[derive(Debug, Clone)]
|
|
270
|
+
pub struct ActivityHeartbeatResponse {
|
|
271
|
+
/// True if the activity has been asked to cancel itself.
|
|
272
|
+
pub cancel_requested: bool,
|
|
273
|
+
/// True if the activity is paused.
|
|
274
|
+
pub activity_paused: bool,
|
|
275
|
+
/// True if the activity was reset.
|
|
276
|
+
pub activity_reset: bool,
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
impl From<RecordActivityTaskHeartbeatResponse> for ActivityHeartbeatResponse {
|
|
280
|
+
fn from(resp: RecordActivityTaskHeartbeatResponse) -> Self {
|
|
281
|
+
Self {
|
|
282
|
+
cancel_requested: resp.cancel_requested,
|
|
283
|
+
activity_paused: resp.activity_paused,
|
|
284
|
+
activity_reset: resp.activity_reset,
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
impl From<RecordActivityTaskHeartbeatByIdResponse> for ActivityHeartbeatResponse {
|
|
290
|
+
fn from(resp: RecordActivityTaskHeartbeatByIdResponse) -> Self {
|
|
291
|
+
Self {
|
|
292
|
+
cancel_requested: resp.cancel_requested,
|
|
293
|
+
activity_paused: resp.activity_paused,
|
|
294
|
+
activity_reset: resp.activity_reset,
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
@@ -15,6 +15,7 @@ use tonic::{Status, metadata::GRPC_CONTENT_TYPE};
|
|
|
15
15
|
use tower::Service;
|
|
16
16
|
|
|
17
17
|
/// gRPC request for use by a callback.
|
|
18
|
+
#[derive(Debug)]
|
|
18
19
|
pub struct GrpcRequest {
|
|
19
20
|
/// Fully qualified gRPC service name.
|
|
20
21
|
pub service: String,
|
|
@@ -27,6 +28,7 @@ pub struct GrpcRequest {
|
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
/// Successful gRPC response returned by a callback.
|
|
31
|
+
#[derive(Debug)]
|
|
30
32
|
pub struct GrpcSuccessResponse {
|
|
31
33
|
/// Response headers.
|
|
32
34
|
pub headers: HeaderMap,
|
|
@@ -46,6 +48,11 @@ pub struct CallbackBasedGrpcService {
|
|
|
46
48
|
+ Sync,
|
|
47
49
|
>,
|
|
48
50
|
}
|
|
51
|
+
impl std::fmt::Debug for CallbackBasedGrpcService {
|
|
52
|
+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
53
|
+
f.debug_struct("CallbackBasedGrpcService").finish()
|
|
54
|
+
}
|
|
55
|
+
}
|
|
49
56
|
|
|
50
57
|
impl Service<Request<tonic::body::Body>> for CallbackBasedGrpcService {
|
|
51
58
|
type Response = http::Response<tonic::body::Body>;
|