@temporalio/core-bridge 1.14.2-canary-release-testing.0 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. package/Cargo.lock +794 -650
  2. package/bridge-macros/src/derive_tryintojs.rs +40 -0
  3. package/lib/native.d.ts +24 -3
  4. package/package.json +4 -4
  5. package/releases/aarch64-apple-darwin/index.node +0 -0
  6. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  7. package/releases/x86_64-apple-darwin/index.node +0 -0
  8. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  9. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  10. package/sdk-core/.github/workflows/per-pr.yml +6 -6
  11. package/sdk-core/AGENTS.md +42 -31
  12. package/sdk-core/Cargo.toml +4 -1
  13. package/sdk-core/README.md +19 -13
  14. package/sdk-core/crates/client/Cargo.toml +4 -0
  15. package/sdk-core/crates/client/README.md +139 -0
  16. package/sdk-core/crates/client/src/async_activity_handle.rs +297 -0
  17. package/sdk-core/crates/client/src/callback_based.rs +7 -0
  18. package/sdk-core/crates/client/src/errors.rs +294 -0
  19. package/sdk-core/crates/client/src/{raw.rs → grpc.rs} +370 -159
  20. package/sdk-core/crates/client/src/lib.rs +920 -1326
  21. package/sdk-core/crates/client/src/metrics.rs +24 -33
  22. package/sdk-core/crates/client/src/options_structs.rs +457 -0
  23. package/sdk-core/crates/client/src/replaceable.rs +5 -4
  24. package/sdk-core/crates/client/src/request_extensions.rs +8 -9
  25. package/sdk-core/crates/client/src/retry.rs +99 -54
  26. package/sdk-core/crates/client/src/{worker/mod.rs → worker.rs} +104 -29
  27. package/sdk-core/crates/client/src/workflow_handle.rs +826 -0
  28. package/sdk-core/crates/common/Cargo.toml +62 -3
  29. package/sdk-core/crates/common/build.rs +742 -12
  30. package/sdk-core/crates/common/protos/api_upstream/.github/workflows/ci.yml +2 -0
  31. package/sdk-core/crates/common/protos/api_upstream/.github/workflows/create-release.yml +0 -5
  32. package/sdk-core/crates/common/protos/api_upstream/Makefile +2 -1
  33. package/sdk-core/crates/common/protos/api_upstream/README.md +8 -0
  34. package/sdk-core/crates/common/protos/api_upstream/cmd/check-path-conflicts/main.go +137 -0
  35. package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv2.json +3329 -2647
  36. package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv3.yaml +2734 -708
  37. package/sdk-core/crates/common/protos/api_upstream/temporal/api/activity/v1/message.proto +155 -3
  38. package/sdk-core/crates/common/protos/api_upstream/temporal/api/command/v1/message.proto +26 -0
  39. package/sdk-core/crates/common/protos/api_upstream/temporal/api/common/v1/message.proto +8 -1
  40. package/sdk-core/crates/common/protos/api_upstream/temporal/api/deployment/v1/message.proto +27 -1
  41. package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/activity.proto +81 -0
  42. package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/event_type.proto +4 -0
  43. package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +4 -0
  44. package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +15 -0
  45. package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/workflow.proto +63 -15
  46. package/sdk-core/crates/common/protos/api_upstream/temporal/api/errordetails/v1/message.proto +8 -0
  47. package/sdk-core/crates/common/protos/api_upstream/temporal/api/failure/v1/message.proto +1 -0
  48. package/sdk-core/crates/common/protos/api_upstream/temporal/api/history/v1/message.proto +111 -17
  49. package/sdk-core/crates/common/protos/api_upstream/temporal/api/namespace/v1/message.proto +21 -0
  50. package/sdk-core/crates/common/protos/api_upstream/temporal/api/nexus/v1/message.proto +20 -1
  51. package/sdk-core/crates/common/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +4 -0
  52. package/sdk-core/crates/common/protos/api_upstream/temporal/api/schedule/v1/message.proto +2 -2
  53. package/sdk-core/crates/common/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +2 -0
  54. package/sdk-core/crates/common/protos/api_upstream/temporal/api/worker/v1/message.proto +4 -7
  55. package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflow/v1/message.proto +80 -22
  56. package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +347 -23
  57. package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +242 -43
  58. package/sdk-core/crates/common/protos/local/temporal/sdk/core/core_interface.proto +15 -0
  59. package/sdk-core/crates/common/protos/local/temporal/sdk/core/nexus/nexus.proto +9 -2
  60. package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +8 -0
  61. package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +22 -5
  62. package/sdk-core/crates/common/src/activity_definition.rs +20 -0
  63. package/sdk-core/crates/common/src/data_converters.rs +770 -0
  64. package/sdk-core/crates/common/src/envconfig.rs +5 -0
  65. package/sdk-core/crates/common/src/lib.rs +15 -211
  66. package/sdk-core/crates/common/src/payload_visitor.rs +648 -0
  67. package/sdk-core/crates/common/src/priority.rs +110 -0
  68. package/sdk-core/crates/common/src/protos/canned_histories.rs +19 -0
  69. package/sdk-core/crates/common/src/protos/history_builder.rs +45 -0
  70. package/sdk-core/crates/common/src/protos/history_info.rs +2 -0
  71. package/sdk-core/crates/common/src/protos/mod.rs +134 -27
  72. package/sdk-core/crates/common/src/protos/task_token.rs +3 -3
  73. package/sdk-core/crates/common/src/protos/utilities.rs +11 -0
  74. package/sdk-core/crates/{sdk-core → common}/src/telemetry/log_export.rs +11 -16
  75. package/sdk-core/crates/common/src/telemetry/metrics/core.rs +125 -0
  76. package/sdk-core/crates/common/src/telemetry/metrics.rs +272 -225
  77. package/sdk-core/crates/{sdk-core → common}/src/telemetry/otel.rs +8 -13
  78. package/sdk-core/crates/{sdk-core → common}/src/telemetry/prometheus_meter.rs +49 -50
  79. package/sdk-core/crates/{sdk-core → common}/src/telemetry/prometheus_server.rs +2 -3
  80. package/sdk-core/crates/common/src/telemetry.rs +278 -19
  81. package/sdk-core/crates/common/src/worker.rs +68 -636
  82. package/sdk-core/crates/common/src/workflow_definition.rs +60 -0
  83. package/sdk-core/crates/macros/Cargo.toml +5 -1
  84. package/sdk-core/crates/macros/src/activities_definitions.rs +585 -0
  85. package/sdk-core/crates/macros/src/fsm_impl.rs +507 -0
  86. package/sdk-core/crates/macros/src/lib.rs +138 -512
  87. package/sdk-core/crates/macros/src/macro_utils.rs +106 -0
  88. package/sdk-core/crates/macros/src/workflow_definitions.rs +1224 -0
  89. package/sdk-core/crates/sdk/Cargo.toml +19 -6
  90. package/sdk-core/crates/sdk/README.md +415 -0
  91. package/sdk-core/crates/sdk/src/activities.rs +417 -0
  92. package/sdk-core/crates/sdk/src/interceptors.rs +1 -1
  93. package/sdk-core/crates/sdk/src/lib.rs +759 -442
  94. package/sdk-core/crates/sdk/src/workflow_context/options.rs +64 -35
  95. package/sdk-core/crates/sdk/src/workflow_context.rs +1033 -289
  96. package/sdk-core/crates/sdk/src/workflow_future.rs +277 -213
  97. package/sdk-core/crates/sdk/src/workflows.rs +711 -0
  98. package/sdk-core/crates/sdk-core/Cargo.toml +59 -65
  99. package/sdk-core/crates/sdk-core/benches/workflow_replay_bench.rs +45 -54
  100. package/sdk-core/crates/sdk-core/machine_coverage/ActivityMachine_Coverage.puml +1 -1
  101. package/sdk-core/crates/sdk-core/src/abstractions.rs +6 -10
  102. package/sdk-core/crates/sdk-core/src/core_tests/activity_tasks.rs +6 -5
  103. package/sdk-core/crates/sdk-core/src/core_tests/mod.rs +22 -21
  104. package/sdk-core/crates/sdk-core/src/core_tests/queries.rs +21 -25
  105. package/sdk-core/crates/sdk-core/src/core_tests/replay_flag.rs +7 -10
  106. package/sdk-core/crates/sdk-core/src/core_tests/updates.rs +14 -17
  107. package/sdk-core/crates/sdk-core/src/core_tests/workers.rs +647 -27
  108. package/sdk-core/crates/sdk-core/src/core_tests/workflow_tasks.rs +46 -41
  109. package/sdk-core/crates/sdk-core/src/ephemeral_server/mod.rs +13 -16
  110. package/sdk-core/crates/sdk-core/src/histfetch.rs +20 -10
  111. package/sdk-core/crates/sdk-core/src/lib.rs +60 -123
  112. package/sdk-core/crates/sdk-core/src/pollers/mod.rs +4 -9
  113. package/sdk-core/crates/sdk-core/src/pollers/poll_buffer.rs +411 -32
  114. package/sdk-core/crates/sdk-core/src/protosext/mod.rs +2 -2
  115. package/sdk-core/crates/sdk-core/src/replay/mod.rs +14 -5
  116. package/sdk-core/crates/sdk-core/src/telemetry/metrics.rs +183 -198
  117. package/sdk-core/crates/sdk-core/src/telemetry/mod.rs +3 -281
  118. package/sdk-core/crates/sdk-core/src/test_help/integ_helpers.rs +35 -16
  119. package/sdk-core/crates/sdk-core/src/test_help/unit_helpers.rs +3 -6
  120. package/sdk-core/crates/sdk-core/src/worker/activities/activity_heartbeat_manager.rs +1 -0
  121. package/sdk-core/crates/sdk-core/src/worker/activities/local_activities.rs +11 -14
  122. package/sdk-core/crates/sdk-core/src/worker/activities.rs +16 -19
  123. package/sdk-core/crates/sdk-core/src/worker/client/mocks.rs +11 -5
  124. package/sdk-core/crates/sdk-core/src/worker/client.rs +104 -86
  125. package/sdk-core/crates/sdk-core/src/worker/heartbeat.rs +10 -14
  126. package/sdk-core/crates/sdk-core/src/worker/mod.rs +1175 -241
  127. package/sdk-core/crates/sdk-core/src/worker/nexus.rs +150 -23
  128. package/sdk-core/crates/sdk-core/src/worker/slot_provider.rs +2 -2
  129. package/sdk-core/crates/sdk-core/src/worker/tuner/fixed_size.rs +2 -2
  130. package/sdk-core/crates/sdk-core/src/worker/tuner/resource_based.rs +25 -27
  131. package/sdk-core/crates/sdk-core/src/worker/tuner.rs +64 -44
  132. package/sdk-core/crates/sdk-core/src/worker/workflow/driven_workflow.rs +9 -3
  133. package/sdk-core/crates/sdk-core/src/worker/workflow/machines/patch_state_machine.rs +5 -8
  134. package/sdk-core/crates/sdk-core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +21 -22
  135. package/sdk-core/crates/sdk-core/src/worker/workflow/machines/workflow_machines.rs +28 -4
  136. package/sdk-core/crates/sdk-core/src/worker/workflow/managed_run.rs +20 -41
  137. package/sdk-core/crates/sdk-core/src/worker/workflow/mod.rs +50 -9
  138. package/sdk-core/crates/sdk-core/src/worker/workflow/run_cache.rs +4 -7
  139. package/sdk-core/crates/sdk-core/src/worker/workflow/wft_extraction.rs +2 -4
  140. package/sdk-core/crates/sdk-core/src/worker/workflow/wft_poller.rs +8 -9
  141. package/sdk-core/crates/sdk-core/src/worker/workflow/workflow_stream.rs +1 -3
  142. package/sdk-core/crates/sdk-core/tests/activities_procmacro.rs +6 -0
  143. package/sdk-core/crates/sdk-core/tests/activities_trybuild/basic_pass.rs +54 -0
  144. package/sdk-core/crates/sdk-core/tests/activities_trybuild/invalid_self_type_fail.rs +18 -0
  145. package/sdk-core/crates/sdk-core/tests/activities_trybuild/invalid_self_type_fail.stderr +5 -0
  146. package/sdk-core/crates/sdk-core/tests/activities_trybuild/missing_context_fail.rs +14 -0
  147. package/sdk-core/crates/sdk-core/tests/activities_trybuild/missing_context_fail.stderr +5 -0
  148. package/sdk-core/crates/sdk-core/tests/activities_trybuild/multi_arg_pass.rs +48 -0
  149. package/sdk-core/crates/sdk-core/tests/activities_trybuild/no_input_pass.rs +14 -0
  150. package/sdk-core/crates/sdk-core/tests/activities_trybuild/no_return_type_pass.rs +19 -0
  151. package/sdk-core/crates/sdk-core/tests/cloud_tests.rs +14 -5
  152. package/sdk-core/crates/sdk-core/tests/common/activity_functions.rs +55 -0
  153. package/sdk-core/crates/sdk-core/tests/common/mod.rs +281 -236
  154. package/sdk-core/crates/sdk-core/tests/common/workflows.rs +41 -28
  155. package/sdk-core/crates/sdk-core/tests/global_metric_tests.rs +9 -14
  156. package/sdk-core/crates/sdk-core/tests/heavy_tests/fuzzy_workflow.rs +73 -66
  157. package/sdk-core/crates/sdk-core/tests/heavy_tests.rs +306 -268
  158. package/sdk-core/crates/sdk-core/tests/integ_tests/async_activity_client_tests.rs +230 -0
  159. package/sdk-core/crates/sdk-core/tests/integ_tests/client_tests.rs +94 -57
  160. package/sdk-core/crates/sdk-core/tests/integ_tests/data_converter_tests.rs +381 -0
  161. package/sdk-core/crates/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +37 -38
  162. package/sdk-core/crates/sdk-core/tests/integ_tests/heartbeat_tests.rs +49 -40
  163. package/sdk-core/crates/sdk-core/tests/integ_tests/metrics_tests.rs +447 -300
  164. package/sdk-core/crates/sdk-core/tests/integ_tests/pagination_tests.rs +50 -45
  165. package/sdk-core/crates/sdk-core/tests/integ_tests/polling_tests.rs +157 -157
  166. package/sdk-core/crates/sdk-core/tests/integ_tests/queries_tests.rs +103 -89
  167. package/sdk-core/crates/sdk-core/tests/integ_tests/update_tests.rs +609 -463
  168. package/sdk-core/crates/sdk-core/tests/integ_tests/visibility_tests.rs +80 -62
  169. package/sdk-core/crates/sdk-core/tests/integ_tests/worker_heartbeat_tests.rs +389 -265
  170. package/sdk-core/crates/sdk-core/tests/integ_tests/worker_tests.rs +250 -185
  171. package/sdk-core/crates/sdk-core/tests/integ_tests/worker_versioning_tests.rs +52 -49
  172. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_client_tests.rs +180 -0
  173. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/activities.rs +437 -327
  174. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +82 -58
  175. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +56 -30
  176. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +364 -251
  177. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/client_interactions.rs +552 -0
  178. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +110 -46
  179. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +243 -149
  180. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/eager.rs +98 -32
  181. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +1475 -1040
  182. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +73 -43
  183. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +402 -245
  184. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/patches.rs +343 -207
  185. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/queries.rs +415 -0
  186. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/replay.rs +96 -36
  187. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/resets.rs +155 -140
  188. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/signals.rs +183 -113
  189. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +85 -44
  190. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/timers.rs +142 -48
  191. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +73 -56
  192. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests.rs +365 -242
  193. package/sdk-core/crates/sdk-core/tests/main.rs +22 -16
  194. package/sdk-core/crates/sdk-core/tests/manual_tests.rs +233 -187
  195. package/sdk-core/crates/sdk-core/tests/runner.rs +4 -6
  196. package/sdk-core/crates/sdk-core/tests/shared_tests/mod.rs +73 -27
  197. package/sdk-core/crates/sdk-core/tests/shared_tests/priority.rs +107 -84
  198. package/sdk-core/crates/sdk-core/tests/workflows_procmacro.rs +6 -0
  199. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/async_query_fail.rs +26 -0
  200. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/async_query_fail.stderr +5 -0
  201. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/basic_pass.rs +49 -0
  202. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/minimal_pass.rs +21 -0
  203. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/mut_query_fail.rs +26 -0
  204. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/mut_query_fail.stderr +5 -0
  205. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/sync_run_fail.rs +21 -0
  206. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/sync_run_fail.stderr +5 -0
  207. package/sdk-core/crates/sdk-core-c-bridge/Cargo.toml +8 -1
  208. package/sdk-core/crates/sdk-core-c-bridge/include/temporal-sdk-core-c-bridge.h +37 -26
  209. package/sdk-core/crates/sdk-core-c-bridge/src/client.rs +180 -87
  210. package/sdk-core/crates/sdk-core-c-bridge/src/lib.rs +89 -5
  211. package/sdk-core/crates/sdk-core-c-bridge/src/metric.rs +10 -16
  212. package/sdk-core/crates/sdk-core-c-bridge/src/runtime.rs +59 -67
  213. package/sdk-core/crates/sdk-core-c-bridge/src/testing.rs +10 -10
  214. package/sdk-core/crates/sdk-core-c-bridge/src/tests/context.rs +57 -22
  215. package/sdk-core/crates/sdk-core-c-bridge/src/tests/mod.rs +108 -12
  216. package/sdk-core/crates/sdk-core-c-bridge/src/tests/utils.rs +9 -52
  217. package/sdk-core/crates/sdk-core-c-bridge/src/worker.rs +74 -91
  218. package/sdk-core/rustfmt.toml +2 -1
  219. package/src/client.rs +206 -289
  220. package/src/helpers/try_into_js.rs +88 -2
  221. package/src/metrics.rs +277 -35
  222. package/src/runtime.rs +94 -45
  223. package/src/testing.rs +9 -16
  224. package/src/worker.rs +86 -68
  225. package/ts/native.ts +39 -3
  226. package/sdk-core/crates/client/src/workflow_handle/mod.rs +0 -212
  227. package/sdk-core/crates/common/src/errors.rs +0 -85
  228. package/sdk-core/crates/common/tests/worker_task_types_test.rs +0 -129
  229. package/sdk-core/crates/macros/LICENSE.txt +0 -21
  230. package/sdk-core/crates/sdk/src/activity_context.rs +0 -238
  231. package/sdk-core/crates/sdk/src/app_data.rs +0 -37
  232. package/sdk-core/crates/sdk-core/tests/integ_tests/activity_functions.rs +0 -5
  233. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +0 -61
