@temporalio/core-bridge 1.12.0 → 1.12.2

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 (116) hide show
  1. package/Cargo.lock +64 -119
  2. package/Cargo.toml +1 -1
  3. package/index.js +3 -2
  4. package/package.json +3 -3
  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/.cargo/config.toml +1 -2
  11. package/sdk-core/.github/workflows/per-pr.yml +2 -0
  12. package/sdk-core/AGENTS.md +7 -0
  13. package/sdk-core/Cargo.toml +9 -5
  14. package/sdk-core/README.md +6 -5
  15. package/sdk-core/client/Cargo.toml +3 -2
  16. package/sdk-core/client/src/lib.rs +17 -8
  17. package/sdk-core/client/src/metrics.rs +57 -23
  18. package/sdk-core/client/src/raw.rs +33 -15
  19. package/sdk-core/core/Cargo.toml +11 -9
  20. package/sdk-core/core/benches/workflow_replay.rs +114 -15
  21. package/sdk-core/core/src/core_tests/activity_tasks.rs +18 -18
  22. package/sdk-core/core/src/core_tests/child_workflows.rs +4 -4
  23. package/sdk-core/core/src/core_tests/determinism.rs +6 -6
  24. package/sdk-core/core/src/core_tests/local_activities.rs +20 -20
  25. package/sdk-core/core/src/core_tests/mod.rs +40 -5
  26. package/sdk-core/core/src/core_tests/queries.rs +25 -16
  27. package/sdk-core/core/src/core_tests/replay_flag.rs +3 -3
  28. package/sdk-core/core/src/core_tests/updates.rs +3 -3
  29. package/sdk-core/core/src/core_tests/workers.rs +9 -7
  30. package/sdk-core/core/src/core_tests/workflow_tasks.rs +40 -42
  31. package/sdk-core/core/src/ephemeral_server/mod.rs +1 -19
  32. package/sdk-core/core/src/lib.rs +10 -1
  33. package/sdk-core/core/src/pollers/poll_buffer.rs +2 -2
  34. package/sdk-core/core/src/replay/mod.rs +3 -3
  35. package/sdk-core/core/src/telemetry/metrics.rs +306 -152
  36. package/sdk-core/core/src/telemetry/mod.rs +11 -4
  37. package/sdk-core/core/src/telemetry/otel.rs +134 -131
  38. package/sdk-core/core/src/telemetry/prometheus_meter.rs +885 -0
  39. package/sdk-core/core/src/telemetry/prometheus_server.rs +48 -28
  40. package/sdk-core/core/src/test_help/mod.rs +27 -12
  41. package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +7 -7
  42. package/sdk-core/core/src/worker/activities.rs +4 -4
  43. package/sdk-core/core/src/worker/client/mocks.rs +10 -3
  44. package/sdk-core/core/src/worker/client.rs +68 -5
  45. package/sdk-core/core/src/worker/heartbeat.rs +229 -0
  46. package/sdk-core/core/src/worker/mod.rs +35 -14
  47. package/sdk-core/core/src/worker/tuner/resource_based.rs +4 -4
  48. package/sdk-core/core/src/worker/workflow/history_update.rs +71 -19
  49. package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -2
  50. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +1 -1
  51. package/sdk-core/core/src/worker/workflow/machines/nexus_operation_state_machine.rs +31 -48
  52. package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -2
  53. package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +3 -3
  54. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +4 -1
  55. package/sdk-core/core/src/worker/workflow/managed_run.rs +1 -1
  56. package/sdk-core/core/src/worker/workflow/mod.rs +15 -15
  57. package/sdk-core/core-api/Cargo.toml +2 -2
  58. package/sdk-core/core-api/src/envconfig.rs +204 -99
  59. package/sdk-core/core-api/src/lib.rs +9 -0
  60. package/sdk-core/core-api/src/telemetry/metrics.rs +548 -100
  61. package/sdk-core/core-api/src/worker.rs +11 -5
  62. package/sdk-core/core-c-bridge/Cargo.toml +49 -0
  63. package/sdk-core/core-c-bridge/build.rs +26 -0
  64. package/sdk-core/core-c-bridge/include/temporal-sdk-core-c-bridge.h +817 -0
  65. package/sdk-core/core-c-bridge/src/client.rs +679 -0
  66. package/sdk-core/core-c-bridge/src/lib.rs +245 -0
  67. package/sdk-core/core-c-bridge/src/metric.rs +682 -0
  68. package/sdk-core/core-c-bridge/src/random.rs +61 -0
  69. package/sdk-core/core-c-bridge/src/runtime.rs +445 -0
  70. package/sdk-core/core-c-bridge/src/testing.rs +282 -0
  71. package/sdk-core/core-c-bridge/src/tests/context.rs +644 -0
  72. package/sdk-core/core-c-bridge/src/tests/mod.rs +178 -0
  73. package/sdk-core/core-c-bridge/src/tests/utils.rs +108 -0
  74. package/sdk-core/core-c-bridge/src/worker.rs +1069 -0
  75. package/sdk-core/etc/deps.svg +64 -64
  76. package/sdk-core/sdk/src/activity_context.rs +6 -4
  77. package/sdk-core/sdk/src/lib.rs +49 -27
  78. package/sdk-core/sdk/src/workflow_future.rs +18 -25
  79. package/sdk-core/sdk-core-protos/protos/api_upstream/README.md +4 -0
  80. package/sdk-core/sdk-core-protos/protos/api_upstream/buf.yaml +0 -2
  81. package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv2.json +630 -83
  82. package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv3.yaml +632 -78
  83. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/batch/v1/message.proto +4 -4
  84. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/command/v1/message.proto +6 -4
  85. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/common/v1/message.proto +2 -2
  86. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/deployment/v1/message.proto +32 -2
  87. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/common.proto +10 -1
  88. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/deployment.proto +26 -0
  89. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +2 -0
  90. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/reset.proto +4 -4
  91. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/failure/v1/message.proto +2 -2
  92. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/history/v1/message.proto +47 -31
  93. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/nexus/v1/message.proto +4 -4
  94. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/schedule/v1/message.proto +7 -1
  95. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/worker/v1/message.proto +134 -0
  96. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflow/v1/message.proto +14 -11
  97. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +148 -37
  98. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +21 -0
  99. package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +4 -4
  100. package/sdk-core/sdk-core-protos/src/history_builder.rs +9 -5
  101. package/sdk-core/sdk-core-protos/src/lib.rs +96 -6
  102. package/sdk-core/test-utils/src/lib.rs +11 -3
  103. package/sdk-core/tests/cloud_tests.rs +3 -3
  104. package/sdk-core/tests/heavy_tests.rs +11 -3
  105. package/sdk-core/tests/integ_tests/client_tests.rs +12 -13
  106. package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +1 -1
  107. package/sdk-core/tests/integ_tests/metrics_tests.rs +188 -83
  108. package/sdk-core/tests/integ_tests/polling_tests.rs +1 -1
  109. package/sdk-core/tests/integ_tests/queries_tests.rs +56 -40
  110. package/sdk-core/tests/integ_tests/update_tests.rs +2 -7
  111. package/sdk-core/tests/integ_tests/worker_tests.rs +3 -4
  112. package/sdk-core/tests/integ_tests/worker_versioning_tests.rs +3 -7
  113. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +3 -5
  114. package/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +24 -17
  115. package/src/client.rs +6 -0
  116. package/src/metrics.rs +6 -6
