@temporalio/core-bridge 1.11.8 → 1.12.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 (205) hide show
  1. package/Cargo.lock +219 -193
  2. package/Cargo.toml +27 -8
  3. package/README.md +5 -0
  4. package/index.js +72 -12
  5. package/lib/errors.d.ts +25 -0
  6. package/lib/errors.js +76 -1
  7. package/lib/errors.js.map +1 -1
  8. package/lib/index.d.ts +11 -478
  9. package/lib/index.js +28 -5
  10. package/lib/index.js.map +1 -1
  11. package/lib/native.d.ts +330 -0
  12. package/lib/{worker-tuner.js → native.js} +1 -1
  13. package/lib/native.js.map +1 -0
  14. package/package.json +7 -3
  15. package/releases/aarch64-apple-darwin/index.node +0 -0
  16. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  17. package/releases/x86_64-apple-darwin/index.node +0 -0
  18. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  19. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  20. package/sdk-core/.cargo/config.toml +8 -2
  21. package/sdk-core/.cargo/multi-worker-manual-test +15 -0
  22. package/sdk-core/.github/workflows/per-pr.yml +40 -11
  23. package/sdk-core/AGENTS.md +73 -0
  24. package/sdk-core/ARCHITECTURE.md +71 -23
  25. package/sdk-core/Cargo.toml +1 -1
  26. package/sdk-core/README.md +4 -4
  27. package/sdk-core/arch_docs/workflow_task_chunking.md +51 -0
  28. package/sdk-core/client/Cargo.toml +1 -1
  29. package/sdk-core/client/src/lib.rs +49 -13
  30. package/sdk-core/client/src/metrics.rs +15 -16
  31. package/sdk-core/client/src/proxy.rs +2 -2
  32. package/sdk-core/client/src/raw.rs +54 -8
  33. package/sdk-core/client/src/retry.rs +109 -13
  34. package/sdk-core/client/src/worker_registry/mod.rs +4 -4
  35. package/sdk-core/client/src/workflow_handle/mod.rs +1 -1
  36. package/sdk-core/core/Cargo.toml +28 -8
  37. package/sdk-core/core/src/abstractions.rs +62 -10
  38. package/sdk-core/core/src/core_tests/activity_tasks.rs +180 -8
  39. package/sdk-core/core/src/core_tests/mod.rs +4 -4
  40. package/sdk-core/core/src/core_tests/queries.rs +18 -4
  41. package/sdk-core/core/src/core_tests/workers.rs +3 -3
  42. package/sdk-core/core/src/core_tests/workflow_tasks.rs +191 -25
  43. package/sdk-core/core/src/ephemeral_server/mod.rs +10 -3
  44. package/sdk-core/core/src/internal_flags.rs +14 -14
  45. package/sdk-core/core/src/lib.rs +5 -2
  46. package/sdk-core/core/src/pollers/mod.rs +1 -1
  47. package/sdk-core/core/src/pollers/poll_buffer.rs +495 -164
  48. package/sdk-core/core/src/protosext/mod.rs +3 -3
  49. package/sdk-core/core/src/replay/mod.rs +3 -3
  50. package/sdk-core/core/src/telemetry/metrics.rs +13 -4
  51. package/sdk-core/core/src/telemetry/mod.rs +72 -70
  52. package/sdk-core/core/src/telemetry/otel.rs +51 -54
  53. package/sdk-core/core/src/test_help/mod.rs +9 -3
  54. package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +31 -11
  55. package/sdk-core/core/src/worker/activities/local_activities.rs +35 -28
  56. package/sdk-core/core/src/worker/activities.rs +58 -30
  57. package/sdk-core/core/src/worker/client/mocks.rs +3 -3
  58. package/sdk-core/core/src/worker/client.rs +155 -53
  59. package/sdk-core/core/src/worker/mod.rs +103 -95
  60. package/sdk-core/core/src/worker/nexus.rs +100 -73
  61. package/sdk-core/core/src/worker/tuner/resource_based.rs +14 -6
  62. package/sdk-core/core/src/worker/tuner.rs +4 -13
  63. package/sdk-core/core/src/worker/workflow/history_update.rs +47 -51
  64. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +1 -4
  65. package/sdk-core/core/src/worker/workflow/machines/nexus_operation_state_machine.rs +127 -32
  66. package/sdk-core/core/src/worker/workflow/machines/transition_coverage.rs +1 -2
  67. package/sdk-core/core/src/worker/workflow/machines/update_state_machine.rs +1 -1
  68. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +55 -42
  69. package/sdk-core/core/src/worker/workflow/managed_run.rs +45 -35
  70. package/sdk-core/core/src/worker/workflow/mod.rs +200 -97
  71. package/sdk-core/core/src/worker/workflow/wft_poller.rs +175 -4
  72. package/sdk-core/core/src/worker/workflow/workflow_stream.rs +38 -36
  73. package/sdk-core/core-api/Cargo.toml +8 -0
  74. package/sdk-core/core-api/src/envconfig.rs +1544 -0
  75. package/sdk-core/core-api/src/lib.rs +2 -0
  76. package/sdk-core/core-api/src/telemetry/metrics.rs +8 -0
  77. package/sdk-core/core-api/src/telemetry.rs +36 -3
  78. package/sdk-core/core-api/src/worker.rs +301 -75
  79. package/sdk-core/docker/docker-compose-telem.yaml +1 -0
  80. package/sdk-core/etc/prometheus.yaml +6 -2
  81. package/sdk-core/histories/long_local_activity_with_update-0_history.bin +0 -0
  82. package/sdk-core/histories/long_local_activity_with_update-1_history.bin +0 -0
  83. package/sdk-core/histories/long_local_activity_with_update-2_history.bin +0 -0
  84. package/sdk-core/histories/long_local_activity_with_update-3_history.bin +0 -0
  85. package/sdk-core/sdk/src/activity_context.rs +5 -0
  86. package/sdk-core/sdk/src/interceptors.rs +73 -3
  87. package/sdk-core/sdk/src/lib.rs +15 -16
  88. package/sdk-core/sdk/src/workflow_context/options.rs +10 -0
  89. package/sdk-core/sdk/src/workflow_context.rs +48 -29
  90. package/sdk-core/sdk/src/workflow_future.rs +5 -6
  91. package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/.github/workflows/push-to-buf.yml +20 -0
  92. package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/CODEOWNERS +6 -0
  93. package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/README.md +17 -6
  94. package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/VERSION +1 -1
  95. package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/buf.lock +7 -2
  96. package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/buf.yaml +2 -0
  97. package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/temporal/api/cloud/cloudservice/v1/request_response.proto +78 -0
  98. package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/temporal/api/cloud/cloudservice/v1/service.proto +29 -0
  99. package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/temporal/api/cloud/identity/v1/message.proto +74 -32
  100. package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/temporal/api/cloud/namespace/v1/message.proto +45 -15
  101. package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/temporal/api/cloud/nexus/v1/message.proto +7 -1
  102. package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/temporal/api/cloud/operation/v1/message.proto +3 -3
  103. package/sdk-core/sdk-core-protos/protos/api_cloud_upstream/temporal/api/cloud/region/v1/message.proto +3 -3
  104. package/sdk-core/sdk-core-protos/protos/api_upstream/LICENSE +1 -1
  105. package/sdk-core/sdk-core-protos/protos/api_upstream/buf.yaml +2 -0
  106. package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv2.json +1103 -88
  107. package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv3.yaml +1233 -151
  108. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/activity/v1/message.proto +0 -22
  109. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/batch/v1/message.proto +19 -24
  110. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/command/v1/message.proto +0 -22
  111. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/common/v1/message.proto +12 -22
  112. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/deployment/v1/message.proto +45 -45
  113. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/batch_operation.proto +0 -22
  114. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/command_type.proto +0 -22
  115. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/common.proto +15 -22
  116. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/deployment.proto +0 -22
  117. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/event_type.proto +4 -22
  118. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +0 -22
  119. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/namespace.proto +0 -22
  120. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/nexus.proto +0 -20
  121. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/query.proto +0 -22
  122. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/reset.proto +0 -22
  123. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/schedule.proto +0 -22
  124. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +0 -22
  125. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/update.proto +0 -22
  126. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/workflow.proto +4 -22
  127. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/errordetails/v1/message.proto +0 -22
  128. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/export/v1/message.proto +0 -22
  129. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/failure/v1/message.proto +2 -22
  130. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/filter/v1/message.proto +0 -22
  131. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/history/v1/message.proto +75 -49
  132. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/namespace/v1/message.proto +0 -22
  133. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/nexus/v1/message.proto +0 -20
  134. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +0 -22
  135. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/operatorservice/v1/service.proto +0 -22
  136. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/protocol/v1/message.proto +0 -22
  137. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/query/v1/message.proto +0 -22
  138. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/replication/v1/message.proto +0 -22
  139. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/rules/v1/message.proto +90 -0
  140. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/schedule/v1/message.proto +0 -22
  141. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/sdk/v1/enhanced_stack_trace.proto +0 -22
  142. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/sdk/v1/task_complete_metadata.proto +0 -22
  143. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/sdk/v1/user_metadata.proto +0 -22
  144. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/sdk/v1/workflow_metadata.proto +0 -22
  145. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +17 -38
  146. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/update/v1/message.proto +0 -22
  147. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/version/v1/message.proto +0 -22
  148. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflow/v1/message.proto +151 -44
  149. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +172 -65
  150. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +69 -28
  151. package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/activity_task/activity_task.proto +18 -0
  152. package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/common/common.proto +5 -0
  153. package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/nexus/nexus.proto +16 -1
  154. package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +21 -15
  155. package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +3 -0
  156. package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_completion/workflow_completion.proto +3 -0
  157. package/sdk-core/sdk-core-protos/src/lib.rs +60 -16
  158. package/sdk-core/test-utils/src/lib.rs +157 -39
  159. package/sdk-core/tests/cloud_tests.rs +86 -0
  160. package/sdk-core/tests/fuzzy_workflow.rs +23 -26
  161. package/sdk-core/tests/global_metric_tests.rs +116 -0
  162. package/sdk-core/tests/heavy_tests.rs +127 -7
  163. package/sdk-core/tests/integ_tests/client_tests.rs +2 -8
  164. package/sdk-core/tests/integ_tests/metrics_tests.rs +100 -106
  165. package/sdk-core/tests/integ_tests/polling_tests.rs +94 -8
  166. package/sdk-core/tests/integ_tests/update_tests.rs +75 -6
  167. package/sdk-core/tests/integ_tests/worker_tests.rs +54 -5
  168. package/sdk-core/tests/integ_tests/worker_versioning_tests.rs +240 -0
  169. package/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +41 -3
  170. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +168 -8
  171. package/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +285 -15
  172. package/sdk-core/tests/integ_tests/workflow_tests/priority.rs +12 -4
  173. package/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +3 -2
  174. package/sdk-core/tests/integ_tests/workflow_tests.rs +124 -74
  175. package/sdk-core/tests/main.rs +3 -51
  176. package/sdk-core/tests/manual_tests.rs +430 -0
  177. package/sdk-core/tests/runner.rs +28 -2
  178. package/src/client.rs +565 -0
  179. package/src/helpers/abort_controller.rs +204 -0
  180. package/src/helpers/callbacks.rs +299 -0
  181. package/src/helpers/errors.rs +302 -0
  182. package/src/helpers/future.rs +44 -0
  183. package/src/helpers/handles.rs +191 -0
  184. package/src/helpers/inspect.rs +18 -0
  185. package/src/helpers/json_string.rs +58 -0
  186. package/src/helpers/mod.rs +20 -0
  187. package/src/helpers/properties.rs +71 -0
  188. package/src/helpers/try_from_js.rs +213 -0
  189. package/src/helpers/try_into_js.rs +129 -0
  190. package/src/lib.rs +28 -40
  191. package/src/logs.rs +111 -0
  192. package/src/metrics.rs +325 -0
  193. package/src/runtime.rs +409 -498
  194. package/src/testing.rs +315 -57
  195. package/src/worker.rs +907 -378
  196. package/ts/errors.ts +57 -0
  197. package/ts/index.ts +10 -596
  198. package/ts/native.ts +496 -0
  199. package/lib/worker-tuner.d.ts +0 -167
  200. package/lib/worker-tuner.js.map +0 -1
  201. package/src/conversions/slot_supplier_bridge.rs +0 -291
  202. package/src/conversions.rs +0 -618
  203. package/src/errors.rs +0 -38
  204. package/src/helpers.rs +0 -297
  205. package/ts/worker-tuner.ts +0 -193