@@ -1,12 +1,12 @@
1
1
  use crate::{
2
- CancellableID, RustWfCmd, SignalData, TimerResult, UnblockEvent, UpdateContext,
3
- UpdateFunctions, UpdateInfo, WfContext, WfExitValue, WorkflowFunction, WorkflowResult,
4
- panic_formatter,
2
+ BaseWorkflowContext, CancellableID, RustWfCmd, TimerResult, UnblockEvent, WorkflowResult,
3
+ WorkflowTermination, panic_formatter,
4
+ workflows::{DispatchData, DynWorkflowExecution, WorkflowExecutionFactory},
5
5
  };
6
6
  use anyhow::{Context as AnyhowContext, Error, anyhow, bail};
7
- use futures_util::{FutureExt, future::BoxFuture};
7
+ use futures_util::{FutureExt, future::LocalBoxFuture};
8
8
  use std::{
9
- collections::{HashMap, hash_map::Entry},
9
+ collections::HashMap,
10
10
  future::Future,
11
11
  panic,
12
12
  panic::AssertUnwindSafe,
@@ -14,74 +14,103 @@ use std::{
14
14
  sync::mpsc::Receiver,
15
15
  task::{Context, Poll},
16
16
  };
17
- use temporalio_common::protos::{
18
- coresdk::{
19
- workflow_activation::{
20
- FireTimer, InitializeWorkflow, NotifyHasPatch, ResolveActivity,
21
- ResolveChildWorkflowExecution, ResolveChildWorkflowExecutionStart, WorkflowActivation,
22
- WorkflowActivationJob, workflow_activation_job::Variant,
17
+ use temporalio_common::{
18
+ data_converters::PayloadConverter,
19
+ protos::{
20
+ coresdk::{
21
+ workflow_activation::{
22
+ FireTimer, InitializeWorkflow, NotifyHasPatch, ResolveActivity,
23
+ ResolveChildWorkflowExecution, ResolveChildWorkflowExecutionStart,
24
+ WorkflowActivation, WorkflowActivationJob, workflow_activation_job::Variant,
25
+ },
26
+ workflow_commands::{
27
+ CancelChildWorkflowExecution, CancelSignalWorkflow, CancelTimer,
28
+ CancelWorkflowExecution, CompleteWorkflowExecution, FailWorkflowExecution,
29
+ QueryResult, QuerySuccess, RequestCancelActivity,
30
+ RequestCancelExternalWorkflowExecution, RequestCancelLocalActivity,
31
+ RequestCancelNexusOperation, ScheduleActivity, ScheduleLocalActivity, StartTimer,
32
+ UpdateResponse, WorkflowCommand, query_result, update_response, workflow_command,
33
+ },
34
+ workflow_completion,
35
+ workflow_completion::{WorkflowActivationCompletion, workflow_activation_completion},
23
36
  },
24
- workflow_commands::{
25
- CancelChildWorkflowExecution, CancelSignalWorkflow, CancelTimer,
26
- CancelWorkflowExecution, CompleteWorkflowExecution, FailWorkflowExecution,
27
- RequestCancelActivity, RequestCancelExternalWorkflowExecution,
28
- RequestCancelLocalActivity, RequestCancelNexusOperation, ScheduleActivity,
29
- ScheduleLocalActivity, StartTimer, UpdateResponse, WorkflowCommand, update_response,
30
- workflow_command,
37
+ temporal::api::{
38
+ common::v1::{Payload, Payloads},
39
+ enums::v1::VersioningBehavior,
40
+ failure::v1::Failure,
31
41
  },
32
- workflow_completion,
33
- workflow_completion::{WorkflowActivationCompletion, workflow_activation_completion},
42
+ utilities::TryIntoOrNone,
34
43
  },
35
- temporal::api::{common::v1::Payload, enums::v1::VersioningBehavior, failure::v1::Failure},
36
- utilities::TryIntoOrNone,
37
44
  };
38
45
  use tokio::sync::{
39
46
  mpsc::{UnboundedReceiver, UnboundedSender, unbounded_channel},
40
47
  oneshot, watch,
41
48
  };
42
- use tracing::Instrument;
49
+
50
+ pub(crate) struct WorkflowFunction {
51
+ factory: WorkflowExecutionFactory,
52
+ }
43
53
 
44
54
  impl WorkflowFunction {
55
+ pub(crate) fn from_invocation(factory: WorkflowExecutionFactory) -> Self {
56
+ WorkflowFunction { factory }
57
+ }
58
+
45
59
  /// Start a workflow function, returning a future that will resolve when the workflow does,
46
60
  /// and a channel that can be used to send it activations.
47
61
  pub(crate) fn start_workflow(
48
62
  &self,
49
63
  namespace: String,
50
64
  task_queue: String,
65
+ run_id: String,
51
66
  init_workflow_job: InitializeWorkflow,
52
67
  outgoing_completions: UnboundedSender<WorkflowActivationCompletion>,
53
- ) -> (
54
- impl Future<Output = WorkflowResult<Payload>> + use<>,
55
- UnboundedSender<WorkflowActivation>,
56
- ) {
68
+ payload_converter: PayloadConverter,
69
+ ) -> Result<
70
+ (
71
+ impl Future<Output = WorkflowResult<Payload>> + use<>,
72
+ UnboundedSender<WorkflowActivation>,
73
+ ),
74
+ anyhow::Error,
75
+ > {
57
76
  let (cancel_tx, cancel_rx) = watch::channel(None);
58
77
  let span = info_span!(
59
78
  "RunWorkflow",
60
79
  "otel.name" = format!("RunWorkflow:{}", &init_workflow_job.workflow_type),
61
80
  "otel.kind" = "server"
62
81
  );
63
- let (wf_context, cmd_receiver) =
64
- WfContext::new(namespace, task_queue, init_workflow_job, cancel_rx);
82
+
83
+ let input = init_workflow_job.arguments.clone();
84
+ let (base_ctx, cmd_receiver) = BaseWorkflowContext::new(
85
+ namespace,
86
+ task_queue,
87
+ run_id,
88
+ init_workflow_job,
89
+ cancel_rx,
90
+ payload_converter.clone(),
91
+ );
92
+
93
+ // Create the workflow execution using the factory
94
+ let execution = (self.factory)(input, payload_converter.clone(), base_ctx.clone())
95
+ .context("Failed to create workflow execution")?;
96
+
65
97
  let (tx, incoming_activations) = unbounded_channel();
66
- let inner_fut = (self.wf_func)(wf_context.clone()).instrument(span);
67
- (
98
+ Ok((
68
99
  WorkflowFuture {
69
- wf_ctx: wf_context,
70
- // We need to mark the workflow future as unconstrained, otherwise Tokio will impose
71
- // an artificial limit on how many commands we can unblock in one poll round.
72
- // TODO: Now we *need* deadlock detection or we could hose the whole system
73
- inner: tokio::task::unconstrained(inner_fut).fuse().boxed(),
100
+ base_ctx,
101
+ execution,
102
+ span,
74
103
  incoming_commands: cmd_receiver,
75
104
  outgoing_completions,
76
105
  incoming_activations,
77
106
  command_status: Default::default(),
78
107
  cancel_sender: cancel_tx,
79
- sig_chans: Default::default(),
80
- updates: Default::default(),
108
+ payload_converter,
81
109
  update_futures: Default::default(),
110
+ signal_futures: Default::default(),
82
111
  },
83
112
  tx,
84
- )
113
+ ))
85
114
  }
86
115
  }
87
116
 
@@ -89,18 +118,11 @@ struct WFCommandFutInfo {
89
118
  unblocker: oneshot::Sender<UnblockEvent>,
90
119
  }
91
120
 
92
- // Allows the workflow to receive signals even though the signal handler may not yet be registered.
93
- // TODO: Either make this go away by requiring all signals to be registered up-front in a more
94
- // production-ready SDK design, or if desired to allow dynamic signal registration, prevent this
95
- // from growing unbounded if being sent lots of unhandled signals.
96
- enum SigChanOrBuffer {
97
- Chan(UnboundedSender<SignalData>),
98
- Buffer(Vec<SignalData>),
99
- }
100
-
101
121
  pub(crate) struct WorkflowFuture {
102
- /// Future produced by calling the workflow function
103
- inner: BoxFuture<'static, WorkflowResult<Payload>>,
122
+ /// The workflow execution instance
123
+ execution: Box<dyn DynWorkflowExecution>,
124
+ /// The tracing span for this workflow
125
+ span: tracing::Span,
104
126
  /// Commands produced inside user's wf code
105
127
  incoming_commands: Receiver<RustWfCmd>,
106
128
  /// Once blocked or the workflow has finished or errored out, the result is sent here
@@ -111,14 +133,17 @@ pub(crate) struct WorkflowFuture {
111
133
  command_status: HashMap<CommandID, WFCommandFutInfo>,
112
134
  /// Use to notify workflow code of cancellation
113
135
  cancel_sender: watch::Sender<Option<String>>,
114
- /// Copy of the workflow context
115
- wf_ctx: WfContext,
116
- /// Maps signal IDs to channels to send down when they are signaled
117
- sig_chans: HashMap<String, SigChanOrBuffer>,
118
- /// Maps update handlers by name to implementations
119
- updates: HashMap<String, UpdateFunctions>,
136
+ /// Base workflow context for sending commands
137
+ base_ctx: BaseWorkflowContext,
138
+ /// Payload converter for serialization/deserialization
139
+ payload_converter: PayloadConverter,
120
140
  /// Stores in-progress update futures
121
- update_futures: Vec<(String, BoxFuture<'static, Result<Payload, Error>>)>,
141
+ update_futures: Vec<(
142
+ String,
143
+ LocalBoxFuture<'static, Result<Payload, crate::workflows::WorkflowError>>,
144
+ )>,
145
+ /// Stores in-progress signal futures
146
+ signal_futures: Vec<LocalBoxFuture<'static, Result<(), crate::workflows::WorkflowError>>>,
122
147
  }
123
148
 
124
149
  impl WorkflowFuture {
@@ -169,15 +194,18 @@ impl WorkflowFuture {
169
194
 
170
195
  /// Handle a particular workflow activation job.
171
196
  ///
172
- /// Returns Ok(true) if the workflow should be evicted. Returns an error in the event that
173
- /// the workflow task should be failed.
197
+ /// Returns `Ok(should_poll_wf)` where `should_poll_wf` indicates whether the workflow future
198
+ /// should be polled after this job. Query jobs return false since an activation containing
199
+ /// _only_ queries must not advance the workflow.
200
+ ///
201
+ /// Returns an error in the event that the workflow task should be failed.
174
202
  ///
175
203
  /// Panics if internal assumptions are violated
176
204
  fn handle_job(
177
205
  &mut self,
178
206
  variant: Option<Variant>,
179
207
  outgoing_cmds: &mut Vec<WorkflowCommand>,
180
- ) -> Result<(), Error> {
208
+ ) -> Result<bool, Error> {
181
209
  if let Some(v) = variant {
182
210
  match v {
183
211
  Variant::InitializeWorkflow(_) => {
@@ -207,13 +235,54 @@ impl WorkflowFuture {
207
235
  Box::new(result.context("Child Workflow execution must have a result")?),
208
236
  ))?,
209
237
  Variant::UpdateRandomSeed(rs) => {
210
- self.wf_ctx.shared.write().random_seed = rs.randomness_seed;
238
+ self.base_ctx.shared_mut().random_seed = rs.randomness_seed;
211
239
  }
212
240
  Variant::QueryWorkflow(q) => {
213
- error!(
214
- "Queries are not implemented in the Rust SDK. Got query '{}'",
215
- q.query_type
241
+ debug!(query_type = %q.query_type, "Query received");
242
+ let query_type = q.query_type;
243
+ let query_id = q.query_id;
244
+ let data = DispatchData {
245
+ payloads: Payloads {
246
+ payloads: q.arguments,
247
+ },
248
+ headers: q.headers,
249
+ converter: &self.payload_converter,
250
+ };
251
+
252
+ let dispatch_result = match panic::catch_unwind(AssertUnwindSafe(|| {
253
+ self.execution.dispatch_query(&query_type, data)
254
+ })) {
255
+ Ok(r) => r,
256
+ Err(e) => Some(Err(anyhow!(
257
+ "Panic in query handler: {}",
258
+ panic_formatter(e)
259
+ )
260
+ .into())),
261
+ };
262
+
263
+ let response = match dispatch_result {
264
+ Some(Ok(payload)) => query_result::Variant::Succeeded(QuerySuccess {
265
+ response: Some(payload),
266
+ }),
267
+ // TODO [rust-sdk-branch]: Return list of known queries in error
268
+ None => query_result::Variant::Failed(Failure {
269
+ message: format!("No query handler for '{}'", query_type),
270
+ ..Default::default()
271
+ }),
272
+ Some(Err(e)) => query_result::Variant::Failed(Failure {
273
+ message: e.to_string(),
274
+ ..Default::default()
275
+ }),
276
+ };
277
+
278
+ outgoing_cmds.push(
279
+ workflow_command::Variant::RespondToQuery(QueryResult {
280
+ query_id,
281
+ variant: Some(response),
282
+ })
283
+ .into(),
216
284
  );
285
+ return Ok(false);
217
286
  }
218
287
  Variant::CancelWorkflow(c) => {
219
288
  // TODO: Cancel pending futures, etc
@@ -222,22 +291,31 @@ impl WorkflowFuture {
222
291
  .expect("Cancel rx not dropped");
223
292
  }
224
293
  Variant::SignalWorkflow(sig) => {
225
- let mut dat = SignalData::new(sig.input);
226
- dat.headers = sig.headers;
227
- match self.sig_chans.entry(sig.signal_name) {
228
- Entry::Occupied(mut o) => match o.get_mut() {
229
- SigChanOrBuffer::Chan(chan) => {
230
- let _ = chan.send(dat);
231
- }
232
- SigChanOrBuffer::Buffer(buf) => buf.push(dat),
294
+ debug!(signal_name = %sig.signal_name, "Signal received");
295
+ let data = DispatchData {
296
+ payloads: Payloads {
297
+ payloads: sig.input,
233
298
  },
234
- Entry::Vacant(v) => {
235
- v.insert(SigChanOrBuffer::Buffer(vec![dat]));
299
+ headers: sig.headers,
300
+ converter: &self.payload_converter,
301
+ };
302
+
303
+ let dispatch_result = match panic::catch_unwind(AssertUnwindSafe(|| {
304
+ self.execution.dispatch_signal(&sig.signal_name, data)
305
+ })) {
306
+ Ok(r) => r,
307
+ Err(e) => {
308
+ bail!("Panic in signal handler: {}", panic_formatter(e));
236
309
  }
310
+ };
311
+
312
+ if let Some(fut) = dispatch_result {
313
+ self.signal_futures.push(fut);
237
314
  }
315
+ // TODO [rust-sdk-branch]: Buffer signals w/ no handler
238
316
  }
239
317
  Variant::NotifyHasPatch(NotifyHasPatch { patch_id }) => {
240
- self.wf_ctx.shared.write().changes.insert(patch_id, true);
318
+ self.base_ctx.shared_mut().changes.insert(patch_id, true);
241
319
  }
242
320
  Variant::ResolveSignalExternalWorkflow(attrs) => {
243
321
  self.unblock(UnblockEvent::SignalExternal(attrs.seq, attrs.failure))?;
@@ -246,61 +324,65 @@ impl WorkflowFuture {
246
324
  self.unblock(UnblockEvent::CancelExternal(attrs.seq, attrs.failure))?;
247
325
  }
248
326
  Variant::DoUpdate(u) => {
249
- if let Some(impls) = self.updates.get_mut(&u.name) {
250
- let info = UpdateInfo {
251
- update_id: u.id,
252
- headers: u.headers,
253
- };
254
- let defp = Payload::default();
255
- let val_res = if u.run_validator {
256
- match panic::catch_unwind(AssertUnwindSafe(|| {
257
- (impls.validator)(&info, u.input.first().unwrap_or(&defp))
258
- })) {
259
- Ok(r) => r,
260
- Err(e) => {
261
- bail!("Panic in update validator {}", panic_formatter(e));
262
- }
327
+ let protocol_instance_id = u.protocol_instance_id;
328
+ let name = u.name;
329
+ let data = DispatchData {
330
+ payloads: Payloads { payloads: u.input },
331
+ headers: u.headers,
332
+ converter: &self.payload_converter,
333
+ };
334
+
335
+ let trait_val_result = if u.run_validator {
336
+ match panic::catch_unwind(AssertUnwindSafe(|| {
337
+ self.execution.validate_update(&name, &data)
338
+ })) {
339
+ Ok(r) => r,
340
+ Err(e) => {
341
+ bail!("Panic in update validator {}", panic_formatter(e));
263
342
  }
264
- } else {
265
- Ok(())
266
- };
267
- match val_res {
268
- Ok(_) => {
343
+ }
344
+ } else {
345
+ Some(Ok(()))
346
+ };
347
+
348
+ let mut not_found = false;
349
+ match trait_val_result {
350
+ Some(Ok(())) => {
351
+ if let Some(fut) = self.execution.start_update(&name, data) {
269
352
  outgoing_cmds.push(
270
353
  update_response(
271
- u.protocol_instance_id.clone(),
354
+ protocol_instance_id.clone(),
272
355
  update_response::Response::Accepted(()),
273
356
  )
274
357
  .into(),
275
358
  );
276
- let handler_fut = (impls.handler)(
277
- UpdateContext {
278
- wf_ctx: self.wf_ctx.clone(),
279
- info,
280
- },
281
- u.input.first().unwrap_or(&defp),
282
- );
283
359
  self.update_futures
284
- .push((u.protocol_instance_id, handler_fut));
285
- }
286
- Err(e) => {
287
- outgoing_cmds.push(
288
- update_response(
289
- u.protocol_instance_id,
290
- update_response::Response::Rejected(e.into()),
291
- )
292
- .into(),
293
- );
360
+ .push((protocol_instance_id.clone(), fut));
361
+ } else {
362
+ not_found = true;
294
363
  }
295
364
  }
296
- } else {
365
+ Some(Err(e)) => {
366
+ outgoing_cmds.push(
367
+ update_response(
368
+ protocol_instance_id.clone(),
369
+ update_response::Response::Rejected(anyhow!(e).into()),
370
+ )
371
+ .into(),
372
+ );
373
+ }
374
+ None => {
375
+ not_found = true;
376
+ }
377
+ }
378
+ if not_found {
297
379
  outgoing_cmds.push(
298
380
  update_response(
299
- u.protocol_instance_id,
381
+ protocol_instance_id,
300
382
  update_response::Response::Rejected(
301
383
  format!(
302
384
  "No update handler registered for update name {}",
303
- u.name
385
+ name
304
386
  )
305
387
  .into(),
306
388
  ),
@@ -333,7 +415,7 @@ impl WorkflowFuture {
333
415
  bail!("Empty activation job variant");
334
416
  }
335
417
 
336
- Ok(())
418
+ Ok(true)
337
419
  }
338
420
  }
339
421
 
@@ -347,9 +429,9 @@ impl Future for WorkflowFuture {
347
429
  Poll::Ready(a) => match a {
348
430
  Some(act) => act,
349
431
  None => {
350
- return Poll::Ready(Err(anyhow!(
432
+ return Poll::Ready(Err(WorkflowTermination::failed(anyhow!(
351
433
  "Workflow future's activation channel was lost!"
352
- )));
434
+ ))));
353
435
  }
354
436
  },
355
437
  Poll::Pending => return Poll::Pending,
@@ -358,61 +440,64 @@ impl Future for WorkflowFuture {
358
440
  let is_only_eviction = activation.is_only_eviction();
359
441
  let run_id = activation.run_id;
360
442
  {
361
- let mut wlock = self.wf_ctx.shared.write();
443
+ let mut wlock = self.base_ctx.shared_mut();
362
444
  wlock.is_replaying = activation.is_replaying;
363
445
  wlock.wf_time = activation.timestamp.try_into_or_none();
364
446
  wlock.history_length = activation.history_length;
447
+ wlock.continue_as_new_suggested = activation.continue_as_new_suggested;
365
448
  wlock.current_deployment_version = activation
366
449
  .deployment_version_for_current_task
367
450
  .map(Into::into);
368
451
  }
369
452
 
370
453
  let mut activation_cmds = vec![];
371
- let mut init_activation_cmds = vec![];
372
- // Lame hack to avoid hitting "unregistered" update handlers in a situation where
373
- // the history has no commands until an update is accepted. Will go away w/ SDK redesign
374
- if activation
375
- .jobs
376
- .iter()
377
- .any(|j| matches!(j.variant, Some(Variant::InitializeWorkflow(_))))
378
- && activation.jobs.iter().all(|j| {
379
- matches!(
380
- j.variant,
381
- Some(Variant::InitializeWorkflow(_) | Variant::DoUpdate(_))
382
- )
383
- })
384
- {
385
- // Poll the workflow future once to get things registered
386
- if self.poll_wf_future(cx, &run_id, &mut init_activation_cmds)? {
387
- continue;
388
- }
389
- }
390
454
 
391
455
  if is_only_eviction {
392
456
  // No need to do anything with the workflow code in this case
393
457
  self.outgoing_completions
394
458
  .send(WorkflowActivationCompletion::from_cmds(run_id, vec![]))
395
459
  .expect("Completion channel intact");
396
- return Ok(WfExitValue::Evicted).into();
460
+ return Err(WorkflowTermination::Evicted).into();
397
461
  }
398
462
 
463
+ let mut should_poll_wf = false;
399
464
  for WorkflowActivationJob { variant } in activation.jobs {
400
- if let Err(e) = self.handle_job(variant, &mut activation_cmds) {
401
- self.fail_wft(run_id, e);
465
+ match self.handle_job(variant, &mut activation_cmds) {
466
+ Ok(should_poll) => should_poll_wf |= should_poll,
467
+ Err(e) => {
468
+ self.fail_wft(run_id, e);
469
+ continue 'activations;
470
+ }
471
+ }
472
+ }
473
+
474
+ // Handle signals first
475
+ let signal_result: Result<Vec<_>, _> = std::mem::take(&mut self.signal_futures)
476
+ .into_iter()
477
+ .filter_map(|mut sig_fut| match sig_fut.poll_unpin(cx) {
478
+ Poll::Ready(Ok(())) => None,
479
+ Poll::Ready(Err(e)) => Some(Err(e)),
480
+ Poll::Pending => Some(Ok(sig_fut)),
481
+ })
482
+ .collect();
483
+ match signal_result {
484
+ Ok(remaining) => self.signal_futures = remaining,
485
+ Err(e) => {
486
+ self.fail_wft(run_id, anyhow!("Signal handler error: {}", e));
402
487
  continue 'activations;
403
488
  }
404
489
  }
405
490
 
406
- // Drive update functions
491
+ // Then updates
407
492
  self.update_futures = std::mem::take(&mut self.update_futures)
408
493
  .into_iter()
409
494
  .filter_map(
410
495
  |(instance_id, mut update_fut)| match update_fut.poll_unpin(cx) {
411
496
  Poll::Ready(v) => {
412
497
  // Push into the command channel here rather than activation_cmds
413
- // directly to avoid completing and update before any final un-awaited
498
+ // directly to avoid completing an update before any final un-awaited
414
499
  // commands started from within it.
415
- self.wf_ctx.send(
500
+ self.base_ctx.send(
416
501
  update_response(
417
502
  instance_id,
418
503
  match v {
@@ -429,13 +514,7 @@ impl Future for WorkflowFuture {
429
514
  )
430
515
  .collect();
431
516
 
432
- // The commands from the initial activation should go _after_ the updates run. This
433
- // is still a bit of hacky nonsense, as the first poll of the WF future should be able
434
- // to observe any state changed by the update handlers - but that's impossible to do
435
- // with current handler registration. In the real SDK, this will be obviated by them
436
- // being functions on a struct.
437
- activation_cmds.extend(init_activation_cmds);
438
- if self.poll_wf_future(cx, &run_id, &mut activation_cmds)? {
517
+ if should_poll_wf && self.poll_wf_future(cx, &run_id, &mut activation_cmds)? {
439
518
  continue;
440
519
  }
441
520
 
@@ -463,29 +542,31 @@ impl WorkflowFuture {
463
542
  run_id: &str,
464
543
  activation_cmds: &mut Vec<WorkflowCommand>,
465
544
  ) -> Result<bool, Error> {
466
- // TODO: Make sure this is *actually* safe before un-prototyping rust sdk
467
- let mut res = match AssertUnwindSafe(&mut self.inner)
468
- .catch_unwind()
469
- .poll_unpin(cx)
470
- {
471
- Poll::Ready(Err(e)) => {
472
- let errmsg = format!("Workflow function panicked: {}", panic_formatter(e));
473
- warn!("{}", errmsg);
474
- self.outgoing_completions
475
- .send(WorkflowActivationCompletion::fail(
476
- run_id,
477
- Failure {
478
- message: errmsg,
479
- ..Default::default()
480
- },
481
- None,
482
- ))
483
- .expect("Completion channel intact");
484
- // Loop back up because we're about to get evicted
485
- return Ok(true);
545
+ // SAFETY: AssertUnwindSafe is safe here because:
546
+ // 1. Workflows run in a single-threaded LocalSet - no data races possible
547
+ // 2. Workflow state uses closure-scoped borrows (RefCell guards released on unwind)
548
+ // 3. Core sends eviction after WFT failure, discarding all workflow state
549
+ let mut res = {
550
+ let _guard = self.span.enter();
551
+ match panic::catch_unwind(AssertUnwindSafe(|| self.execution.poll_run(cx))) {
552
+ Ok(r) => r,
553
+ Err(e) => {
554
+ let errmsg = format!("Workflow function panicked: {}", panic_formatter(e));
555
+ warn!("{}", errmsg);
556
+ self.outgoing_completions
557
+ .send(WorkflowActivationCompletion::fail(
558
+ run_id,
559
+ Failure {
560
+ message: errmsg,
561
+ ..Default::default()
562
+ },
563
+ None,
564
+ ))
565
+ .expect("Completion channel intact");
566
+ // Loop back up because we're about to get evicted
567
+ return Ok(true);
568
+ }
486
569
  }
487
- Poll::Ready(Ok(r)) => Poll::Ready(r),
488
- Poll::Pending => Poll::Pending,
489
570
  };
490
571
 
491
572
  while let Ok(cmd) = self.incoming_commands.try_recv() {
@@ -495,7 +576,7 @@ impl WorkflowFuture {
495
576
  CancellableID::Timer(seq) => {
496
577
  self.unblock(UnblockEvent::Timer(seq, TimerResult::Cancelled))?;
497
578
  // Re-poll wf future since a timer is now unblocked
498
- res = self.inner.poll_unpin(cx);
579
+ res = self.execution.poll_run(cx);
499
580
  workflow_command::Variant::CancelTimer(CancelTimer { seq })
500
581
  }
501
582
  CancellableID::Activity(seq) => {
@@ -581,9 +662,7 @@ impl WorkflowFuture {
581
662
  },
582
663
  );
583
664
  }
584
- RustWfCmd::NewNonblockingCmd(cmd) => {
585
- activation_cmds.push(cmd.into());
586
- }
665
+ RustWfCmd::NewNonblockingCmd(cmd) => activation_cmds.push(cmd.into()),
587
666
  RustWfCmd::SubscribeChildWorkflowCompletion(sub) => {
588
667
  self.command_status.insert(
589
668
  CommandID::ChildWorkflowComplete(sub.seq),
@@ -592,25 +671,10 @@ impl WorkflowFuture {
592
671
  },
593
672
  );
594
673
  }
595
- RustWfCmd::SubscribeSignal(signame, chan) => {
596
- // Deal with any buffered signal inputs for signals that were not yet
597
- // registered
598
- if let Some(SigChanOrBuffer::Buffer(buf)) = self.sig_chans.remove(&signame) {
599
- for input in buf {
600
- let _ = chan.send(input);
601
- }
602
- // Re-poll wf future since signals may be unblocked
603
- res = self.inner.poll_unpin(cx);
604
- }
605
- self.sig_chans.insert(signame, SigChanOrBuffer::Chan(chan));
606
- }
607
674
  RustWfCmd::ForceWFTFailure(err) => {
608
675
  self.fail_wft(run_id.to_string(), err);
609
676
  return Ok(true);
610
677
  }
611
- RustWfCmd::RegisterUpdate(name, impls) => {
612
- self.updates.insert(name, impls);
613
- }
614
678
  RustWfCmd::SubscribeNexusOperationCompletion { seq, unblocker } => {
615
679
  self.command_status.insert(
616
680
  CommandID::NexusOpComplete(seq),
@@ -621,33 +685,33 @@ impl WorkflowFuture {
621
685
  }
622
686
 
623
687
  if let Poll::Ready(res) = res {
624
- // TODO: Auto reply with cancel when cancelled (instead of normal exit value)
625
688
  let cmd = match res {
626
- Ok(exit_val) => match exit_val {
627
- // TODO: Generic values
628
- WfExitValue::Normal(result) => {
629
- workflow_command::Variant::CompleteWorkflowExecution(
630
- CompleteWorkflowExecution {
631
- result: Some(result),
632
- },
689
+ Ok(result) => workflow_command::Variant::CompleteWorkflowExecution(
690
+ CompleteWorkflowExecution {
691
+ result: Some(result),
692
+ },
693
+ ),
694
+ Err(termination) => match termination {
695
+ WorkflowTermination::ContinueAsNew(cmd) => {
696
+ workflow_command::Variant::ContinueAsNewWorkflowExecution(*cmd)
697
+ }
698
+ WorkflowTermination::Cancelled => {
699
+ workflow_command::Variant::CancelWorkflowExecution(
700
+ CancelWorkflowExecution {},
633
701
  )
634
702
  }
635
- WfExitValue::ContinueAsNew(cmd) => {
636
- workflow_command::Variant::ContinueAsNewWorkflowExecution(*cmd)
703
+ WorkflowTermination::Evicted => {
704
+ panic!("Don't explicitly return WorkflowTermination::Evicted")
637
705
  }
638
- WfExitValue::Cancelled => workflow_command::Variant::CancelWorkflowExecution(
639
- CancelWorkflowExecution {},
640
- ),
641
- WfExitValue::Evicted => {
642
- panic!("Don't explicitly return this")
706
+ WorkflowTermination::Failed(e) => {
707
+ workflow_command::Variant::FailWorkflowExecution(FailWorkflowExecution {
708
+ failure: Some(Failure {
709
+ message: format!("Workflow execution error: {e}"),
710
+ ..Default::default()
711
+ }),
712
+ })
643
713
  }
644
714
  },
645
- Err(e) => workflow_command::Variant::FailWorkflowExecution(FailWorkflowExecution {
646
- failure: Some(Failure {
647
- message: e.to_string(),
648
- ..Default::default()
649
- }),
650
- }),
651
715
  };
652
716
  activation_cmds.push(cmd.into())
653
717
  }