@@ -0,0 +1,679 @@
1
+ use crate::ByteArray;
2
+ use crate::ByteArrayRef;
3
+ use crate::CancellationToken;
4
+ use crate::MetadataRef;
5
+ use crate::UserDataHandle;
6
+ use crate::runtime::Runtime;
7
+
8
+ use std::str::FromStr;
9
+ use std::time::Duration;
10
+ use temporal_client::{
11
+ ClientKeepAliveConfig, ClientOptions as CoreClientOptions, ClientOptionsBuilder,
12
+ ClientTlsConfig, CloudService, ConfiguredClient, HealthService, HttpConnectProxyOptions,
13
+ OperatorService, RetryClient, RetryConfig, TemporalServiceClientWithMetrics, TestService,
14
+ TlsConfig, WorkflowService,
15
+ };
16
+ use tonic::metadata::MetadataKey;
17
+ use url::Url;
18
+
19
+ #[repr(C)]
20
+ pub struct ClientOptions {
21
+ pub target_url: ByteArrayRef,
22
+ pub client_name: ByteArrayRef,
23
+ pub client_version: ByteArrayRef,
24
+ pub metadata: MetadataRef,
25
+ pub api_key: ByteArrayRef,
26
+ pub identity: ByteArrayRef,
27
+ pub tls_options: *const ClientTlsOptions,
28
+ pub retry_options: *const ClientRetryOptions,
29
+ pub keep_alive_options: *const ClientKeepAliveOptions,
30
+ pub http_connect_proxy_options: *const ClientHttpConnectProxyOptions,
31
+ }
32
+
33
+ #[repr(C)]
34
+ pub struct ClientTlsOptions {
35
+ pub server_root_ca_cert: ByteArrayRef,
36
+ pub domain: ByteArrayRef,
37
+ pub client_cert: ByteArrayRef,
38
+ pub client_private_key: ByteArrayRef,
39
+ }
40
+
41
+ #[repr(C)]
42
+ pub struct ClientRetryOptions {
43
+ pub initial_interval_millis: u64,
44
+ pub randomization_factor: f64,
45
+ pub multiplier: f64,
46
+ pub max_interval_millis: u64,
47
+ pub max_elapsed_time_millis: u64,
48
+ pub max_retries: usize,
49
+ }
50
+
51
+ #[repr(C)]
52
+ pub struct ClientKeepAliveOptions {
53
+ pub interval_millis: u64,
54
+ pub timeout_millis: u64,
55
+ }
56
+
57
+ #[repr(C)]
58
+ pub struct ClientHttpConnectProxyOptions {
59
+ pub target_host: ByteArrayRef,
60
+ pub username: ByteArrayRef,
61
+ pub password: ByteArrayRef,
62
+ }
63
+
64
+ type CoreClient = RetryClient<ConfiguredClient<TemporalServiceClientWithMetrics>>;
65
+
66
+ pub struct Client {
67
+ pub(crate) runtime: Runtime,
68
+ pub(crate) core: CoreClient,
69
+ }
70
+
71
+ // Expected to outlive all async calls that use it
72
+ unsafe impl Send for Client {}
73
+ unsafe impl Sync for Client {}
74
+
75
+ /// If success or fail are not null, they must be manually freed when done.
76
+ pub type ClientConnectCallback = unsafe extern "C" fn(
77
+ user_data: *mut libc::c_void,
78
+ success: *mut Client,
79
+ fail: *const ByteArray,
80
+ );
81
+
82
+ /// Runtime must live as long as client. Options and user data must live through
83
+ /// callback.
84
+ #[unsafe(no_mangle)]
85
+ pub extern "C" fn temporal_core_client_connect(
86
+ runtime: *mut Runtime,
87
+ options: *const ClientOptions,
88
+ user_data: *mut libc::c_void,
89
+ callback: ClientConnectCallback,
90
+ ) {
91
+ let runtime = unsafe { &mut *runtime };
92
+ // Convert opts
93
+ let options = unsafe { &*options };
94
+ let core_options: CoreClientOptions = match options.try_into() {
95
+ Ok(v) => v,
96
+ Err(err) => {
97
+ unsafe {
98
+ callback(
99
+ user_data,
100
+ std::ptr::null_mut(),
101
+ runtime
102
+ .alloc_utf8(&format!("Invalid options: {err}"))
103
+ .into_raw(),
104
+ );
105
+ }
106
+ return;
107
+ }
108
+ };
109
+ // Spawn async call
110
+ let user_data = UserDataHandle(user_data);
111
+ let core = runtime.core.clone();
112
+ runtime.core.tokio_handle().spawn(async move {
113
+ match core_options
114
+ .connect_no_namespace(core.telemetry().get_temporal_metric_meter())
115
+ .await
116
+ {
117
+ Ok(core) => {
118
+ let owned_client = Box::into_raw(Box::new(Client {
119
+ runtime: runtime.clone(),
120
+ core,
121
+ }));
122
+ unsafe {
123
+ callback(user_data.into(), owned_client, std::ptr::null());
124
+ }
125
+ }
126
+ Err(err) => unsafe {
127
+ callback(
128
+ user_data.into(),
129
+ std::ptr::null_mut(),
130
+ runtime
131
+ .alloc_utf8(&format!("Connection failed: {err}"))
132
+ .into_raw(),
133
+ );
134
+ },
135
+ }
136
+ });
137
+ }
138
+
139
+ #[unsafe(no_mangle)]
140
+ pub extern "C" fn temporal_core_client_free(client: *mut Client) {
141
+ unsafe {
142
+ let _ = Box::from_raw(client);
143
+ }
144
+ }
145
+
146
+ #[unsafe(no_mangle)]
147
+ pub extern "C" fn temporal_core_client_update_metadata(
148
+ client: *mut Client,
149
+ metadata: ByteArrayRef,
150
+ ) {
151
+ let client = unsafe { &*client };
152
+ client
153
+ .core
154
+ .get_client()
155
+ .set_headers(metadata.to_string_map_on_newlines());
156
+ }
157
+
158
+ #[unsafe(no_mangle)]
159
+ pub extern "C" fn temporal_core_client_update_api_key(client: *mut Client, api_key: ByteArrayRef) {
160
+ let client = unsafe { &*client };
161
+ client
162
+ .core
163
+ .get_client()
164
+ .set_api_key(api_key.to_option_string());
165
+ }
166
+
167
+ #[repr(C)]
168
+ pub struct RpcCallOptions {
169
+ pub service: RpcService,
170
+ pub rpc: ByteArrayRef,
171
+ pub req: ByteArrayRef,
172
+ pub retry: bool,
173
+ pub metadata: MetadataRef,
174
+ /// 0 means no timeout
175
+ pub timeout_millis: u32,
176
+ pub cancellation_token: *const CancellationToken,
177
+ }
178
+
179
+ // Expected to outlive all async calls that use it
180
+ unsafe impl Send for RpcCallOptions {}
181
+ unsafe impl Sync for RpcCallOptions {}
182
+
183
+ #[repr(C)]
184
+ #[derive(Copy, Clone, Debug)]
185
+ pub enum RpcService {
186
+ Workflow = 1,
187
+ Operator,
188
+ Cloud,
189
+ Test,
190
+ Health,
191
+ }
192
+
193
+ /// If success or failure byte arrays inside fail are not null, they must be
194
+ /// manually freed when done. Either success or failure_message are always
195
+ /// present. Status code may still be 0 with a failure message. Failure details
196
+ /// represent a protobuf gRPC status message.
197
+ pub type ClientRpcCallCallback = unsafe extern "C" fn(
198
+ user_data: *mut libc::c_void,
199
+ success: *const ByteArray,
200
+ status_code: u32,
201
+ failure_message: *const ByteArray,
202
+ failure_details: *const ByteArray,
203
+ );
204
+
205
+ macro_rules! service_call {
206
+ ($service_fn:ident, $client:ident, $options:ident, $cancel_token:ident) => {{
207
+ let call_future = $service_fn(&$client.core, &$options);
208
+ if let Some(cancel_token) = $cancel_token {
209
+ tokio::select! {
210
+ _ = cancel_token.cancelled() => Err(anyhow::anyhow!("Cancelled")),
211
+ v = call_future => v,
212
+ }
213
+ } else {
214
+ call_future.await
215
+ }
216
+ }};
217
+ }
218
+
219
+ /// Client, options, and user data must live through callback.
220
+ #[unsafe(no_mangle)]
221
+ pub extern "C" fn temporal_core_client_rpc_call(
222
+ client: *mut Client,
223
+ options: *const RpcCallOptions,
224
+ user_data: *mut libc::c_void,
225
+ callback: ClientRpcCallCallback,
226
+ ) {
227
+ let client = unsafe { &*client };
228
+ let options = unsafe { &*options };
229
+ let cancel_token = unsafe { options.cancellation_token.as_ref() }.map(|v| v.token.clone());
230
+ let user_data = UserDataHandle(user_data);
231
+ client.runtime.core.tokio_handle().spawn(async move {
232
+ let res = match options.service {
233
+ RpcService::Workflow => {
234
+ service_call!(call_workflow_service, client, options, cancel_token)
235
+ }
236
+ RpcService::Cloud => {
237
+ service_call!(call_cloud_service, client, options, cancel_token)
238
+ }
239
+ RpcService::Operator => {
240
+ service_call!(call_operator_service, client, options, cancel_token)
241
+ }
242
+ RpcService::Test => service_call!(call_test_service, client, options, cancel_token),
243
+ RpcService::Health => service_call!(call_health_service, client, options, cancel_token),
244
+ };
245
+ let (success, status_code, failure_message, failure_details) = match res {
246
+ Ok(b) => (
247
+ ByteArray::from_vec(b).into_raw(),
248
+ 0,
249
+ std::ptr::null_mut(),
250
+ std::ptr::null_mut(),
251
+ ),
252
+ Err(err) => match err.downcast::<tonic::Status>() {
253
+ Ok(status) => (
254
+ std::ptr::null_mut(),
255
+ status.code() as u32,
256
+ ByteArray::from_utf8(status.message().to_string()).into_raw(),
257
+ ByteArray::from_vec(status.details().to_owned()).into_raw(),
258
+ ),
259
+ Err(err) => (
260
+ std::ptr::null_mut(),
261
+ 0,
262
+ ByteArray::from_utf8(format!("{err}")).into_raw(),
263
+ std::ptr::null_mut(),
264
+ ),
265
+ },
266
+ };
267
+ unsafe {
268
+ callback(
269
+ user_data.into(),
270
+ success,
271
+ status_code,
272
+ failure_message,
273
+ failure_details,
274
+ );
275
+ }
276
+ });
277
+ }
278
+
279
+ macro_rules! rpc_call {
280
+ ($client:ident, $call:ident, $call_name:ident) => {
281
+ if $call.retry {
282
+ rpc_resp($client.$call_name(rpc_req($call)?).await)
283
+ } else {
284
+ rpc_resp($client.into_inner().$call_name(rpc_req($call)?).await)
285
+ }
286
+ };
287
+ }
288
+
289
+ macro_rules! rpc_call_on_trait {
290
+ ($client:ident, $call:ident, $trait:tt, $call_name:ident) => {
291
+ if $call.retry {
292
+ rpc_resp($trait::$call_name(&mut $client, rpc_req($call)?).await)
293
+ } else {
294
+ rpc_resp($trait::$call_name(&mut $client.into_inner(), rpc_req($call)?).await)
295
+ }
296
+ };
297
+ }
298
+
299
+ async fn call_workflow_service(
300
+ client: &CoreClient,
301
+ call: &RpcCallOptions,
302
+ ) -> anyhow::Result<Vec<u8>> {
303
+ let rpc = call.rpc.to_str();
304
+ let mut client = client.clone();
305
+ match rpc {
306
+ "CountWorkflowExecutions" => rpc_call!(client, call, count_workflow_executions),
307
+ "CreateSchedule" => rpc_call!(client, call, create_schedule),
308
+ "CreateWorkflowRule" => rpc_call!(client, call, create_workflow_rule),
309
+ "DeleteSchedule" => rpc_call!(client, call, delete_schedule),
310
+ "DeleteWorkerDeployment" => rpc_call!(client, call, delete_worker_deployment),
311
+ "DeleteWorkerDeploymentVersion" => {
312
+ rpc_call!(client, call, delete_worker_deployment_version)
313
+ }
314
+ "DeleteWorkflowExecution" => rpc_call!(client, call, delete_workflow_execution),
315
+ "DeleteWorkflowRule" => rpc_call!(client, call, delete_workflow_rule),
316
+ "DeprecateNamespace" => rpc_call!(client, call, deprecate_namespace),
317
+ "DescribeBatchOperation" => rpc_call!(client, call, describe_batch_operation),
318
+ "DescribeDeployment" => rpc_call!(client, call, describe_deployment),
319
+ "DescribeNamespace" => rpc_call!(client, call, describe_namespace),
320
+ "DescribeSchedule" => rpc_call!(client, call, describe_schedule),
321
+ "DescribeTaskQueue" => rpc_call!(client, call, describe_task_queue),
322
+ "DescribeWorkerDeployment" => rpc_call!(client, call, describe_worker_deployment),
323
+ "DescribeWorkerDeploymentVersion" => {
324
+ rpc_call!(client, call, describe_worker_deployment_version)
325
+ }
326
+ "DescribeWorkflowExecution" => rpc_call!(client, call, describe_workflow_execution),
327
+ "DescribeWorkflowRule" => rpc_call!(client, call, describe_workflow_rule),
328
+ "ExecuteMultiOperation" => rpc_call!(client, call, execute_multi_operation),
329
+ "GetClusterInfo" => rpc_call!(client, call, get_cluster_info),
330
+ "GetCurrentDeployment" => rpc_call!(client, call, get_current_deployment),
331
+ "GetDeploymentReachability" => rpc_call!(client, call, get_deployment_reachability),
332
+ "GetSearchAttributes" => rpc_call!(client, call, get_search_attributes),
333
+ "GetSystemInfo" => rpc_call!(client, call, get_system_info),
334
+ "GetWorkerBuildIdCompatibility" => {
335
+ rpc_call!(client, call, get_worker_build_id_compatibility)
336
+ }
337
+ "GetWorkerTaskReachability" => {
338
+ rpc_call!(client, call, get_worker_task_reachability)
339
+ }
340
+ "GetWorkerVersioningRules" => rpc_call!(client, call, get_worker_versioning_rules),
341
+ "GetWorkflowExecutionHistory" => rpc_call!(client, call, get_workflow_execution_history),
342
+ "GetWorkflowExecutionHistoryReverse" => {
343
+ rpc_call!(client, call, get_workflow_execution_history_reverse)
344
+ }
345
+ "ListArchivedWorkflowExecutions" => {
346
+ rpc_call!(client, call, list_archived_workflow_executions)
347
+ }
348
+ "ListBatchOperations" => rpc_call!(client, call, list_batch_operations),
349
+ "ListClosedWorkflowExecutions" => rpc_call!(client, call, list_closed_workflow_executions),
350
+ "ListDeployments" => rpc_call!(client, call, list_deployments),
351
+ "ListNamespaces" => rpc_call!(client, call, list_namespaces),
352
+ "ListOpenWorkflowExecutions" => rpc_call!(client, call, list_open_workflow_executions),
353
+ "ListScheduleMatchingTimes" => rpc_call!(client, call, list_schedule_matching_times),
354
+ "ListSchedules" => rpc_call!(client, call, list_schedules),
355
+ "ListTaskQueuePartitions" => rpc_call!(client, call, list_task_queue_partitions),
356
+ "ListWorkerDeployments" => rpc_call!(client, call, list_worker_deployments),
357
+ "ListWorkers" => rpc_call!(client, call, list_workers),
358
+ "ListWorkflowExecutions" => rpc_call!(client, call, list_workflow_executions),
359
+ "ListWorkflowRules" => rpc_call!(client, call, list_workflow_rules),
360
+ "PatchSchedule" => rpc_call!(client, call, patch_schedule),
361
+ "PauseActivity" => rpc_call!(client, call, pause_activity),
362
+ "PollActivityTaskQueue" => rpc_call!(client, call, poll_activity_task_queue),
363
+ "PollNexusTaskQueue" => rpc_call!(client, call, poll_nexus_task_queue),
364
+ "PollWorkflowExecutionUpdate" => rpc_call!(client, call, poll_workflow_execution_update),
365
+ "PollWorkflowTaskQueue" => rpc_call!(client, call, poll_workflow_task_queue),
366
+ "QueryWorkflow" => rpc_call!(client, call, query_workflow),
367
+ "RecordActivityTaskHeartbeat" => rpc_call!(client, call, record_activity_task_heartbeat),
368
+ "RecordActivityTaskHeartbeatById" => {
369
+ rpc_call!(client, call, record_activity_task_heartbeat_by_id)
370
+ }
371
+ "RecordWorkerHeartbeat" => rpc_call!(client, call, record_worker_heartbeat),
372
+ "RegisterNamespace" => rpc_call!(client, call, register_namespace),
373
+ "RequestCancelWorkflowExecution" => {
374
+ rpc_call!(client, call, request_cancel_workflow_execution)
375
+ }
376
+ "ResetActivity" => rpc_call!(client, call, reset_activity),
377
+ "ResetStickyTaskQueue" => rpc_call!(client, call, reset_sticky_task_queue),
378
+ "ResetWorkflowExecution" => rpc_call!(client, call, reset_workflow_execution),
379
+ "RespondActivityTaskCanceled" => rpc_call!(client, call, respond_activity_task_canceled),
380
+ "RespondActivityTaskCanceledById" => {
381
+ rpc_call!(client, call, respond_activity_task_canceled_by_id)
382
+ }
383
+ "RespondActivityTaskCompleted" => rpc_call!(client, call, respond_activity_task_completed),
384
+ "RespondActivityTaskCompletedById" => {
385
+ rpc_call!(client, call, respond_activity_task_completed_by_id)
386
+ }
387
+ "RespondActivityTaskFailed" => rpc_call!(client, call, respond_activity_task_failed),
388
+ "RespondActivityTaskFailedById" => {
389
+ rpc_call!(client, call, respond_activity_task_failed_by_id)
390
+ }
391
+ "RespondNexusTaskCompleted" => rpc_call!(client, call, respond_nexus_task_completed),
392
+ "RespondNexusTaskFailed" => rpc_call!(client, call, respond_nexus_task_failed),
393
+ "RespondQueryTaskCompleted" => rpc_call!(client, call, respond_query_task_completed),
394
+ "RespondWorkflowTaskCompleted" => rpc_call!(client, call, respond_workflow_task_completed),
395
+ "RespondWorkflowTaskFailed" => rpc_call!(client, call, respond_workflow_task_failed),
396
+ "ScanWorkflowExecutions" => rpc_call!(client, call, scan_workflow_executions),
397
+ "SetCurrentDeployment" => rpc_call!(client, call, set_current_deployment),
398
+ "SetWorkerDeploymentCurrentVersion" => {
399
+ rpc_call!(client, call, set_worker_deployment_current_version)
400
+ }
401
+ "SetWorkerDeploymentRampingVersion" => {
402
+ rpc_call!(client, call, set_worker_deployment_ramping_version)
403
+ }
404
+ "ShutdownWorker" => rpc_call!(client, call, shutdown_worker),
405
+ "SignalWithStartWorkflowExecution" => {
406
+ rpc_call!(client, call, signal_with_start_workflow_execution)
407
+ }
408
+ "SignalWorkflowExecution" => rpc_call!(client, call, signal_workflow_execution),
409
+ "StartWorkflowExecution" => rpc_call!(client, call, start_workflow_execution),
410
+ "StartBatchOperation" => rpc_call!(client, call, start_batch_operation),
411
+ "StopBatchOperation" => rpc_call!(client, call, stop_batch_operation),
412
+ "TerminateWorkflowExecution" => rpc_call!(client, call, terminate_workflow_execution),
413
+ "TriggerWorkflowRule" => rpc_call!(client, call, trigger_workflow_rule),
414
+ "UnpauseActivity" => {
415
+ rpc_call_on_trait!(client, call, WorkflowService, unpause_activity)
416
+ }
417
+ "UpdateActivityOptions" => {
418
+ rpc_call_on_trait!(client, call, WorkflowService, update_activity_options)
419
+ }
420
+ "UpdateNamespace" => rpc_call_on_trait!(client, call, WorkflowService, update_namespace),
421
+ "UpdateSchedule" => rpc_call!(client, call, update_schedule),
422
+ "UpdateWorkerDeploymentVersionMetadata" => {
423
+ rpc_call!(client, call, update_worker_deployment_version_metadata)
424
+ }
425
+ "UpdateWorkerVersioningRules" => rpc_call!(client, call, update_worker_versioning_rules),
426
+ "UpdateWorkflowExecution" => rpc_call!(client, call, update_workflow_execution),
427
+ "UpdateWorkflowExecutionOptions" => {
428
+ rpc_call!(client, call, update_workflow_execution_options)
429
+ }
430
+ "UpdateWorkerBuildIdCompatibility" => {
431
+ rpc_call!(client, call, update_worker_build_id_compatibility)
432
+ }
433
+ rpc => Err(anyhow::anyhow!("Unknown RPC call {}", rpc)),
434
+ }
435
+ }
436
+
437
+ async fn call_operator_service(
438
+ client: &CoreClient,
439
+ call: &RpcCallOptions,
440
+ ) -> anyhow::Result<Vec<u8>> {
441
+ let rpc = call.rpc.to_str();
442
+ let mut client = client.clone();
443
+ match rpc {
444
+ "AddOrUpdateRemoteCluster" => rpc_call!(client, call, add_or_update_remote_cluster),
445
+ "AddSearchAttributes" => rpc_call!(client, call, add_search_attributes),
446
+ "CreateNexusEndpoint" => {
447
+ rpc_call_on_trait!(client, call, OperatorService, create_nexus_endpoint)
448
+ }
449
+ "DeleteNamespace" => rpc_call_on_trait!(client, call, OperatorService, delete_namespace),
450
+ "DeleteNexusEndpoint" => {
451
+ rpc_call_on_trait!(client, call, OperatorService, delete_nexus_endpoint)
452
+ }
453
+ "DeleteWorkflowExecution" => rpc_call!(client, call, delete_workflow_execution),
454
+ "GetNexusEndpoint" => rpc_call_on_trait!(client, call, OperatorService, get_nexus_endpoint),
455
+ "ListClusters" => rpc_call!(client, call, list_clusters),
456
+ "ListNexusEndpoints" => rpc_call!(client, call, list_nexus_endpoints),
457
+ "ListSearchAttributes" => rpc_call!(client, call, list_search_attributes),
458
+ "RemoveRemoteCluster" => rpc_call!(client, call, remove_remote_cluster),
459
+ "RemoveSearchAttributes" => rpc_call!(client, call, remove_search_attributes),
460
+ "UpdateNexusEndpoint" => {
461
+ rpc_call_on_trait!(client, call, OperatorService, update_nexus_endpoint)
462
+ }
463
+ rpc => Err(anyhow::anyhow!("Unknown RPC call {}", rpc)),
464
+ }
465
+ }
466
+
467
+ async fn call_cloud_service(client: &CoreClient, call: &RpcCallOptions) -> anyhow::Result<Vec<u8>> {
468
+ let rpc = call.rpc.to_str();
469
+ let mut client = client.clone();
470
+ match rpc {
471
+ "AddNamespaceRegion" => rpc_call!(client, call, add_namespace_region),
472
+ "AddUserGroupMember" => rpc_call!(client, call, add_user_group_member),
473
+ "CreateApiKey" => rpc_call!(client, call, create_api_key),
474
+ "CreateNamespace" => rpc_call!(client, call, create_namespace),
475
+ "CreateNamespaceExportSink" => rpc_call!(client, call, create_namespace_export_sink),
476
+ "CreateNexusEndpoint" => {
477
+ rpc_call_on_trait!(client, call, CloudService, create_nexus_endpoint)
478
+ }
479
+ "CreateServiceAccount" => rpc_call!(client, call, create_service_account),
480
+ "CreateUserGroup" => rpc_call!(client, call, create_user_group),
481
+ "CreateUser" => rpc_call!(client, call, create_user),
482
+ "DeleteApiKey" => rpc_call!(client, call, delete_api_key),
483
+ "DeleteNamespace" => rpc_call_on_trait!(client, call, CloudService, delete_namespace),
484
+ "DeleteNamespaceExportSink" => rpc_call!(client, call, delete_namespace_export_sink),
485
+ "DeleteNamespaceRegion" => rpc_call!(client, call, delete_namespace_region),
486
+ "DeleteNexusEndpoint" => {
487
+ rpc_call_on_trait!(client, call, CloudService, delete_nexus_endpoint)
488
+ }
489
+ "DeleteServiceAccount" => rpc_call!(client, call, delete_service_account),
490
+ "DeleteUserGroup" => rpc_call!(client, call, delete_user_group),
491
+ "DeleteUser" => rpc_call!(client, call, delete_user),
492
+ "FailoverNamespaceRegion" => rpc_call!(client, call, failover_namespace_region),
493
+ "GetAccount" => rpc_call!(client, call, get_account),
494
+ "GetApiKey" => rpc_call!(client, call, get_api_key),
495
+ "GetApiKeys" => rpc_call!(client, call, get_api_keys),
496
+ "GetAsyncOperation" => rpc_call!(client, call, get_async_operation),
497
+ "GetNamespace" => rpc_call!(client, call, get_namespace),
498
+ "GetNamespaceExportSink" => rpc_call!(client, call, get_namespace_export_sink),
499
+ "GetNamespaceExportSinks" => rpc_call!(client, call, get_namespace_export_sinks),
500
+ "GetNamespaces" => rpc_call!(client, call, get_namespaces),
501
+ "GetNexusEndpoint" => rpc_call_on_trait!(client, call, CloudService, get_nexus_endpoint),
502
+ "GetNexusEndpoints" => rpc_call!(client, call, get_nexus_endpoints),
503
+ "GetRegion" => rpc_call!(client, call, get_region),
504
+ "GetRegions" => rpc_call!(client, call, get_regions),
505
+ "GetServiceAccount" => rpc_call!(client, call, get_service_account),
506
+ "GetServiceAccounts" => rpc_call!(client, call, get_service_accounts),
507
+ "GetUsage" => rpc_call!(client, call, get_usage),
508
+ "GetUserGroup" => rpc_call!(client, call, get_user_group),
509
+ "GetUserGroupMembers" => rpc_call!(client, call, get_user_group_members),
510
+ "GetUserGroups" => rpc_call!(client, call, get_user_groups),
511
+ "GetUser" => rpc_call!(client, call, get_user),
512
+ "GetUsers" => rpc_call!(client, call, get_users),
513
+ "RemoveUserGroupMember" => rpc_call!(client, call, remove_user_group_member),
514
+ "RenameCustomSearchAttribute" => rpc_call!(client, call, rename_custom_search_attribute),
515
+ "SetUserGroupNamespaceAccess" => rpc_call!(client, call, set_user_group_namespace_access),
516
+ "SetUserNamespaceAccess" => rpc_call!(client, call, set_user_namespace_access),
517
+ "UpdateAccount" => rpc_call!(client, call, update_account),
518
+ "UpdateApiKey" => rpc_call!(client, call, update_api_key),
519
+ "UpdateNamespace" => rpc_call_on_trait!(client, call, CloudService, update_namespace),
520
+ "UpdateNamespaceExportSink" => rpc_call!(client, call, update_namespace_export_sink),
521
+ "UpdateNexusEndpoint" => {
522
+ rpc_call_on_trait!(client, call, CloudService, update_nexus_endpoint)
523
+ }
524
+ "UpdateServiceAccount" => rpc_call!(client, call, update_service_account),
525
+ "UpdateUserGroup" => rpc_call!(client, call, update_user_group),
526
+ "UpdateUser" => rpc_call!(client, call, update_user),
527
+ "ValidateNamespaceExportSink" => rpc_call!(client, call, validate_namespace_export_sink),
528
+ rpc => Err(anyhow::anyhow!("Unknown RPC call {}", rpc)),
529
+ }
530
+ }
531
+
532
+ async fn call_test_service(client: &CoreClient, call: &RpcCallOptions) -> anyhow::Result<Vec<u8>> {
533
+ let rpc = call.rpc.to_str();
534
+ let mut client = client.clone();
535
+ match rpc {
536
+ "GetCurrentTime" => rpc_call!(client, call, get_current_time),
537
+ "LockTimeSkipping" => rpc_call!(client, call, lock_time_skipping),
538
+ "SleepUntil" => rpc_call!(client, call, sleep_until),
539
+ "Sleep" => rpc_call!(client, call, sleep),
540
+ "UnlockTimeSkippingWithSleep" => rpc_call!(client, call, unlock_time_skipping_with_sleep),
541
+ "UnlockTimeSkipping" => rpc_call!(client, call, unlock_time_skipping),
542
+ rpc => Err(anyhow::anyhow!("Unknown RPC call {}", rpc)),
543
+ }
544
+ }
545
+
546
+ async fn call_health_service(
547
+ client: &CoreClient,
548
+ call: &RpcCallOptions,
549
+ ) -> anyhow::Result<Vec<u8>> {
550
+ let rpc = call.rpc.to_str();
551
+ let mut client = client.clone();
552
+ match rpc {
553
+ "Check" => rpc_call!(client, call, check),
554
+ "Watch" => Err(anyhow::anyhow!(
555
+ "Health service Watch method is not implemented in C bridge"
556
+ )),
557
+ rpc => Err(anyhow::anyhow!("Unknown RPC call {}", rpc)),
558
+ }
559
+ }
560
+
561
+ fn rpc_req<P: prost::Message + Default>(
562
+ call: &RpcCallOptions,
563
+ ) -> anyhow::Result<tonic::Request<P>> {
564
+ let proto = P::decode(call.req.to_slice())?;
565
+ let mut req = tonic::Request::new(proto);
566
+ if call.metadata.size > 0 {
567
+ for (k, v) in call.metadata.to_str_map_on_newlines() {
568
+ req.metadata_mut()
569
+ .insert(MetadataKey::from_str(k)?, v.parse()?);
570
+ }
571
+ }
572
+ if call.timeout_millis > 0 {
573
+ req.set_timeout(Duration::from_millis(call.timeout_millis.into()));
574
+ }
575
+ Ok(req)
576
+ }
577
+
578
+ fn rpc_resp<P>(res: Result<tonic::Response<P>, tonic::Status>) -> anyhow::Result<Vec<u8>>
579
+ where
580
+ P: prost::Message,
581
+ P: Default,
582
+ {
583
+ Ok(res?.get_ref().encode_to_vec())
584
+ }
585
+
586
+ impl TryFrom<&ClientOptions> for CoreClientOptions {
587
+ type Error = anyhow::Error;
588
+
589
+ fn try_from(opts: &ClientOptions) -> anyhow::Result<Self> {
590
+ let mut opts_builder = ClientOptionsBuilder::default();
591
+ opts_builder
592
+ .target_url(Url::parse(opts.target_url.to_str())?)
593
+ .client_name(opts.client_name.to_string())
594
+ .client_version(opts.client_version.to_string())
595
+ .identity(opts.identity.to_string())
596
+ .retry_config(
597
+ unsafe { opts.retry_options.as_ref() }.map_or(RetryConfig::default(), |c| c.into()),
598
+ )
599
+ .keep_alive(unsafe { opts.keep_alive_options.as_ref() }.map(Into::into))
600
+ .headers(if opts.metadata.size == 0 {
601
+ None
602
+ } else {
603
+ Some(opts.metadata.to_string_map_on_newlines())
604
+ })
605
+ .api_key(opts.api_key.to_option_string())
606
+ .http_connect_proxy(
607
+ unsafe { opts.http_connect_proxy_options.as_ref() }.map(Into::into),
608
+ );
609
+ if let Some(tls_config) = unsafe { opts.tls_options.as_ref() } {
610
+ opts_builder.tls_cfg(tls_config.try_into()?);
611
+ }
612
+ Ok(opts_builder.build()?)
613
+ }
614
+ }
615
+
616
+ impl TryFrom<&ClientTlsOptions> for TlsConfig {
617
+ type Error = anyhow::Error;
618
+
619
+ fn try_from(opts: &ClientTlsOptions) -> anyhow::Result<Self> {
620
+ Ok(TlsConfig {
621
+ server_root_ca_cert: opts.server_root_ca_cert.to_option_vec(),
622
+ domain: opts.domain.to_option_string(),
623
+ client_tls_config: match (
624
+ opts.client_cert.to_option_vec(),
625
+ opts.client_private_key.to_option_vec(),
626
+ ) {
627
+ (None, None) => None,
628
+ (Some(client_cert), Some(client_private_key)) => Some(ClientTlsConfig {
629
+ client_cert,
630
+ client_private_key,
631
+ }),
632
+ _ => {
633
+ return Err(anyhow::anyhow!(
634
+ "Must have both client cert and private key or neither"
635
+ ));
636
+ }
637
+ },
638
+ })
639
+ }
640
+ }
641
+
642
+ impl From<&ClientRetryOptions> for RetryConfig {
643
+ fn from(opts: &ClientRetryOptions) -> Self {
644
+ RetryConfig {
645
+ initial_interval: Duration::from_millis(opts.initial_interval_millis),
646
+ randomization_factor: opts.randomization_factor,
647
+ multiplier: opts.multiplier,
648
+ max_interval: Duration::from_millis(opts.max_interval_millis),
649
+ max_elapsed_time: if opts.max_elapsed_time_millis == 0 {
650
+ None
651
+ } else {
652
+ Some(Duration::from_millis(opts.max_elapsed_time_millis))
653
+ },
654
+ max_retries: opts.max_retries,
655
+ }
656
+ }
657
+ }
658
+
659
+ impl From<&ClientKeepAliveOptions> for ClientKeepAliveConfig {
660
+ fn from(opts: &ClientKeepAliveOptions) -> Self {
661
+ ClientKeepAliveConfig {
662
+ interval: Duration::from_millis(opts.interval_millis),
663
+ timeout: Duration::from_millis(opts.timeout_millis),
664
+ }
665
+ }
666
+ }
667
+
668
+ impl From<&ClientHttpConnectProxyOptions> for HttpConnectProxyOptions {
669
+ fn from(opts: &ClientHttpConnectProxyOptions) -> Self {
670
+ HttpConnectProxyOptions {
671
+ target_addr: opts.target_host.to_string(),
672
+ basic_auth: if opts.username.size != 0 && opts.password.size != 0 {
673
+ Some((opts.username.to_string(), opts.password.to_string()))
674
+ } else {
675
+ None
676
+ },
677
+ }
678
+ }
679
+ }