@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.
Files changed (209) hide show
  1. package/Cargo.lock +172 -70
  2. package/lib/native.d.ts +1 -1
  3. package/package.json +2 -2
  4. package/releases/aarch64-apple-darwin/index.node +0 -0
  5. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  6. package/releases/x86_64-apple-darwin/index.node +0 -0
  7. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  8. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  9. package/sdk-core/.github/workflows/per-pr.yml +6 -6
  10. package/sdk-core/AGENTS.md +41 -30
  11. package/sdk-core/Cargo.toml +3 -0
  12. package/sdk-core/README.md +15 -9
  13. package/sdk-core/crates/client/Cargo.toml +4 -0
  14. package/sdk-core/crates/client/README.md +139 -0
  15. package/sdk-core/crates/client/src/async_activity_handle.rs +297 -0
  16. package/sdk-core/crates/client/src/callback_based.rs +7 -0
  17. package/sdk-core/crates/client/src/errors.rs +294 -0
  18. package/sdk-core/crates/client/src/{raw.rs → grpc.rs} +280 -159
  19. package/sdk-core/crates/client/src/lib.rs +920 -1326
  20. package/sdk-core/crates/client/src/metrics.rs +24 -33
  21. package/sdk-core/crates/client/src/options_structs.rs +457 -0
  22. package/sdk-core/crates/client/src/replaceable.rs +5 -4
  23. package/sdk-core/crates/client/src/request_extensions.rs +8 -9
  24. package/sdk-core/crates/client/src/retry.rs +99 -54
  25. package/sdk-core/crates/client/src/{worker/mod.rs → worker.rs} +1 -1
  26. package/sdk-core/crates/client/src/workflow_handle.rs +826 -0
  27. package/sdk-core/crates/common/Cargo.toml +61 -2
  28. package/sdk-core/crates/common/build.rs +742 -12
  29. package/sdk-core/crates/common/protos/api_upstream/.github/workflows/ci.yml +2 -0
  30. package/sdk-core/crates/common/protos/api_upstream/Makefile +2 -1
  31. package/sdk-core/crates/common/protos/api_upstream/buf.yaml +0 -3
  32. package/sdk-core/crates/common/protos/api_upstream/cmd/check-path-conflicts/main.go +137 -0
  33. package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv2.json +1166 -770
  34. package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv3.yaml +1243 -750
  35. package/sdk-core/crates/common/protos/api_upstream/temporal/api/deployment/v1/message.proto +2 -2
  36. package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/workflow.proto +4 -3
  37. package/sdk-core/crates/common/protos/api_upstream/temporal/api/failure/v1/message.proto +1 -0
  38. package/sdk-core/crates/common/protos/api_upstream/temporal/api/history/v1/message.proto +4 -0
  39. package/sdk-core/crates/common/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -0
  40. package/sdk-core/crates/common/protos/api_upstream/temporal/api/nexus/v1/message.proto +16 -1
  41. package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +64 -6
  42. package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +88 -33
  43. package/sdk-core/crates/common/protos/local/temporal/sdk/core/nexus/nexus.proto +4 -2
  44. package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +4 -0
  45. package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +5 -5
  46. package/sdk-core/crates/common/src/activity_definition.rs +20 -0
  47. package/sdk-core/crates/common/src/data_converters.rs +770 -0
  48. package/sdk-core/crates/common/src/envconfig.rs +5 -0
  49. package/sdk-core/crates/common/src/lib.rs +15 -211
  50. package/sdk-core/crates/common/src/payload_visitor.rs +648 -0
  51. package/sdk-core/crates/common/src/priority.rs +110 -0
  52. package/sdk-core/crates/common/src/protos/canned_histories.rs +3 -0
  53. package/sdk-core/crates/common/src/protos/history_builder.rs +45 -0
  54. package/sdk-core/crates/common/src/protos/history_info.rs +2 -0
  55. package/sdk-core/crates/common/src/protos/mod.rs +122 -27
  56. package/sdk-core/crates/common/src/protos/task_token.rs +3 -3
  57. package/sdk-core/crates/common/src/protos/utilities.rs +11 -0
  58. package/sdk-core/crates/{sdk-core → common}/src/telemetry/log_export.rs +5 -7
  59. package/sdk-core/crates/common/src/telemetry/metrics/core.rs +125 -0
  60. package/sdk-core/crates/common/src/telemetry/metrics.rs +268 -223
  61. package/sdk-core/crates/{sdk-core → common}/src/telemetry/otel.rs +8 -13
  62. package/sdk-core/crates/{sdk-core → common}/src/telemetry/prometheus_meter.rs +49 -50
  63. package/sdk-core/crates/{sdk-core → common}/src/telemetry/prometheus_server.rs +2 -3
  64. package/sdk-core/crates/common/src/telemetry.rs +264 -4
  65. package/sdk-core/crates/common/src/worker.rs +68 -603
  66. package/sdk-core/crates/common/src/workflow_definition.rs +60 -0
  67. package/sdk-core/crates/macros/Cargo.toml +5 -1
  68. package/sdk-core/crates/macros/src/activities_definitions.rs +585 -0
  69. package/sdk-core/crates/macros/src/fsm_impl.rs +507 -0
  70. package/sdk-core/crates/macros/src/lib.rs +138 -512
  71. package/sdk-core/crates/macros/src/macro_utils.rs +106 -0
  72. package/sdk-core/crates/macros/src/workflow_definitions.rs +1224 -0
  73. package/sdk-core/crates/sdk/Cargo.toml +19 -6
  74. package/sdk-core/crates/sdk/README.md +415 -0
  75. package/sdk-core/crates/sdk/src/activities.rs +417 -0
  76. package/sdk-core/crates/sdk/src/interceptors.rs +1 -1
  77. package/sdk-core/crates/sdk/src/lib.rs +757 -442
  78. package/sdk-core/crates/sdk/src/workflow_context/options.rs +45 -35
  79. package/sdk-core/crates/sdk/src/workflow_context.rs +1033 -289
  80. package/sdk-core/crates/sdk/src/workflow_future.rs +277 -213
  81. package/sdk-core/crates/sdk/src/workflows.rs +711 -0
  82. package/sdk-core/crates/sdk-core/Cargo.toml +57 -64
  83. package/sdk-core/crates/sdk-core/benches/workflow_replay_bench.rs +41 -35
  84. package/sdk-core/crates/sdk-core/machine_coverage/ActivityMachine_Coverage.puml +1 -1
  85. package/sdk-core/crates/sdk-core/src/abstractions.rs +6 -10
  86. package/sdk-core/crates/sdk-core/src/core_tests/activity_tasks.rs +6 -5
  87. package/sdk-core/crates/sdk-core/src/core_tests/mod.rs +13 -15
  88. package/sdk-core/crates/sdk-core/src/core_tests/queries.rs +21 -25
  89. package/sdk-core/crates/sdk-core/src/core_tests/replay_flag.rs +7 -10
  90. package/sdk-core/crates/sdk-core/src/core_tests/updates.rs +14 -17
  91. package/sdk-core/crates/sdk-core/src/core_tests/workers.rs +493 -26
  92. package/sdk-core/crates/sdk-core/src/core_tests/workflow_tasks.rs +4 -8
  93. package/sdk-core/crates/sdk-core/src/ephemeral_server/mod.rs +7 -7
  94. package/sdk-core/crates/sdk-core/src/histfetch.rs +20 -10
  95. package/sdk-core/crates/sdk-core/src/lib.rs +41 -111
  96. package/sdk-core/crates/sdk-core/src/pollers/mod.rs +4 -9
  97. package/sdk-core/crates/sdk-core/src/pollers/poll_buffer.rs +118 -19
  98. package/sdk-core/crates/sdk-core/src/protosext/mod.rs +2 -2
  99. package/sdk-core/crates/sdk-core/src/replay/mod.rs +14 -5
  100. package/sdk-core/crates/sdk-core/src/telemetry/metrics.rs +179 -196
  101. package/sdk-core/crates/sdk-core/src/telemetry/mod.rs +3 -280
  102. package/sdk-core/crates/sdk-core/src/test_help/integ_helpers.rs +6 -9
  103. package/sdk-core/crates/sdk-core/src/test_help/unit_helpers.rs +3 -6
  104. package/sdk-core/crates/sdk-core/src/worker/activities/local_activities.rs +11 -14
  105. package/sdk-core/crates/sdk-core/src/worker/activities.rs +16 -19
  106. package/sdk-core/crates/sdk-core/src/worker/client/mocks.rs +9 -5
  107. package/sdk-core/crates/sdk-core/src/worker/client.rs +103 -81
  108. package/sdk-core/crates/sdk-core/src/worker/heartbeat.rs +7 -11
  109. package/sdk-core/crates/sdk-core/src/worker/mod.rs +1124 -229
  110. package/sdk-core/crates/sdk-core/src/worker/nexus.rs +145 -23
  111. package/sdk-core/crates/sdk-core/src/worker/slot_provider.rs +2 -2
  112. package/sdk-core/crates/sdk-core/src/worker/tuner/fixed_size.rs +2 -2
  113. package/sdk-core/crates/sdk-core/src/worker/tuner/resource_based.rs +13 -13
  114. package/sdk-core/crates/sdk-core/src/worker/tuner.rs +28 -8
  115. package/sdk-core/crates/sdk-core/src/worker/workflow/driven_workflow.rs +9 -3
  116. package/sdk-core/crates/sdk-core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +21 -22
  117. package/sdk-core/crates/sdk-core/src/worker/workflow/machines/workflow_machines.rs +19 -4
  118. package/sdk-core/crates/sdk-core/src/worker/workflow/managed_run.rs +14 -18
  119. package/sdk-core/crates/sdk-core/src/worker/workflow/mod.rs +4 -6
  120. package/sdk-core/crates/sdk-core/src/worker/workflow/run_cache.rs +4 -7
  121. package/sdk-core/crates/sdk-core/src/worker/workflow/wft_extraction.rs +2 -4
  122. package/sdk-core/crates/sdk-core/src/worker/workflow/wft_poller.rs +8 -9
  123. package/sdk-core/crates/sdk-core/src/worker/workflow/workflow_stream.rs +1 -3
  124. package/sdk-core/crates/sdk-core/tests/activities_procmacro.rs +6 -0
  125. package/sdk-core/crates/sdk-core/tests/activities_trybuild/basic_pass.rs +54 -0
  126. package/sdk-core/crates/sdk-core/tests/activities_trybuild/invalid_self_type_fail.rs +18 -0
  127. package/sdk-core/crates/sdk-core/tests/activities_trybuild/invalid_self_type_fail.stderr +5 -0
  128. package/sdk-core/crates/sdk-core/tests/activities_trybuild/missing_context_fail.rs +14 -0
  129. package/sdk-core/crates/sdk-core/tests/activities_trybuild/missing_context_fail.stderr +5 -0
  130. package/sdk-core/crates/sdk-core/tests/activities_trybuild/multi_arg_pass.rs +48 -0
  131. package/sdk-core/crates/sdk-core/tests/activities_trybuild/no_input_pass.rs +14 -0
  132. package/sdk-core/crates/sdk-core/tests/activities_trybuild/no_return_type_pass.rs +19 -0
  133. package/sdk-core/crates/sdk-core/tests/cloud_tests.rs +14 -5
  134. package/sdk-core/crates/sdk-core/tests/common/activity_functions.rs +55 -0
  135. package/sdk-core/crates/sdk-core/tests/common/mod.rs +241 -196
  136. package/sdk-core/crates/sdk-core/tests/common/workflows.rs +41 -28
  137. package/sdk-core/crates/sdk-core/tests/global_metric_tests.rs +3 -5
  138. package/sdk-core/crates/sdk-core/tests/heavy_tests/fuzzy_workflow.rs +73 -64
  139. package/sdk-core/crates/sdk-core/tests/heavy_tests.rs +298 -252
  140. package/sdk-core/crates/sdk-core/tests/integ_tests/async_activity_client_tests.rs +230 -0
  141. package/sdk-core/crates/sdk-core/tests/integ_tests/client_tests.rs +94 -57
  142. package/sdk-core/crates/sdk-core/tests/integ_tests/data_converter_tests.rs +381 -0
  143. package/sdk-core/crates/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +16 -12
  144. package/sdk-core/crates/sdk-core/tests/integ_tests/heartbeat_tests.rs +48 -40
  145. package/sdk-core/crates/sdk-core/tests/integ_tests/metrics_tests.rs +327 -255
  146. package/sdk-core/crates/sdk-core/tests/integ_tests/pagination_tests.rs +50 -45
  147. package/sdk-core/crates/sdk-core/tests/integ_tests/polling_tests.rs +147 -126
  148. package/sdk-core/crates/sdk-core/tests/integ_tests/queries_tests.rs +103 -89
  149. package/sdk-core/crates/sdk-core/tests/integ_tests/update_tests.rs +609 -453
  150. package/sdk-core/crates/sdk-core/tests/integ_tests/visibility_tests.rs +80 -62
  151. package/sdk-core/crates/sdk-core/tests/integ_tests/worker_heartbeat_tests.rs +360 -231
  152. package/sdk-core/crates/sdk-core/tests/integ_tests/worker_tests.rs +248 -185
  153. package/sdk-core/crates/sdk-core/tests/integ_tests/worker_versioning_tests.rs +52 -43
  154. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_client_tests.rs +180 -0
  155. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/activities.rs +428 -315
  156. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +82 -56
  157. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +56 -28
  158. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +364 -243
  159. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/client_interactions.rs +552 -0
  160. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +101 -42
  161. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +243 -147
  162. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/eager.rs +98 -28
  163. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +1475 -1036
  164. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +73 -41
  165. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +397 -238
  166. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/patches.rs +414 -189
  167. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/queries.rs +415 -0
  168. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/replay.rs +96 -36
  169. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/resets.rs +154 -137
  170. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/signals.rs +183 -105
  171. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +85 -38
  172. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/timers.rs +142 -40
  173. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +73 -54
  174. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests.rs +363 -226
  175. package/sdk-core/crates/sdk-core/tests/main.rs +17 -15
  176. package/sdk-core/crates/sdk-core/tests/manual_tests.rs +207 -152
  177. package/sdk-core/crates/sdk-core/tests/shared_tests/mod.rs +65 -34
  178. package/sdk-core/crates/sdk-core/tests/shared_tests/priority.rs +107 -84
  179. package/sdk-core/crates/sdk-core/tests/workflows_procmacro.rs +6 -0
  180. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/async_query_fail.rs +26 -0
  181. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/async_query_fail.stderr +5 -0
  182. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/basic_pass.rs +49 -0
  183. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/minimal_pass.rs +21 -0
  184. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/mut_query_fail.rs +26 -0
  185. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/mut_query_fail.stderr +5 -0
  186. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/sync_run_fail.rs +21 -0
  187. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/sync_run_fail.stderr +5 -0
  188. package/sdk-core/crates/sdk-core-c-bridge/Cargo.toml +7 -1
  189. package/sdk-core/crates/sdk-core-c-bridge/include/temporal-sdk-core-c-bridge.h +14 -14
  190. package/sdk-core/crates/sdk-core-c-bridge/src/client.rs +83 -74
  191. package/sdk-core/crates/sdk-core-c-bridge/src/metric.rs +9 -14
  192. package/sdk-core/crates/sdk-core-c-bridge/src/runtime.rs +1 -2
  193. package/sdk-core/crates/sdk-core-c-bridge/src/tests/context.rs +13 -13
  194. package/sdk-core/crates/sdk-core-c-bridge/src/tests/mod.rs +6 -6
  195. package/sdk-core/crates/sdk-core-c-bridge/src/tests/utils.rs +3 -4
  196. package/sdk-core/crates/sdk-core-c-bridge/src/worker.rs +62 -75
  197. package/sdk-core/rustfmt.toml +2 -1
  198. package/src/client.rs +205 -318
  199. package/src/metrics.rs +22 -30
  200. package/src/runtime.rs +4 -5
  201. package/src/worker.rs +16 -19
  202. package/ts/native.ts +1 -1
  203. package/sdk-core/crates/client/src/workflow_handle/mod.rs +0 -212
  204. package/sdk-core/crates/common/src/errors.rs +0 -85
  205. package/sdk-core/crates/common/tests/worker_task_types_test.rs +0 -129
  206. package/sdk-core/crates/sdk/src/activity_context.rs +0 -238
  207. package/sdk-core/crates/sdk/src/app_data.rs +0 -37
  208. package/sdk-core/crates/sdk-core/tests/integ_tests/activity_functions.rs +0 -5
  209. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +0 -61
@@ -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
+ [![crates.io](https://img.shields.io/crates/v/temporalio-sdk.svg)](https://crates.io/crates/temporalio-sdk)
13
+ [![docs.rs](https://docs.rs/temporalio-sdk/badge.svg)](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
+ [![crates.io](https://img.shields.io/crates/v/temporalio-sdk.svg)](https://crates.io/crates/temporalio-client)
20
+ [![docs.rs](https://docs.rs/temporalio-sdk/badge.svg)](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 -Xsubtree=crates/common/protos/api_upstream ssh://git@github.com/temporalio/api.git master --allow-unrelated-histories`
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
+ [![crates.io](https://img.shields.io/crates/v/temporalio-client.svg)](https://crates.io/crates/temporalio-client)
4
+ [![docs.rs](https://docs.rs/temporalio-client/badge.svg)](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>;