package/src/client.rs ADDED
@@ -0,0 +1,565 @@
1
+ use std::str::FromStr as _;
2
+ use std::time::Duration;
3
+ use std::{collections::HashMap, sync::Arc};
4
+
5
+ use neon::prelude::*;
6
+ use tonic::metadata::MetadataKey;
7
+
8
+ use temporal_sdk_core::{ClientOptions as CoreClientOptions, CoreRuntime, RetryClient};
9
+
10
+ use bridge_macros::{TryFromJs, js_function};
11
+ use temporal_client::{
12
+ ClientInitError, ConfiguredClient, TemporalServiceClientWithMetrics, WorkflowService,
13
+ };
14
+
15
+ use crate::runtime::Runtime;
16
+ use crate::{helpers::*, runtime::RuntimeExt as _};
17
+
18
+ pub fn init(cx: &mut neon::prelude::ModuleContext) -> neon::prelude::NeonResult<()> {
19
+ cx.export_function("newClient", client_new)?;
20
+ cx.export_function("clientUpdateHeaders", client_update_headers)?;
21
+ cx.export_function("clientUpdateApiKey", client_update_api_key)?;
22
+ cx.export_function("clientSendRequest", client_send_request)?;
23
+ cx.export_function("clientClose", client_close)?;
24
+
25
+ Ok(())
26
+ }
27
+
28
+ type CoreClient = RetryClient<ConfiguredClient<TemporalServiceClientWithMetrics>>;
29
+
30
+ pub struct Client {
31
+ // These fields are pub because they are accessed from Worker::new
32
+ pub(crate) core_runtime: Arc<CoreRuntime>,
33
+ pub(crate) core_client: CoreClient,
34
+ }
35
+
36
+ /// Create a connected gRPC client which can be used to initialize workers.
37
+ #[js_function]
38
+ pub fn client_new(
39
+ runtime: OpaqueInboundHandle<Runtime>,
40
+ config: config::ClientOptions,
41
+ ) -> BridgeResult<BridgeFuture<OpaqueOutboundHandle<Client>>> {
42
+ let runtime = runtime.borrow()?.core_runtime.clone();
43
+ let config: CoreClientOptions = config.try_into()?;
44
+
45
+ runtime.clone().future_to_promise(async move {
46
+ let metric_meter = runtime.clone().telemetry().get_temporal_metric_meter();
47
+ let res = config.connect_no_namespace(metric_meter).await;
48
+
49
+ let core_client = match res {
50
+ Ok(core_client) => core_client,
51
+ Err(ClientInitError::SystemInfoCallError(e)) => Err(BridgeError::TransportError(
52
+ format!("Failed to call GetSystemInfo: {e}"),
53
+ ))?,
54
+ Err(ClientInitError::TonicTransportError(e)) => {
55
+ Err(BridgeError::TransportError(format!("{e:?}")))?
56
+ }
57
+ Err(ClientInitError::InvalidUri(e)) => Err(BridgeError::TypeError {
58
+ message: e.to_string(),
59
+ field: None,
60
+ })?,
61
+ };
62
+
63
+ Ok(OpaqueOutboundHandle::new(Client {
64
+ core_runtime: runtime,
65
+ core_client,
66
+ }))
67
+ })
68
+ }
69
+
70
+ /// Update a Client's HTTP request headers
71
+ #[js_function]
72
+ pub fn client_update_headers(
73
+ client: OpaqueInboundHandle<Client>,
74
+ headers: HashMap<String, String>,
75
+ ) -> BridgeResult<()> {
76
+ client
77
+ .borrow()?
78
+ .core_client
79
+ .get_client()
80
+ .set_headers(headers);
81
+ Ok(())
82
+ }
83
+
84
+ /// Update a Client's API key
85
+ #[js_function]
86
+ pub fn client_update_api_key(client: OpaqueInboundHandle<Client>, key: String) -> BridgeResult<()> {
87
+ client
88
+ .borrow()?
89
+ .core_client
90
+ .get_client()
91
+ .set_api_key(Some(key));
92
+ Ok(())
93
+ }
94
+
95
+ #[js_function]
96
+ pub fn client_close(client: OpaqueInboundHandle<Client>) -> BridgeResult<()> {
97
+ // Just drop the client; there's actually no "close" method on Client.
98
+ let _ = client.take()?;
99
+ Ok(())
100
+ }
101
+
102
+ // Just drop the client, there's really nothing more to do.
103
+ impl MutableFinalize for Client {}
104
+
105
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
106
+
107
+ #[derive(Debug, TryFromJs)]
108
+ pub struct RpcCall {
109
+ pub rpc: String,
110
+ pub req: Vec<u8>,
111
+ pub retry: bool,
112
+ pub metadata: HashMap<String, String>,
113
+ pub timeout: Option<Duration>,
114
+ }
115
+
116
+ /// Send a request using the provided Client
117
+ #[js_function]
118
+ pub fn client_send_request(
119
+ client: OpaqueInboundHandle<Client>,
120
+ call: RpcCall,
121
+ ) -> BridgeResult<BridgeFuture<Vec<u8>>> {
122
+ let client = client.borrow()?;
123
+ let core_runtime = client.core_runtime.clone();
124
+ let core_client = client.core_client.clone();
125
+
126
+ // FIXME: "large future with a size of 18560 bytes"
127
+ core_runtime.future_to_promise(async move { client_invoke(core_client, call).await })
128
+ }
129
+
130
+ /// Indicates that a gRPC request failed
131
+ const SERVICE_ERROR: &str = "ServiceError";
132
+
133
+ impl TryIntoJs for tonic::Status {
134
+ type Output = JsError;
135
+ fn try_into_js<'cx>(self, cx: &mut impl Context<'cx>) -> JsResult<'cx, Self::Output> {
136
+ let jsmetadata = cx.empty_object();
137
+
138
+ let details = self.details();
139
+ if !details.is_empty() {
140
+ jsmetadata.set_property_from(cx, "grpc-status-details-bin", details)?;
141
+ }
142
+
143
+ let metadata = self.metadata().clone();
144
+ for (k, v) in &metadata.into_headers() {
145
+ let k: &str = k.as_ref();
146
+ if k.ends_with("-bin") {
147
+ jsmetadata.set_property_from(cx, k, v.as_bytes())?;
148
+ } else {
149
+ jsmetadata.set_property_from(cx, k, v.to_str().unwrap())?;
150
+ }
151
+ }
152
+
153
+ let jserr = cx.error(self.message())?;
154
+ jserr.set_property_from(cx, "name", SERVICE_ERROR)?;
155
+ jserr.set_property_from(cx, "code", self.code() as u32)?;
156
+ jserr.set_property(cx, "metadata", jsmetadata)?;
157
+
158
+ Ok(jserr)
159
+ }
160
+ }
161
+
162
+ macro_rules! rpc_call {
163
+ ($retry_client:ident, $call:ident, $call_name:ident) => {
164
+ if $call.retry {
165
+ rpc_resp($retry_client.$call_name(rpc_req($call)?).await)
166
+ } else {
167
+ rpc_resp($retry_client.into_inner().$call_name(rpc_req($call)?).await)
168
+ }
169
+ };
170
+ }
171
+
172
+ // FIXME: "this function may allocate 1400106 bytes on the stack"
173
+ #[allow(clippy::too_many_lines)]
174
+ async fn client_invoke(mut retry_client: CoreClient, call: RpcCall) -> BridgeResult<Vec<u8>> {
175
+ match call.rpc.as_str() {
176
+ "CountWorkflowExecutions" => {
177
+ rpc_call!(retry_client, call, count_workflow_executions)
178
+ }
179
+ "CreateSchedule" => {
180
+ rpc_call!(retry_client, call, create_schedule)
181
+ }
182
+ "CreateWorkflowRule" => {
183
+ rpc_call!(retry_client, call, create_workflow_rule)
184
+ }
185
+ "DeleteSchedule" => {
186
+ rpc_call!(retry_client, call, delete_schedule)
187
+ }
188
+ "DeleteWorkerDeployment" => {
189
+ rpc_call!(retry_client, call, delete_worker_deployment)
190
+ }
191
+ "DeleteWorkerDeploymentVersion" => {
192
+ rpc_call!(retry_client, call, delete_worker_deployment_version)
193
+ }
194
+ "DeleteWorkflowExecution" => {
195
+ rpc_call!(retry_client, call, delete_workflow_execution)
196
+ }
197
+ "DeleteWorkflowRule" => {
198
+ rpc_call!(retry_client, call, delete_workflow_rule)
199
+ }
200
+ "DescribeBatchOperation" => {
201
+ rpc_call!(retry_client, call, describe_batch_operation)
202
+ }
203
+ "DescribeDeployment" => {
204
+ rpc_call!(retry_client, call, describe_deployment)
205
+ }
206
+ "DeprecateNamespace" => rpc_call!(retry_client, call, deprecate_namespace),
207
+ "DescribeNamespace" => rpc_call!(retry_client, call, describe_namespace),
208
+ "DescribeSchedule" => rpc_call!(retry_client, call, describe_schedule),
209
+ "DescribeTaskQueue" => rpc_call!(retry_client, call, describe_task_queue),
210
+ "DescribeWorkerDeployment" => {
211
+ rpc_call!(retry_client, call, describe_worker_deployment)
212
+ }
213
+ "DescribeWorkerDeploymentVersion" => {
214
+ rpc_call!(retry_client, call, describe_worker_deployment_version)
215
+ }
216
+ "DescribeWorkflowExecution" => {
217
+ rpc_call!(retry_client, call, describe_workflow_execution)
218
+ }
219
+ "DescribeWorkflowRule" => {
220
+ rpc_call!(retry_client, call, describe_workflow_rule)
221
+ }
222
+ "ExecuteMultiOperation" => rpc_call!(retry_client, call, execute_multi_operation),
223
+ "GetClusterInfo" => rpc_call!(retry_client, call, get_cluster_info),
224
+ "GetCurrentDeployment" => rpc_call!(retry_client, call, get_current_deployment),
225
+ "GetDeploymentReachability" => {
226
+ rpc_call!(retry_client, call, get_deployment_reachability)
227
+ }
228
+ "GetSearchAttributes" => {
229
+ rpc_call!(retry_client, call, get_search_attributes)
230
+ }
231
+ "GetSystemInfo" => rpc_call!(retry_client, call, get_system_info),
232
+ "GetWorkerBuildIdCompatibility" => {
233
+ rpc_call!(retry_client, call, get_worker_build_id_compatibility)
234
+ }
235
+ "GetWorkerTaskReachability" => {
236
+ rpc_call!(retry_client, call, get_worker_task_reachability)
237
+ }
238
+ "GetWorkerVersioningRules" => {
239
+ rpc_call!(retry_client, call, get_worker_versioning_rules)
240
+ }
241
+ "GetWorkflowExecutionHistory" => {
242
+ rpc_call!(retry_client, call, get_workflow_execution_history)
243
+ }
244
+ "GetWorkflowExecutionHistoryReverse" => {
245
+ rpc_call!(retry_client, call, get_workflow_execution_history_reverse)
246
+ }
247
+ "ListArchivedWorkflowExecutions" => {
248
+ rpc_call!(retry_client, call, list_archived_workflow_executions)
249
+ }
250
+ "ListBatchOperations" => {
251
+ rpc_call!(retry_client, call, list_batch_operations)
252
+ }
253
+ "ListClosedWorkflowExecutions" => {
254
+ rpc_call!(retry_client, call, list_closed_workflow_executions)
255
+ }
256
+ "ListDeployments" => {
257
+ rpc_call!(retry_client, call, list_deployments)
258
+ }
259
+ "ListNamespaces" => rpc_call!(retry_client, call, list_namespaces),
260
+ "ListOpenWorkflowExecutions" => {
261
+ rpc_call!(retry_client, call, list_open_workflow_executions)
262
+ }
263
+ "ListScheduleMatchingTimes" => {
264
+ rpc_call!(retry_client, call, list_schedule_matching_times)
265
+ }
266
+ "ListSchedules" => {
267
+ rpc_call!(retry_client, call, list_schedules)
268
+ }
269
+ "ListTaskQueuePartitions" => {
270
+ rpc_call!(retry_client, call, list_task_queue_partitions)
271
+ }
272
+ "ListWorkerDeployments" => {
273
+ rpc_call!(retry_client, call, list_worker_deployments)
274
+ }
275
+ "ListWorkflowExecutions" => {
276
+ rpc_call!(retry_client, call, list_workflow_executions)
277
+ }
278
+ "ListWorkflowRules" => {
279
+ rpc_call!(retry_client, call, list_workflow_rules)
280
+ }
281
+ "PatchSchedule" => {
282
+ rpc_call!(retry_client, call, patch_schedule)
283
+ }
284
+ "PauseActivity" => {
285
+ rpc_call!(retry_client, call, pause_activity)
286
+ }
287
+ "PollActivityTaskQueue" => {
288
+ rpc_call!(retry_client, call, poll_activity_task_queue)
289
+ }
290
+ "PollNexusTaskQueue" => rpc_call!(retry_client, call, poll_nexus_task_queue),
291
+ "PollWorkflowExecutionUpdate" => {
292
+ rpc_call!(retry_client, call, poll_workflow_execution_update)
293
+ }
294
+ "PollWorkflowTaskQueue" => {
295
+ rpc_call!(retry_client, call, poll_workflow_task_queue)
296
+ }
297
+ "QueryWorkflow" => rpc_call!(retry_client, call, query_workflow),
298
+ "RecordActivityTaskHeartbeat" => {
299
+ rpc_call!(retry_client, call, record_activity_task_heartbeat)
300
+ }
301
+ "RecordActivityTaskHeartbeatById" => {
302
+ rpc_call!(retry_client, call, record_activity_task_heartbeat_by_id)
303
+ }
304
+ "RegisterNamespace" => rpc_call!(retry_client, call, register_namespace),
305
+ "RequestCancelWorkflowExecution" => {
306
+ rpc_call!(retry_client, call, request_cancel_workflow_execution)
307
+ }
308
+ "ResetActivity" => {
309
+ rpc_call!(retry_client, call, reset_activity)
310
+ }
311
+ "ResetStickyTaskQueue" => {
312
+ rpc_call!(retry_client, call, reset_sticky_task_queue)
313
+ }
314
+ "ResetWorkflowExecution" => {
315
+ rpc_call!(retry_client, call, reset_workflow_execution)
316
+ }
317
+ "RespondActivityTaskCanceled" => {
318
+ rpc_call!(retry_client, call, respond_activity_task_canceled)
319
+ }
320
+ "RespondActivityTaskCanceledById" => {
321
+ rpc_call!(retry_client, call, respond_activity_task_canceled_by_id)
322
+ }
323
+ "RespondActivityTaskCompleted" => {
324
+ rpc_call!(retry_client, call, respond_activity_task_completed)
325
+ }
326
+ "RespondActivityTaskCompletedById" => {
327
+ rpc_call!(retry_client, call, respond_activity_task_completed_by_id)
328
+ }
329
+ "RespondActivityTaskFailed" => {
330
+ rpc_call!(retry_client, call, respond_activity_task_failed)
331
+ }
332
+ "RespondActivityTaskFailedById" => {
333
+ rpc_call!(retry_client, call, respond_activity_task_failed_by_id)
334
+ }
335
+ "RespondNexusTaskCompleted" => {
336
+ rpc_call!(retry_client, call, respond_nexus_task_completed)
337
+ }
338
+ "RespondNexusTaskFailed" => {
339
+ rpc_call!(retry_client, call, respond_nexus_task_failed)
340
+ }
341
+ "RespondQueryTaskCompleted" => {
342
+ rpc_call!(retry_client, call, respond_query_task_completed)
343
+ }
344
+ "RespondWorkflowTaskCompleted" => {
345
+ rpc_call!(retry_client, call, respond_workflow_task_completed)
346
+ }
347
+ "RespondWorkflowTaskFailed" => {
348
+ rpc_call!(retry_client, call, respond_workflow_task_failed)
349
+ }
350
+ "ScanWorkflowExecutions" => {
351
+ rpc_call!(retry_client, call, scan_workflow_executions)
352
+ }
353
+ "SetCurrentDeployment" => {
354
+ rpc_call!(retry_client, call, set_current_deployment)
355
+ }
356
+ "SetWorkerDeploymentCurrentVersion" => {
357
+ rpc_call!(retry_client, call, set_worker_deployment_current_version)
358
+ }
359
+ "SetWorkerDeploymentRampingVersion" => {
360
+ rpc_call!(retry_client, call, set_worker_deployment_ramping_version)
361
+ }
362
+ "ShutdownWorker" => {
363
+ rpc_call!(retry_client, call, shutdown_worker)
364
+ }
365
+ "SignalWithStartWorkflowExecution" => {
366
+ rpc_call!(retry_client, call, signal_with_start_workflow_execution)
367
+ }
368
+ "SignalWorkflowExecution" => {
369
+ rpc_call!(retry_client, call, signal_workflow_execution)
370
+ }
371
+ "StartWorkflowExecution" => {
372
+ rpc_call!(retry_client, call, start_workflow_execution)
373
+ }
374
+ "StartBatchOperation" => {
375
+ rpc_call!(retry_client, call, start_batch_operation)
376
+ }
377
+ "StopBatchOperation" => {
378
+ rpc_call!(retry_client, call, stop_batch_operation)
379
+ }
380
+ "TerminateWorkflowExecution" => {
381
+ rpc_call!(retry_client, call, terminate_workflow_execution)
382
+ }
383
+ "TriggerWorkflowRule" => {
384
+ rpc_call!(retry_client, call, trigger_workflow_rule)
385
+ }
386
+ "UnpauseActivity" => {
387
+ rpc_call!(retry_client, call, unpause_activity)
388
+ }
389
+ "UpdateActivityOptions" => {
390
+ rpc_call!(retry_client, call, update_activity_options)
391
+ }
392
+ "UpdateNamespace" => {
393
+ rpc_call!(retry_client, call, update_namespace)
394
+ }
395
+ "UpdateSchedule" => rpc_call!(retry_client, call, update_schedule),
396
+ "UpdateWorkerDeploymentVersionMetadata" => {
397
+ rpc_call!(
398
+ retry_client,
399
+ call,
400
+ update_worker_deployment_version_metadata
401
+ )
402
+ }
403
+ "UpdateWorkflowExecution" => {
404
+ rpc_call!(retry_client, call, update_workflow_execution)
405
+ }
406
+ "UpdateWorkflowExecutionOptions" => {
407
+ rpc_call!(retry_client, call, update_workflow_execution_options)
408
+ }
409
+ "UpdateWorkerBuildIdCompatibility" => {
410
+ rpc_call!(retry_client, call, update_worker_build_id_compatibility)
411
+ }
412
+ "UpdateWorkerVersioningRules" => {
413
+ rpc_call!(retry_client, call, update_worker_versioning_rules)
414
+ }
415
+ _ => Err(BridgeError::TypeError {
416
+ field: None,
417
+ message: format!("Unknown RPC call {}", call.rpc),
418
+ }),
419
+ }
420
+ }
421
+
422
+ fn rpc_req<P: prost::Message + Default>(call: RpcCall) -> BridgeResult<tonic::Request<P>> {
423
+ let proto = P::decode(&*call.req).map_err(|err| BridgeError::TypeError {
424
+ field: None,
425
+ message: format!("Cannot decode response from buffer: {err:?}"),
426
+ })?;
427
+
428
+ let mut req = tonic::Request::new(proto);
429
+ for (k, v) in call.metadata {
430
+ req.metadata_mut().insert(
431
+ MetadataKey::from_str(k.as_str()).map_err(|err| BridgeError::TypeError {
432
+ field: None,
433
+ message: format!("Invalid metadata key: {err}"),
434
+ })?,
435
+ v.parse().map_err(|err| BridgeError::TypeError {
436
+ field: None,
437
+ message: format!("Invalid metadata value: {err}"),
438
+ })?,
439
+ );
440
+ }
441
+
442
+ if let Some(timeout) = call.timeout {
443
+ req.set_timeout(timeout);
444
+ }
445
+
446
+ Ok(req)
447
+ }
448
+
449
+ fn rpc_resp<P>(res: Result<tonic::Response<P>, tonic::Status>) -> BridgeResult<Vec<u8>>
450
+ where
451
+ P: prost::Message + Default,
452
+ {
453
+ match res {
454
+ Ok(resp) => Ok(resp.get_ref().encode_to_vec()),
455
+ Err(err) => Err(BridgeError::ServiceError(err)),
456
+ }
457
+ }
458
+
459
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
460
+
461
+ mod config {
462
+ use std::collections::HashMap;
463
+
464
+ use anyhow::Context as _;
465
+
466
+ use temporal_client::HttpConnectProxyOptions;
467
+ use temporal_sdk_core::{
468
+ ClientOptions as CoreClientOptions, ClientOptionsBuilder,
469
+ ClientTlsConfig as CoreClientTlsConfig, TlsConfig as CoreTlsConfig, Url,
470
+ };
471
+
472
+ use bridge_macros::TryFromJs;
473
+
474
+ use crate::helpers::*;
475
+
476
+ #[derive(Debug, Clone, TryFromJs)]
477
+ pub(super) struct ClientOptions {
478
+ target_url: Url,
479
+ client_name: String,
480
+ client_version: String,
481
+ tls: Option<TlsConfig>,
482
+ http_connect_proxy: Option<HttpConnectProxy>,
483
+ headers: Option<HashMap<String, String>>,
484
+ api_key: Option<String>,
485
+ disable_error_code_metric_tags: bool,
486
+ }
487
+
488
+ #[derive(Debug, Clone, TryFromJs)]
489
+ #[allow(clippy::struct_field_names)]
490
+ struct TlsConfig {
491
+ domain: Option<String>,
492
+ server_root_ca_cert: Option<Vec<u8>>,
493
+ client_tls_config: Option<TlsConfigClientCertPair>,
494
+ }
495
+
496
+ #[derive(Debug, Clone, TryFromJs)]
497
+ struct TlsConfigClientCertPair {
498
+ client_cert: Vec<u8>,
499
+ client_private_key: Vec<u8>,
500
+ }
501
+
502
+ #[derive(Debug, Clone, TryFromJs)]
503
+ struct HttpConnectProxy {
504
+ target_host: String,
505
+ basic_auth: Option<HttpConnectProxyBasicAuth>,
506
+ }
507
+
508
+ #[derive(Debug, Clone, TryFromJs)]
509
+ struct HttpConnectProxyBasicAuth {
510
+ username: String,
511
+ password: String,
512
+ }
513
+
514
+ impl TryInto<CoreClientOptions> for ClientOptions {
515
+ type Error = BridgeError;
516
+ fn try_into(self) -> Result<CoreClientOptions, Self::Error> {
517
+ let mut builder = ClientOptionsBuilder::default();
518
+
519
+ if let Some(tls) = self.tls {
520
+ builder.tls_cfg(tls.into());
521
+ }
522
+
523
+ let client_options = builder
524
+ .target_url(self.target_url)
525
+ .client_name(self.client_name)
526
+ .client_version(self.client_version)
527
+ // tls_cfg -- above
528
+ .http_connect_proxy(self.http_connect_proxy.map(Into::into))
529
+ .headers(self.headers)
530
+ .api_key(self.api_key)
531
+ .disable_error_code_metric_tags(self.disable_error_code_metric_tags)
532
+ // identity -- skipped: will be set on worker
533
+ // retry_config -- skipped: worker overrides anyway
534
+ // override_origin -- skipped: will default to tls_cfg.domain
535
+ // keep_alive -- skipped: defaults to true; is there any reason to disable this?
536
+ // skip_get_system_info -- skipped: defaults to false; is there any reason to set this?
537
+ .build()
538
+ .context("Invalid Client options")?;
539
+
540
+ Ok(client_options)
541
+ }
542
+ }
543
+
544
+ impl From<TlsConfig> for CoreTlsConfig {
545
+ fn from(val: TlsConfig) -> Self {
546
+ Self {
547
+ domain: val.domain,
548
+ server_root_ca_cert: val.server_root_ca_cert,
549
+ client_tls_config: val.client_tls_config.map(|pair| CoreClientTlsConfig {
550
+ client_cert: pair.client_cert,
551
+ client_private_key: pair.client_private_key,
552
+ }),
553
+ }
554
+ }
555
+ }
556
+
557
+ impl From<HttpConnectProxy> for HttpConnectProxyOptions {
558
+ fn from(val: HttpConnectProxy) -> Self {
559
+ Self {
560
+ target_addr: val.target_host,
561
+ basic_auth: val.basic_auth.map(|auth| (auth.username, auth.password)),
562
+ }
563
+ }
564
+ }
565
+ }