temporalio 0.0.2 → 0.1.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 (202) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +25 -23
  3. data/bridge/Cargo.lock +168 -59
  4. data/bridge/Cargo.toml +4 -2
  5. data/bridge/sdk-core/README.md +19 -6
  6. data/bridge/sdk-core/client/src/lib.rs +215 -39
  7. data/bridge/sdk-core/client/src/metrics.rs +17 -8
  8. data/bridge/sdk-core/client/src/raw.rs +4 -4
  9. data/bridge/sdk-core/client/src/retry.rs +32 -20
  10. data/bridge/sdk-core/core/Cargo.toml +22 -9
  11. data/bridge/sdk-core/core/src/abstractions.rs +203 -14
  12. data/bridge/sdk-core/core/src/core_tests/activity_tasks.rs +76 -41
  13. data/bridge/sdk-core/core/src/core_tests/determinism.rs +165 -2
  14. data/bridge/sdk-core/core/src/core_tests/local_activities.rs +204 -83
  15. data/bridge/sdk-core/core/src/core_tests/queries.rs +3 -4
  16. data/bridge/sdk-core/core/src/core_tests/workers.rs +1 -3
  17. data/bridge/sdk-core/core/src/core_tests/workflow_tasks.rs +397 -54
  18. data/bridge/sdk-core/core/src/ephemeral_server/mod.rs +106 -12
  19. data/bridge/sdk-core/core/src/internal_flags.rs +136 -0
  20. data/bridge/sdk-core/core/src/lib.rs +16 -9
  21. data/bridge/sdk-core/core/src/telemetry/log_export.rs +1 -1
  22. data/bridge/sdk-core/core/src/telemetry/metrics.rs +69 -35
  23. data/bridge/sdk-core/core/src/telemetry/mod.rs +29 -13
  24. data/bridge/sdk-core/core/src/telemetry/prometheus_server.rs +17 -12
  25. data/bridge/sdk-core/core/src/test_help/mod.rs +62 -12
  26. data/bridge/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +112 -156
  27. data/bridge/sdk-core/core/src/worker/activities/activity_task_poller_stream.rs +89 -0
  28. data/bridge/sdk-core/core/src/worker/activities/local_activities.rs +352 -122
  29. data/bridge/sdk-core/core/src/worker/activities.rs +233 -157
  30. data/bridge/sdk-core/core/src/worker/client/mocks.rs +22 -2
  31. data/bridge/sdk-core/core/src/worker/client.rs +18 -2
  32. data/bridge/sdk-core/core/src/worker/mod.rs +165 -58
  33. data/bridge/sdk-core/core/src/worker/workflow/bridge.rs +1 -3
  34. data/bridge/sdk-core/core/src/worker/workflow/driven_workflow.rs +3 -5
  35. data/bridge/sdk-core/core/src/worker/workflow/history_update.rs +856 -277
  36. data/bridge/sdk-core/core/src/worker/workflow/machines/activity_state_machine.rs +100 -43
  37. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +7 -7
  38. data/bridge/sdk-core/core/src/worker/workflow/machines/cancel_workflow_state_machine.rs +5 -4
  39. data/bridge/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +87 -27
  40. data/bridge/sdk-core/core/src/worker/workflow/machines/complete_workflow_state_machine.rs +5 -4
  41. data/bridge/sdk-core/core/src/worker/workflow/machines/continue_as_new_workflow_state_machine.rs +5 -4
  42. data/bridge/sdk-core/core/src/worker/workflow/machines/fail_workflow_state_machine.rs +5 -4
  43. data/bridge/sdk-core/core/src/worker/workflow/machines/local_activity_state_machine.rs +137 -62
  44. data/bridge/sdk-core/core/src/worker/workflow/machines/mod.rs +25 -17
  45. data/bridge/sdk-core/core/src/worker/workflow/machines/modify_workflow_properties_state_machine.rs +7 -6
  46. data/bridge/sdk-core/core/src/worker/workflow/machines/patch_state_machine.rs +103 -152
  47. data/bridge/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +7 -7
  48. data/bridge/sdk-core/core/src/worker/workflow/machines/timer_state_machine.rs +9 -9
  49. data/bridge/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +2 -2
  50. data/bridge/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +14 -7
  51. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines/local_acts.rs +5 -16
  52. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +201 -121
  53. data/bridge/sdk-core/core/src/worker/workflow/machines/workflow_task_state_machine.rs +11 -14
  54. data/bridge/sdk-core/core/src/worker/workflow/managed_run/managed_wf_test.rs +30 -15
  55. data/bridge/sdk-core/core/src/worker/workflow/managed_run.rs +1026 -376
  56. data/bridge/sdk-core/core/src/worker/workflow/mod.rs +460 -384
  57. data/bridge/sdk-core/core/src/worker/workflow/run_cache.rs +40 -57
  58. data/bridge/sdk-core/core/src/worker/workflow/wft_extraction.rs +125 -0
  59. data/bridge/sdk-core/core/src/worker/workflow/wft_poller.rs +1 -4
  60. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/saved_wf_inputs.rs +117 -0
  61. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream/tonic_status_serde.rs +24 -0
  62. data/bridge/sdk-core/core/src/worker/workflow/workflow_stream.rs +448 -718
  63. data/bridge/sdk-core/core-api/Cargo.toml +2 -1
  64. data/bridge/sdk-core/core-api/src/errors.rs +1 -34
  65. data/bridge/sdk-core/core-api/src/lib.rs +6 -2
  66. data/bridge/sdk-core/core-api/src/telemetry.rs +0 -6
  67. data/bridge/sdk-core/core-api/src/worker.rs +14 -1
  68. data/bridge/sdk-core/fsm/rustfsm_procmacro/src/lib.rs +18 -15
  69. data/bridge/sdk-core/fsm/rustfsm_trait/src/lib.rs +8 -3
  70. data/bridge/sdk-core/histories/evict_while_la_running_no_interference-16_history.bin +0 -0
  71. data/bridge/sdk-core/protos/api_upstream/temporal/api/command/v1/message.proto +5 -17
  72. data/bridge/sdk-core/protos/api_upstream/temporal/api/common/v1/message.proto +11 -0
  73. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/command_type.proto +1 -6
  74. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/event_type.proto +6 -6
  75. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +5 -0
  76. data/bridge/sdk-core/protos/api_upstream/temporal/api/enums/v1/update.proto +22 -6
  77. data/bridge/sdk-core/protos/api_upstream/temporal/api/history/v1/message.proto +48 -19
  78. data/bridge/sdk-core/protos/api_upstream/temporal/api/namespace/v1/message.proto +2 -0
  79. data/bridge/sdk-core/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +3 -0
  80. data/bridge/sdk-core/protos/api_upstream/temporal/api/{enums/v1/interaction_type.proto → protocol/v1/message.proto} +29 -11
  81. data/bridge/sdk-core/protos/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +63 -0
  82. data/bridge/sdk-core/protos/api_upstream/temporal/api/update/v1/message.proto +111 -0
  83. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +59 -28
  84. data/bridge/sdk-core/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +2 -2
  85. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_result/activity_result.proto +1 -0
  86. data/bridge/sdk-core/protos/local/temporal/sdk/core/activity_task/activity_task.proto +1 -0
  87. data/bridge/sdk-core/protos/local/temporal/sdk/core/child_workflow/child_workflow.proto +1 -0
  88. data/bridge/sdk-core/protos/local/temporal/sdk/core/common/common.proto +1 -0
  89. data/bridge/sdk-core/protos/local/temporal/sdk/core/core_interface.proto +1 -0
  90. data/bridge/sdk-core/protos/local/temporal/sdk/core/external_data/external_data.proto +1 -0
  91. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +7 -0
  92. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +1 -0
  93. data/bridge/sdk-core/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +6 -0
  94. data/bridge/sdk-core/sdk/Cargo.toml +3 -2
  95. data/bridge/sdk-core/sdk/src/lib.rs +87 -20
  96. data/bridge/sdk-core/sdk/src/workflow_future.rs +9 -8
  97. data/bridge/sdk-core/sdk-core-protos/Cargo.toml +5 -2
  98. data/bridge/sdk-core/sdk-core-protos/build.rs +36 -1
  99. data/bridge/sdk-core/sdk-core-protos/src/history_builder.rs +100 -87
  100. data/bridge/sdk-core/sdk-core-protos/src/history_info.rs +5 -1
  101. data/bridge/sdk-core/sdk-core-protos/src/lib.rs +175 -57
  102. data/bridge/sdk-core/sdk-core-protos/src/task_token.rs +12 -2
  103. data/bridge/sdk-core/test-utils/Cargo.toml +3 -1
  104. data/bridge/sdk-core/test-utils/src/canned_histories.rs +106 -296
  105. data/bridge/sdk-core/test-utils/src/histfetch.rs +1 -1
  106. data/bridge/sdk-core/test-utils/src/lib.rs +82 -23
  107. data/bridge/sdk-core/test-utils/src/wf_input_saver.rs +50 -0
  108. data/bridge/sdk-core/test-utils/src/workflows.rs +29 -0
  109. data/bridge/sdk-core/tests/fuzzy_workflow.rs +130 -0
  110. data/bridge/sdk-core/tests/{load_tests.rs → heavy_tests.rs} +125 -51
  111. data/bridge/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +25 -3
  112. data/bridge/sdk-core/tests/integ_tests/heartbeat_tests.rs +5 -3
  113. data/bridge/sdk-core/tests/integ_tests/metrics_tests.rs +218 -16
  114. data/bridge/sdk-core/tests/integ_tests/polling_tests.rs +4 -47
  115. data/bridge/sdk-core/tests/integ_tests/queries_tests.rs +5 -128
  116. data/bridge/sdk-core/tests/integ_tests/visibility_tests.rs +83 -25
  117. data/bridge/sdk-core/tests/integ_tests/workflow_tests/activities.rs +93 -69
  118. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -0
  119. data/bridge/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +6 -13
  120. data/bridge/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +1 -0
  121. data/bridge/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +6 -2
  122. data/bridge/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +3 -10
  123. data/bridge/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +72 -191
  124. data/bridge/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +1 -0
  125. data/bridge/sdk-core/tests/integ_tests/workflow_tests/patches.rs +7 -28
  126. data/bridge/sdk-core/tests/integ_tests/workflow_tests/replay.rs +12 -7
  127. data/bridge/sdk-core/tests/integ_tests/workflow_tests/resets.rs +1 -0
  128. data/bridge/sdk-core/tests/integ_tests/workflow_tests/signals.rs +18 -14
  129. data/bridge/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +6 -20
  130. data/bridge/sdk-core/tests/integ_tests/workflow_tests/timers.rs +10 -21
  131. data/bridge/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +6 -4
  132. data/bridge/sdk-core/tests/integ_tests/workflow_tests.rs +10 -11
  133. data/bridge/sdk-core/tests/main.rs +3 -13
  134. data/bridge/sdk-core/tests/runner.rs +75 -36
  135. data/bridge/sdk-core/tests/wf_input_replay.rs +32 -0
  136. data/bridge/src/connection.rs +41 -25
  137. data/bridge/src/lib.rs +269 -14
  138. data/bridge/src/runtime.rs +1 -1
  139. data/bridge/src/test_server.rs +153 -0
  140. data/bridge/src/worker.rs +89 -16
  141. data/lib/gen/temporal/api/command/v1/message_pb.rb +4 -18
  142. data/lib/gen/temporal/api/common/v1/message_pb.rb +4 -0
  143. data/lib/gen/temporal/api/enums/v1/command_type_pb.rb +1 -3
  144. data/lib/gen/temporal/api/enums/v1/event_type_pb.rb +3 -3
  145. data/lib/gen/temporal/api/enums/v1/failed_cause_pb.rb +2 -0
  146. data/lib/gen/temporal/api/enums/v1/update_pb.rb +6 -4
  147. data/lib/gen/temporal/api/history/v1/message_pb.rb +27 -19
  148. data/lib/gen/temporal/api/namespace/v1/message_pb.rb +1 -0
  149. data/lib/gen/temporal/api/operatorservice/v1/request_response_pb.rb +3 -0
  150. data/lib/gen/temporal/api/protocol/v1/message_pb.rb +30 -0
  151. data/lib/gen/temporal/api/sdk/v1/task_complete_metadata_pb.rb +23 -0
  152. data/lib/gen/temporal/api/testservice/v1/request_response_pb.rb +49 -0
  153. data/lib/gen/temporal/api/testservice/v1/service_pb.rb +21 -0
  154. data/lib/gen/temporal/api/update/v1/message_pb.rb +72 -0
  155. data/lib/gen/temporal/api/workflowservice/v1/request_response_pb.rb +26 -16
  156. data/lib/gen/temporal/sdk/core/activity_result/activity_result_pb.rb +13 -9
  157. data/lib/gen/temporal/sdk/core/activity_task/activity_task_pb.rb +10 -6
  158. data/lib/gen/temporal/sdk/core/child_workflow/child_workflow_pb.rb +13 -9
  159. data/lib/gen/temporal/sdk/core/common/common_pb.rb +7 -3
  160. data/lib/gen/temporal/sdk/core/core_interface_pb.rb +9 -3
  161. data/lib/gen/temporal/sdk/core/external_data/external_data_pb.rb +7 -3
  162. data/lib/gen/temporal/sdk/core/workflow_activation/workflow_activation_pb.rb +27 -21
  163. data/lib/gen/temporal/sdk/core/workflow_commands/workflow_commands_pb.rb +28 -24
  164. data/lib/gen/temporal/sdk/core/workflow_completion/workflow_completion_pb.rb +12 -5
  165. data/lib/temporalio/activity/context.rb +13 -8
  166. data/lib/temporalio/activity/info.rb +1 -1
  167. data/lib/temporalio/bridge/connect_options.rb +15 -0
  168. data/lib/temporalio/bridge/retry_config.rb +24 -0
  169. data/lib/temporalio/bridge/tls_options.rb +19 -0
  170. data/lib/temporalio/client/implementation.rb +8 -8
  171. data/lib/temporalio/connection/retry_config.rb +44 -0
  172. data/lib/temporalio/connection/service.rb +20 -0
  173. data/lib/temporalio/connection/test_service.rb +92 -0
  174. data/lib/temporalio/connection/tls_options.rb +51 -0
  175. data/lib/temporalio/connection/workflow_service.rb +731 -0
  176. data/lib/temporalio/connection.rb +55 -720
  177. data/lib/temporalio/interceptor/activity_inbound.rb +22 -0
  178. data/lib/temporalio/interceptor/activity_outbound.rb +24 -0
  179. data/lib/temporalio/interceptor/chain.rb +5 -5
  180. data/lib/temporalio/interceptor/client.rb +8 -4
  181. data/lib/temporalio/interceptor.rb +22 -0
  182. data/lib/temporalio/retry_policy.rb +13 -3
  183. data/lib/temporalio/testing/time_skipping_handle.rb +32 -0
  184. data/lib/temporalio/testing/time_skipping_interceptor.rb +23 -0
  185. data/lib/temporalio/testing/workflow_environment.rb +112 -0
  186. data/lib/temporalio/testing.rb +175 -0
  187. data/lib/temporalio/version.rb +1 -1
  188. data/lib/temporalio/worker/activity_runner.rb +26 -4
  189. data/lib/temporalio/worker/activity_worker.rb +44 -18
  190. data/lib/temporalio/worker/sync_worker.rb +47 -11
  191. data/lib/temporalio/worker.rb +27 -21
  192. data/lib/temporalio/workflow/async.rb +46 -0
  193. data/lib/temporalio/workflow/future.rb +138 -0
  194. data/lib/temporalio/workflow/info.rb +76 -0
  195. data/temporalio.gemspec +4 -3
  196. metadata +67 -17
  197. data/bridge/sdk-core/Cargo.lock +0 -2606
  198. data/bridge/sdk-core/protos/api_upstream/temporal/api/interaction/v1/message.proto +0 -87
  199. data/lib/bridge.so +0 -0
  200. data/lib/gen/temporal/api/enums/v1/interaction_type_pb.rb +0 -25
  201. data/lib/gen/temporal/api/interaction/v1/message_pb.rb +0 -49
  202. data/lib/gen/temporal/sdk/core/bridge/bridge_pb.rb +0 -222
@@ -1,16 +1,23 @@
1
1
  [![Build status](https://badge.buildkite.com/c23f47f4a827f04daece909963bd3a248496f0cdbabfbecee4.svg?branch=master)](https://buildkite.com/temporal/core-sdk?branch=master)
2
2
 
3
- Core SDK that can be used as a base for all other Temporal SDKs.
3
+ Core SDK that can be used as a base for other Temporal SDKs. It is currently used as the base of:
4
4
 
5
- # Getting started
5
+ - [TypeScript SDK](https://github.com/temporalio/sdk-typescript/)
6
+ - [Python SDK](https://github.com/temporalio/sdk-python/)
7
+ - [.NET SDK](https://github.com/temporalio/sdk-dotnet/)
8
+ - [Ruby SDK](https://github.com/temporalio/sdk-ruby/)
6
9
 
7
- See the [Architecture](ARCHITECTURE.md) doc for some high-level information.
10
+ For the reasoning behind the Core SDK, see:
8
11
 
9
- ## Dependencies
10
- * Protobuf compiler
12
+ - [Why Rust powers Temporal’s new Core SDK](https://temporal.io/blog/why-rust-powers-core-sdk).
13
+
14
+ See the [Architecture](ARCHITECTURE.md) doc for some high-level information about how Core works
15
+ and how language layers interact with it.
11
16
 
12
17
  # Development
13
18
 
19
+ You will need the `protoc` protobuf compiler installed to build Core.
20
+
14
21
  This repo is composed of multiple crates:
15
22
  * temporal-sdk-core-protos `./sdk-core-protos` - Holds the generated proto code and extensions
16
23
  * temporal-client `./client` - Defines client(s) for interacting with the Temporal gRPC service
@@ -24,7 +31,6 @@ Visualized (dev dependencies are in blue):
24
31
 
25
32
  ![Crate dependency graph](./etc/deps.svg)
26
33
 
27
-
28
34
  All the following commands are enforced for each pull request:
29
35
 
30
36
  ## Building and testing
@@ -102,3 +108,10 @@ Any error which is returned from a public interface should be well-typed, and we
102
108
  Errors returned from things only used in testing are free to use
103
109
  [anyhow](https://github.com/dtolnay/anyhow) for less verbosity.
104
110
 
111
+
112
+ # The Rust "SDK"
113
+ This repo contains a *prototype* Rust sdk in the `sdk/` directory. This SDK should be considered
114
+ pre-alpha in terms of its API surface. Since it's still using Core underneath, it is generally
115
+ functional. We do not currently have any firm plans to productionize this SDK. If you want to write
116
+ workflows and activities in Rust, feel free to use it - but be aware that the API may change at any
117
+ time without warning and we do not provide any support guarantees.
@@ -13,14 +13,17 @@ mod retry;
13
13
  mod workflow_handle;
14
14
 
15
15
  pub use crate::retry::{CallType, RetryClient, RETRYABLE_ERROR_CODES};
16
+ pub use metrics::ClientMetricProvider;
16
17
  pub use raw::{HealthService, OperatorService, TestService, WorkflowService};
17
18
  pub use temporal_sdk_core_protos::temporal::api::{
19
+ enums::v1::ArchivalState,
18
20
  filter::v1::{StartTimeFilter, StatusFilter, WorkflowExecutionFilter, WorkflowTypeFilter},
19
21
  workflowservice::v1::{
20
22
  list_closed_workflow_executions_request::Filters as ListClosedFilters,
21
23
  list_open_workflow_executions_request::Filters as ListOpenFilters,
22
24
  },
23
25
  };
26
+ pub use tonic;
24
27
  pub use workflow_handle::{WorkflowExecutionInfo, WorkflowExecutionResult};
25
28
 
26
29
  use crate::{
@@ -32,7 +35,6 @@ use crate::{
32
35
  use backoff::{exponential, ExponentialBackoff, SystemClock};
33
36
  use http::uri::InvalidUri;
34
37
  use once_cell::sync::OnceCell;
35
- use opentelemetry::metrics::Meter;
36
38
  use parking_lot::RwLock;
37
39
  use std::{
38
40
  collections::HashMap,
@@ -51,6 +53,7 @@ use temporal_sdk_core_protos::{
51
53
  failure::v1::Failure,
52
54
  operatorservice::v1::operator_service_client::OperatorServiceClient,
53
55
  query::v1::WorkflowQuery,
56
+ replication::v1::ClusterReplicationConfig,
54
57
  taskqueue::v1::TaskQueue,
55
58
  testservice::v1::test_service_client::TestServiceClient,
56
59
  workflowservice::v1::{workflow_service_client::WorkflowServiceClient, *},
@@ -283,7 +286,7 @@ impl ClientOptions {
283
286
  pub async fn connect(
284
287
  &self,
285
288
  namespace: impl Into<String>,
286
- metrics_meter: Option<&Meter>,
289
+ metrics_meter: Option<&dyn ClientMetricProvider>,
287
290
  headers: Option<Arc<RwLock<HashMap<String, String>>>>,
288
291
  ) -> Result<RetryClient<Client>, ClientInitError> {
289
292
  let client = self
@@ -301,7 +304,7 @@ impl ClientOptions {
301
304
  /// See [RetryClient] for more
302
305
  pub async fn connect_no_namespace(
303
306
  &self,
304
- metrics_meter: Option<&Meter>,
307
+ metrics_meter: Option<&dyn ClientMetricProvider>,
305
308
  headers: Option<Arc<RwLock<HashMap<String, String>>>>,
306
309
  ) -> Result<RetryClient<ConfiguredClient<TemporalServiceClientWithMetrics>>, ClientInitError>
307
310
  {
@@ -592,6 +595,133 @@ impl Namespace {
592
595
  }
593
596
  }
594
597
 
598
+ /// Default workflow execution retention for a Namespace is 3 days
599
+ pub const DEFAULT_WORKFLOW_EXECUTION_RETENTION_PERIOD: Duration =
600
+ Duration::from_secs(60 * 60 * 24 * 3);
601
+
602
+ /// Helper struct for `register_namespace`.
603
+ #[derive(Clone, derive_builder::Builder)]
604
+ pub struct RegisterNamespaceOptions {
605
+ /// Name (required)
606
+ #[builder(setter(into))]
607
+ pub namespace: String,
608
+ /// Description (required)
609
+ #[builder(setter(into))]
610
+ pub description: String,
611
+ /// Owner's email
612
+ #[builder(setter(into), default)]
613
+ pub owner_email: String,
614
+ /// Workflow execution retention period
615
+ #[builder(default = "DEFAULT_WORKFLOW_EXECUTION_RETENTION_PERIOD")]
616
+ pub workflow_execution_retention_period: Duration,
617
+ /// Cluster settings
618
+ #[builder(setter(strip_option, custom), default)]
619
+ pub clusters: Vec<ClusterReplicationConfig>,
620
+ /// Active cluster name
621
+ #[builder(setter(into), default)]
622
+ pub active_cluster_name: String,
623
+ /// Custom Data
624
+ #[builder(default)]
625
+ pub data: HashMap<String, String>,
626
+ /// Security Token
627
+ #[builder(setter(into), default)]
628
+ pub security_token: String,
629
+ /// Global namespace
630
+ #[builder(default)]
631
+ pub is_global_namespace: bool,
632
+ /// History Archival setting
633
+ #[builder(setter(into), default = "ArchivalState::Unspecified")]
634
+ pub history_archival_state: ArchivalState,
635
+ /// History Archival uri
636
+ #[builder(setter(into), default)]
637
+ pub history_archival_uri: String,
638
+ /// Visibility Archival setting
639
+ #[builder(setter(into), default = "ArchivalState::Unspecified")]
640
+ pub visibility_archival_state: ArchivalState,
641
+ /// Visibility Archival uri
642
+ #[builder(setter(into), default)]
643
+ pub visibility_archival_uri: String,
644
+ }
645
+
646
+ impl RegisterNamespaceOptions {
647
+ /// Builder convenience. Less `use` imports
648
+ pub fn builder() -> RegisterNamespaceOptionsBuilder {
649
+ Default::default()
650
+ }
651
+ }
652
+
653
+ impl From<RegisterNamespaceOptions> for RegisterNamespaceRequest {
654
+ fn from(val: RegisterNamespaceOptions) -> Self {
655
+ RegisterNamespaceRequest {
656
+ namespace: val.namespace,
657
+ description: val.description,
658
+ owner_email: val.owner_email,
659
+ workflow_execution_retention_period: val
660
+ .workflow_execution_retention_period
661
+ .try_into()
662
+ .ok(),
663
+ clusters: val.clusters,
664
+ active_cluster_name: val.active_cluster_name,
665
+ data: val.data,
666
+ security_token: val.security_token,
667
+ is_global_namespace: val.is_global_namespace,
668
+ history_archival_state: val.history_archival_state as i32,
669
+ history_archival_uri: val.history_archival_uri,
670
+ visibility_archival_state: val.visibility_archival_state as i32,
671
+ visibility_archival_uri: val.visibility_archival_uri,
672
+ }
673
+ }
674
+ }
675
+
676
+ impl RegisterNamespaceOptionsBuilder {
677
+ /// Custum builder function for convenience
678
+ /// Warning: setting cluster_names could blow away any previously set cluster configs
679
+ pub fn cluster_names(&mut self, clusters: Vec<String>) {
680
+ self.clusters = Some(
681
+ clusters
682
+ .into_iter()
683
+ .map(|s| ClusterReplicationConfig { cluster_name: s })
684
+ .collect(),
685
+ );
686
+ }
687
+ }
688
+
689
+ /// Helper struct for `signal_with_start_workflow_execution`.
690
+ #[derive(Clone, derive_builder::Builder)]
691
+ pub struct SignalWithStartOptions {
692
+ /// Input payload for the workflow run
693
+ #[builder(setter(strip_option), default)]
694
+ pub input: Option<Payloads>,
695
+ /// Task Queue to target (required)
696
+ #[builder(setter(into))]
697
+ pub task_queue: String,
698
+ /// Workflow id for the workflow run
699
+ #[builder(setter(into))]
700
+ pub workflow_id: String,
701
+ /// Workflow type for the workflow run
702
+ #[builder(setter(into))]
703
+ pub workflow_type: String,
704
+ #[builder(setter(strip_option), default)]
705
+ /// Request id for idempotency/deduplication
706
+ pub request_id: Option<String>,
707
+ /// The signal name to send (required)
708
+ #[builder(setter(into))]
709
+ pub signal_name: String,
710
+ /// Payloads for the signal
711
+ #[builder(default)]
712
+ pub signal_input: Option<Payloads>,
713
+ #[builder(setter(strip_option), default)]
714
+ /// Headers for the signal
715
+ pub signal_header: Option<Header>,
716
+ }
717
+
718
+ impl SignalWithStartOptions {
719
+ /// Builder convenience. Less `use` imports
720
+ pub fn builder() -> SignalWithStartOptionsBuilder {
721
+ Default::default()
722
+ }
723
+ }
724
+
595
725
  /// This trait provides higher-level friendlier interaction with the server.
596
726
  /// See the [WorkflowService] trait for a lower-level client.
597
727
  #[cfg_attr(test, mockall::automock)]
@@ -677,15 +807,8 @@ pub trait WorkflowClientTrait {
677
807
  #[allow(clippy::too_many_arguments)]
678
808
  async fn signal_with_start_workflow_execution(
679
809
  &self,
680
- input: Option<Payloads>,
681
- task_queue: String,
682
- workflow_id: String,
683
- workflow_type: String,
684
- request_id: Option<String>,
685
- options: WorkflowOptions,
686
- signal_name: String,
687
- signal_input: Option<Payloads>,
688
- signal_header: Option<Header>,
810
+ options: SignalWithStartOptions,
811
+ workflow_options: WorkflowOptions,
689
812
  ) -> Result<SignalWithStartWorkflowExecutionResponse>;
690
813
 
691
814
  /// Request a query of a certain workflow instance
@@ -734,13 +857,19 @@ pub trait WorkflowClientTrait {
734
857
  run_id: Option<String>,
735
858
  ) -> Result<TerminateWorkflowExecutionResponse>;
736
859
 
860
+ /// Register a new namespace
861
+ async fn register_namespace(
862
+ &self,
863
+ options: RegisterNamespaceOptions,
864
+ ) -> Result<RegisterNamespaceResponse>;
865
+
737
866
  /// Lists all available namespaces
738
867
  async fn list_namespaces(&self) -> Result<ListNamespacesResponse>;
739
868
 
740
869
  /// Query namespace details
741
870
  async fn describe_namespace(&self, namespace: Namespace) -> Result<DescribeNamespaceResponse>;
742
871
 
743
- /// List open workflows with Standard Visibility filtering
872
+ /// List open workflow executions with Standard Visibility filtering
744
873
  async fn list_open_workflow_executions(
745
874
  &self,
746
875
  max_page_size: i32,
@@ -749,7 +878,7 @@ pub trait WorkflowClientTrait {
749
878
  filters: Option<ListOpenFilters>,
750
879
  ) -> Result<ListOpenWorkflowExecutionsResponse>;
751
880
 
752
- /// List closed workflows Standard Visibility filtering
881
+ /// List closed workflow executions Standard Visibility filtering
753
882
  async fn list_closed_workflow_executions(
754
883
  &self,
755
884
  max_page_size: i32,
@@ -758,14 +887,25 @@ pub trait WorkflowClientTrait {
758
887
  filters: Option<ListClosedFilters>,
759
888
  ) -> Result<ListClosedWorkflowExecutionsResponse>;
760
889
 
761
- /// List workflows with Advanced Visibility filtering
890
+ /// List workflow executions with Advanced Visibility filtering
762
891
  async fn list_workflow_executions(
763
892
  &self,
764
- max_page_size: i32,
893
+ page_size: i32,
765
894
  next_page_token: Vec<u8>,
766
895
  query: String,
767
896
  ) -> Result<ListWorkflowExecutionsResponse>;
768
897
 
898
+ /// List archived workflow executions
899
+ async fn list_archived_workflow_executions(
900
+ &self,
901
+ page_size: i32,
902
+ next_page_token: Vec<u8>,
903
+ query: String,
904
+ ) -> Result<ListArchivedWorkflowExecutionsResponse>;
905
+
906
+ /// Get Cluster Search Attributes
907
+ async fn get_search_attributes(&self) -> Result<GetSearchAttributesResponse>;
908
+
769
909
  /// Returns options that were used to initialize the client
770
910
  fn get_options(&self) -> &ClientOptions;
771
911
 
@@ -937,6 +1077,7 @@ impl WorkflowClientTrait for Client {
937
1077
  identity: self.inner.options.identity.clone(),
938
1078
  binary_checksum: self.bound_worker_build_id.clone().unwrap_or_default(),
939
1079
  namespace: self.namespace.clone(),
1080
+ messages: vec![],
940
1081
  };
941
1082
  Ok(self
942
1083
  .wf_svc()
@@ -973,42 +1114,43 @@ impl WorkflowClientTrait for Client {
973
1114
 
974
1115
  async fn signal_with_start_workflow_execution(
975
1116
  &self,
976
- input: Option<Payloads>,
977
- task_queue: String,
978
- workflow_id: String,
979
- workflow_type: String,
980
- request_id: Option<String>,
981
- options: WorkflowOptions,
982
- signal_name: String,
983
- signal_input: Option<Payloads>,
984
- signal_header: Option<Header>,
1117
+ options: SignalWithStartOptions,
1118
+ workflow_options: WorkflowOptions,
985
1119
  ) -> Result<SignalWithStartWorkflowExecutionResponse> {
986
1120
  Ok(self
987
1121
  .wf_svc()
988
1122
  .signal_with_start_workflow_execution(SignalWithStartWorkflowExecutionRequest {
989
1123
  namespace: self.namespace.clone(),
990
- workflow_id,
1124
+ workflow_id: options.workflow_id,
991
1125
  workflow_type: Some(WorkflowType {
992
- name: workflow_type,
1126
+ name: options.workflow_type,
993
1127
  }),
994
1128
  task_queue: Some(TaskQueue {
995
- name: task_queue,
1129
+ name: options.task_queue,
996
1130
  kind: TaskQueueKind::Normal as i32,
997
1131
  }),
998
- input,
999
- signal_name,
1000
- signal_input,
1132
+ input: options.input,
1133
+ signal_name: options.signal_name,
1134
+ signal_input: options.signal_input,
1001
1135
  identity: self.inner.options.identity.clone(),
1002
- request_id: request_id.unwrap_or_else(|| Uuid::new_v4().to_string()),
1003
- workflow_id_reuse_policy: options.id_reuse_policy as i32,
1004
- workflow_execution_timeout: options
1136
+ request_id: options
1137
+ .request_id
1138
+ .unwrap_or_else(|| Uuid::new_v4().to_string()),
1139
+ workflow_id_reuse_policy: workflow_options.id_reuse_policy as i32,
1140
+ workflow_execution_timeout: workflow_options
1005
1141
  .execution_timeout
1006
1142
  .and_then(|d| d.try_into().ok()),
1007
- workflow_run_timeout: options.execution_timeout.and_then(|d| d.try_into().ok()),
1008
- workflow_task_timeout: options.task_timeout.and_then(|d| d.try_into().ok()),
1009
- search_attributes: options.search_attributes.and_then(|d| d.try_into().ok()),
1010
- cron_schedule: options.cron_schedule.unwrap_or_default(),
1011
- header: signal_header,
1143
+ workflow_run_timeout: workflow_options
1144
+ .execution_timeout
1145
+ .and_then(|d| d.try_into().ok()),
1146
+ workflow_task_timeout: workflow_options
1147
+ .task_timeout
1148
+ .and_then(|d| d.try_into().ok()),
1149
+ search_attributes: workflow_options
1150
+ .search_attributes
1151
+ .and_then(|d| d.try_into().ok()),
1152
+ cron_schedule: workflow_options.cron_schedule.unwrap_or_default(),
1153
+ header: options.signal_header,
1012
1154
  ..Default::default()
1013
1155
  })
1014
1156
  .await?
@@ -1140,6 +1282,14 @@ impl WorkflowClientTrait for Client {
1140
1282
  .into_inner())
1141
1283
  }
1142
1284
 
1285
+ async fn register_namespace(
1286
+ &self,
1287
+ options: RegisterNamespaceOptions,
1288
+ ) -> Result<RegisterNamespaceResponse> {
1289
+ let req = Into::<RegisterNamespaceRequest>::into(options);
1290
+ Ok(self.wf_svc().register_namespace(req).await?.into_inner())
1291
+ }
1292
+
1143
1293
  async fn list_namespaces(&self) -> Result<ListNamespacesResponse> {
1144
1294
  Ok(self
1145
1295
  .wf_svc()
@@ -1214,6 +1364,32 @@ impl WorkflowClientTrait for Client {
1214
1364
  .into_inner())
1215
1365
  }
1216
1366
 
1367
+ async fn list_archived_workflow_executions(
1368
+ &self,
1369
+ page_size: i32,
1370
+ next_page_token: Vec<u8>,
1371
+ query: String,
1372
+ ) -> Result<ListArchivedWorkflowExecutionsResponse> {
1373
+ Ok(self
1374
+ .wf_svc()
1375
+ .list_archived_workflow_executions(ListArchivedWorkflowExecutionsRequest {
1376
+ namespace: self.namespace.clone(),
1377
+ page_size,
1378
+ next_page_token,
1379
+ query,
1380
+ })
1381
+ .await?
1382
+ .into_inner())
1383
+ }
1384
+
1385
+ async fn get_search_attributes(&self) -> Result<GetSearchAttributesResponse> {
1386
+ Ok(self
1387
+ .wf_svc()
1388
+ .get_search_attributes(GetSearchAttributesRequest {})
1389
+ .await?
1390
+ .into_inner())
1391
+ }
1392
+
1217
1393
  fn get_options(&self) -> &ClientOptions {
1218
1394
  &self.inner.options
1219
1395
  }
@@ -1,7 +1,7 @@
1
1
  use crate::{AttachMetricLabels, LONG_POLL_METHOD_NAMES};
2
2
  use futures::{future::BoxFuture, FutureExt};
3
3
  use opentelemetry::{
4
- metrics::{Counter, Histogram, Meter},
4
+ metrics::{Counter, Histogram},
5
5
  KeyValue,
6
6
  };
7
7
  use std::{
@@ -30,18 +30,27 @@ pub struct MetricsContext {
30
30
  long_svc_request_latency: Histogram<u64>,
31
31
  }
32
32
 
33
+ /// Things that can provide metrics for the client implement this. Trait exists to avoid having
34
+ /// to make a whole new lower-level crate just for a tiny shared wrapper around OTel meters.
35
+ pub trait ClientMetricProvider {
36
+ /// Construct a counter metric
37
+ fn counter(&self, name: &'static str) -> Counter<u64>;
38
+ /// Construct a histogram metric
39
+ fn histogram(&self, name: &'static str) -> Histogram<u64>;
40
+ }
41
+
33
42
  impl MetricsContext {
34
- pub(crate) fn new(kvs: Vec<KeyValue>, meter: &Meter) -> Self {
43
+ pub(crate) fn new(kvs: Vec<KeyValue>, metric_provider: &dyn ClientMetricProvider) -> Self {
35
44
  Self {
36
45
  ctx: opentelemetry::Context::current(),
37
46
  kvs: Arc::new(kvs),
38
47
  poll_is_long: false,
39
- svc_request: meter.u64_counter("request").init(),
40
- svc_request_failed: meter.u64_counter("request_failure").init(),
41
- long_svc_request: meter.u64_counter("long_request").init(),
42
- long_svc_request_failed: meter.u64_counter("long_request_failure").init(),
43
- svc_request_latency: meter.u64_histogram("request_latency").init(),
44
- long_svc_request_latency: meter.u64_histogram("long_request_latency").init(),
48
+ svc_request: metric_provider.counter("request"),
49
+ svc_request_failed: metric_provider.counter("request_failure"),
50
+ long_svc_request: metric_provider.counter("long_request"),
51
+ long_svc_request_failed: metric_provider.counter("long_request_failure"),
52
+ svc_request_latency: metric_provider.histogram("request_latency"),
53
+ long_svc_request_latency: metric_provider.histogram("long_request_latency"),
45
54
  }
46
55
  }
47
56
 
@@ -760,9 +760,9 @@ proxier! {
760
760
  }
761
761
  );
762
762
  (
763
- update_workflow,
764
- UpdateWorkflowRequest,
765
- UpdateWorkflowResponse,
763
+ update_workflow_execution,
764
+ UpdateWorkflowExecutionRequest,
765
+ UpdateWorkflowExecutionResponse,
766
766
  |r| {
767
767
  let labels = AttachMetricLabels::namespace(r.get_ref().namespace.clone());
768
768
  r.extensions_mut().insert(labels);
@@ -898,7 +898,7 @@ mod tests {
898
898
  let no_underscores: HashSet<_> = impl_list.iter().map(|x| x.replace('_', "")).collect();
899
899
  for method in methods {
900
900
  if !no_underscores.contains(&method.to_lowercase()) {
901
- panic!("RPC method {} is not implemented by raw client", method)
901
+ panic!("RPC method {method} is not implemented by raw client")
902
902
  }
903
903
  }
904
904
  }
@@ -1,6 +1,6 @@
1
1
  use crate::{
2
- ClientOptions, ListClosedFilters, ListOpenFilters, Namespace, Result, RetryConfig,
3
- StartTimeFilter, WorkflowClientTrait, WorkflowOptions,
2
+ ClientOptions, ListClosedFilters, ListOpenFilters, Namespace, RegisterNamespaceOptions, Result,
3
+ RetryConfig, SignalWithStartOptions, StartTimeFilter, WorkflowClientTrait, WorkflowOptions,
4
4
  };
5
5
  use backoff::{backoff::Backoff, exponential::ExponentialBackoff, Clock, SystemClock};
6
6
  use futures_retry::{ErrorHandler, FutureRetry, RetryPolicy};
@@ -8,7 +8,7 @@ use std::{fmt::Debug, future::Future, sync::Arc, time::Duration};
8
8
  use temporal_sdk_core_protos::{
9
9
  coresdk::workflow_commands::QueryResult,
10
10
  temporal::api::{
11
- common::v1::{Header, Payload, Payloads},
11
+ common::v1::{Payload, Payloads},
12
12
  enums::v1::WorkflowTaskFailedCause,
13
13
  failure::v1::Failure,
14
14
  query::v1::WorkflowQuery,
@@ -362,28 +362,14 @@ where
362
362
 
363
363
  async fn signal_with_start_workflow_execution(
364
364
  &self,
365
- input: Option<Payloads>,
366
- task_queue: String,
367
- workflow_id: String,
368
- workflow_type: String,
369
- request_id: Option<String>,
370
- options: WorkflowOptions,
371
- signal_name: String,
372
- signal_input: Option<Payloads>,
373
- signal_header: Option<Header>,
365
+ options: SignalWithStartOptions,
366
+ workflow_options: WorkflowOptions,
374
367
  ) -> Result<SignalWithStartWorkflowExecutionResponse> {
375
368
  retry_call!(
376
369
  self,
377
370
  signal_with_start_workflow_execution,
378
- input.clone(),
379
- task_queue.clone(),
380
- workflow_id.clone(),
381
- workflow_type.clone(),
382
- request_id.clone(),
383
371
  options.clone(),
384
- signal_name.clone(),
385
- signal_input.clone(),
386
- signal_header.clone()
372
+ workflow_options.clone()
387
373
  )
388
374
  }
389
375
 
@@ -473,6 +459,13 @@ where
473
459
  )
474
460
  }
475
461
 
462
+ async fn register_namespace(
463
+ &self,
464
+ options: RegisterNamespaceOptions,
465
+ ) -> Result<RegisterNamespaceResponse> {
466
+ retry_call!(self, register_namespace, options.clone())
467
+ }
468
+
476
469
  async fn list_namespaces(&self) -> Result<ListNamespacesResponse> {
477
470
  retry_call!(self, list_namespaces,)
478
471
  }
@@ -530,6 +523,25 @@ where
530
523
  )
531
524
  }
532
525
 
526
+ async fn list_archived_workflow_executions(
527
+ &self,
528
+ page_size: i32,
529
+ next_page_token: Vec<u8>,
530
+ query: String,
531
+ ) -> Result<ListArchivedWorkflowExecutionsResponse> {
532
+ retry_call!(
533
+ self,
534
+ list_archived_workflow_executions,
535
+ page_size,
536
+ next_page_token.clone(),
537
+ query.clone()
538
+ )
539
+ }
540
+
541
+ async fn get_search_attributes(&self) -> Result<GetSearchAttributesResponse> {
542
+ retry_call!(self, get_search_attributes)
543
+ }
544
+
533
545
  fn get_options(&self) -> &ClientOptions {
534
546
  self.client.get_options()
535
547
  }
@@ -12,12 +12,17 @@ categories = ["development-tools"]
12
12
 
13
13
  [lib]
14
14
 
15
+ [features]
16
+ # Do not enable this feature when building production SDKs. If we ever want a user in the field to
17
+ # record WF input data, we can build them a custom SDK or they can build - it adds significant extra
18
+ # code size in the form of [de]serializers.
19
+ save_wf_inputs = ["rmp-serde", "temporal-sdk-core-protos/serde_serialize"]
20
+
15
21
  [dependencies]
16
22
  anyhow = "1.0"
17
23
  arc-swap = "1.3"
18
- async-channel = "1.6"
19
24
  async-trait = "0.1"
20
- base64 = "0.20"
25
+ base64 = "0.21"
21
26
  crossbeam = "0.8"
22
27
  dashmap = "5.0"
23
28
  derive_builder = "0.12"
@@ -31,8 +36,7 @@ http = "0.2"
31
36
  hyper = "0.14"
32
37
  itertools = "0.10"
33
38
  lazy_static = "1.4"
34
- log = "0.4"
35
- lru = "0.8"
39
+ lru = "0.9"
36
40
  mockall = "0.11"
37
41
  nix = "0.26"
38
42
  once_cell = "1.5"
@@ -40,12 +44,14 @@ opentelemetry = { version = "0.18", features = ["rt-tokio"] }
40
44
  opentelemetry-otlp = { version = "0.11", features = ["tokio", "metrics"] }
41
45
  opentelemetry-prometheus = "0.11"
42
46
  parking_lot = { version = "0.12", features = ["send_guard"] }
47
+ pin-project = "1.0"
43
48
  prometheus = "0.13"
44
49
  prost = "0.11"
45
- prost-types = "0.11"
50
+ prost-types = { version = "0.4", package = "prost-wkt-types" }
46
51
  rand = "0.8.3"
47
52
  reqwest = { version = "0.11", features = ["json", "stream", "rustls-tls", "tokio-rustls"], default-features = false }
48
53
  ringbuf = "0.3"
54
+ rmp-serde = { version = "1.1", optional = true }
49
55
  serde = "1.0"
50
56
  serde_json = "1.0"
51
57
  siphasher = "0.3"
@@ -62,7 +68,7 @@ tracing-opentelemetry = "0.18"
62
68
  tracing-subscriber = { version = "0.3", features = ["parking_lot", "env-filter", "registry"] }
63
69
  url = "2.2"
64
70
  uuid = { version = "1.1", features = ["v4"] }
65
- zip = "0.6"
71
+ zip = "0.6.3"
66
72
 
67
73
  # 1st party local deps
68
74
  [dependencies.temporal-sdk-core-api]
@@ -85,6 +91,7 @@ version = "0.1"
85
91
  [dev-dependencies]
86
92
  assert_matches = "1.4"
87
93
  bimap = "0.6.1"
94
+ clap = { version = "4.0", features = ["derive"] }
88
95
  criterion = "0.4"
89
96
  rstest = "0.16"
90
97
  temporal-sdk-core-test-utils = { path = "../test-utils" }
@@ -101,9 +108,10 @@ path = "../tests/main.rs"
101
108
  test = false
102
109
 
103
110
  [[test]]
104
- name = "load_tests"
105
- path = "../tests/load_tests.rs"
111
+ name = "heavy_tests"
112
+ path = "../tests/heavy_tests.rs"
106
113
  test = false
114
+ required-features = ["save_wf_inputs"]
107
115
 
108
116
  [[bench]]
109
117
  name = "workflow_replay"
@@ -113,4 +121,9 @@ harness = false
113
121
  # the dev-dependencies, which we want.
114
122
  [[example]]
115
123
  name = "integ_runner"
116
- path = "../tests/runner.rs"
124
+ path = "../tests/runner.rs"
125
+
126
+ [[example]]
127
+ name = "wf_input_replay"
128
+ path = "../tests/wf_input_replay.rs"
129
+ required-features = ["save_wf_inputs"]