@temporalio/core-bridge 1.14.1 → 1.15.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 (135) hide show
  1. package/Cargo.lock +648 -606
  2. package/bridge-macros/src/derive_tryintojs.rs +40 -0
  3. package/lib/native.d.ts +23 -2
  4. package/package.json +12 -13
  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/multi-worker-manual-test +0 -0
  11. package/sdk-core/AGENTS.md +2 -2
  12. package/sdk-core/Cargo.toml +1 -1
  13. package/sdk-core/README.md +5 -5
  14. package/sdk-core/crates/client/src/raw.rs +90 -0
  15. package/sdk-core/crates/client/src/worker/mod.rs +103 -28
  16. package/sdk-core/crates/common/Cargo.toml +1 -1
  17. package/sdk-core/crates/common/protos/api_upstream/.github/workflows/create-release.yml +0 -5
  18. package/sdk-core/crates/common/protos/api_upstream/README.md +8 -0
  19. package/sdk-core/crates/common/protos/api_upstream/buf.yaml +3 -0
  20. package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv2.json +2738 -2452
  21. package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv3.yaml +1657 -124
  22. package/sdk-core/crates/common/protos/api_upstream/temporal/api/activity/v1/message.proto +155 -3
  23. package/sdk-core/crates/common/protos/api_upstream/temporal/api/command/v1/message.proto +26 -0
  24. package/sdk-core/crates/common/protos/api_upstream/temporal/api/common/v1/message.proto +8 -1
  25. package/sdk-core/crates/common/protos/api_upstream/temporal/api/deployment/v1/message.proto +26 -0
  26. package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/activity.proto +81 -0
  27. package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/event_type.proto +4 -0
  28. package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +4 -0
  29. package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +15 -0
  30. package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/workflow.proto +62 -15
  31. package/sdk-core/crates/common/protos/api_upstream/temporal/api/errordetails/v1/message.proto +8 -0
  32. package/sdk-core/crates/common/protos/api_upstream/temporal/api/history/v1/message.proto +107 -17
  33. package/sdk-core/crates/common/protos/api_upstream/temporal/api/namespace/v1/message.proto +15 -0
  34. package/sdk-core/crates/common/protos/api_upstream/temporal/api/nexus/v1/message.proto +4 -0
  35. package/sdk-core/crates/common/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +4 -0
  36. package/sdk-core/crates/common/protos/api_upstream/temporal/api/schedule/v1/message.proto +2 -2
  37. package/sdk-core/crates/common/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +2 -0
  38. package/sdk-core/crates/common/protos/api_upstream/temporal/api/worker/v1/message.proto +4 -7
  39. package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflow/v1/message.proto +80 -22
  40. package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +285 -19
  41. package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +154 -10
  42. package/sdk-core/crates/common/protos/local/temporal/sdk/core/core_interface.proto +15 -0
  43. package/sdk-core/crates/common/protos/local/temporal/sdk/core/nexus/nexus.proto +5 -0
  44. package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +4 -0
  45. package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +17 -0
  46. package/sdk-core/crates/common/src/lib.rs +3 -3
  47. package/sdk-core/crates/common/src/protos/canned_histories.rs +16 -0
  48. package/sdk-core/crates/common/src/protos/mod.rs +12 -0
  49. package/sdk-core/crates/common/src/telemetry/metrics.rs +6 -4
  50. package/sdk-core/crates/common/src/telemetry.rs +14 -15
  51. package/sdk-core/crates/common/src/worker.rs +66 -99
  52. package/sdk-core/crates/common/tests/worker_task_types_test.rs +9 -9
  53. package/sdk-core/crates/sdk/src/lib.rs +10 -8
  54. package/sdk-core/crates/sdk/src/workflow_context/options.rs +19 -0
  55. package/sdk-core/crates/sdk-core/Cargo.toml +2 -1
  56. package/sdk-core/crates/sdk-core/benches/workflow_replay_bench.rs +4 -19
  57. package/sdk-core/crates/sdk-core/src/core_tests/mod.rs +9 -6
  58. package/sdk-core/crates/sdk-core/src/core_tests/workers.rs +166 -13
  59. package/sdk-core/crates/sdk-core/src/core_tests/workflow_tasks.rs +42 -33
  60. package/sdk-core/crates/sdk-core/src/ephemeral_server/mod.rs +6 -9
  61. package/sdk-core/crates/sdk-core/src/lib.rs +20 -13
  62. package/sdk-core/crates/sdk-core/src/pollers/poll_buffer.rs +301 -21
  63. package/sdk-core/crates/sdk-core/src/telemetry/log_export.rs +7 -10
  64. package/sdk-core/crates/sdk-core/src/telemetry/metrics.rs +4 -2
  65. package/sdk-core/crates/sdk-core/src/telemetry/mod.rs +2 -3
  66. package/sdk-core/crates/sdk-core/src/test_help/integ_helpers.rs +30 -8
  67. package/sdk-core/crates/sdk-core/src/worker/activities/activity_heartbeat_manager.rs +1 -0
  68. package/sdk-core/crates/sdk-core/src/worker/client/mocks.rs +3 -1
  69. package/sdk-core/crates/sdk-core/src/worker/client.rs +2 -6
  70. package/sdk-core/crates/sdk-core/src/worker/heartbeat.rs +4 -4
  71. package/sdk-core/crates/sdk-core/src/worker/mod.rs +92 -53
  72. package/sdk-core/crates/sdk-core/src/worker/nexus.rs +5 -0
  73. package/sdk-core/crates/sdk-core/src/worker/tuner/resource_based.rs +12 -14
  74. package/sdk-core/crates/sdk-core/src/worker/tuner.rs +36 -36
  75. package/sdk-core/crates/sdk-core/src/worker/workflow/machines/patch_state_machine.rs +5 -8
  76. package/sdk-core/crates/sdk-core/src/worker/workflow/machines/workflow_machines.rs +12 -1
  77. package/sdk-core/crates/sdk-core/src/worker/workflow/managed_run.rs +6 -23
  78. package/sdk-core/crates/sdk-core/src/worker/workflow/mod.rs +46 -3
  79. package/sdk-core/crates/sdk-core/tests/common/mod.rs +45 -45
  80. package/sdk-core/crates/sdk-core/tests/global_metric_tests.rs +7 -10
  81. package/sdk-core/crates/sdk-core/tests/heavy_tests/fuzzy_workflow.rs +3 -5
  82. package/sdk-core/crates/sdk-core/tests/heavy_tests.rs +34 -42
  83. package/sdk-core/crates/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +21 -26
  84. package/sdk-core/crates/sdk-core/tests/integ_tests/heartbeat_tests.rs +1 -0
  85. package/sdk-core/crates/sdk-core/tests/integ_tests/metrics_tests.rs +147 -72
  86. package/sdk-core/crates/sdk-core/tests/integ_tests/polling_tests.rs +27 -48
  87. package/sdk-core/crates/sdk-core/tests/integ_tests/update_tests.rs +5 -15
  88. package/sdk-core/crates/sdk-core/tests/integ_tests/worker_heartbeat_tests.rs +61 -66
  89. package/sdk-core/crates/sdk-core/tests/integ_tests/worker_tests.rs +16 -14
  90. package/sdk-core/crates/sdk-core/tests/integ_tests/worker_versioning_tests.rs +15 -21
  91. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/activities.rs +16 -19
  92. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +1 -3
  93. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +1 -3
  94. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +4 -12
  95. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +14 -9
  96. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +1 -3
  97. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/eager.rs +2 -6
  98. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +4 -8
  99. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +1 -3
  100. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +11 -13
  101. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/patches.rs +11 -27
  102. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/resets.rs +3 -5
  103. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/signals.rs +4 -12
  104. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +7 -13
  105. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/timers.rs +4 -12
  106. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +1 -3
  107. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests.rs +16 -30
  108. package/sdk-core/crates/sdk-core/tests/main.rs +6 -2
  109. package/sdk-core/crates/sdk-core/tests/manual_tests.rs +40 -49
  110. package/sdk-core/crates/sdk-core/tests/runner.rs +4 -6
  111. package/sdk-core/crates/sdk-core/tests/shared_tests/mod.rs +28 -13
  112. package/sdk-core/crates/sdk-core-c-bridge/Cargo.toml +1 -0
  113. package/sdk-core/crates/sdk-core-c-bridge/include/temporal-sdk-core-c-bridge.h +24 -13
  114. package/sdk-core/crates/sdk-core-c-bridge/src/client.rs +103 -19
  115. package/sdk-core/crates/sdk-core-c-bridge/src/lib.rs +89 -5
  116. package/sdk-core/crates/sdk-core-c-bridge/src/metric.rs +1 -2
  117. package/sdk-core/crates/sdk-core-c-bridge/src/runtime.rs +59 -66
  118. package/sdk-core/crates/sdk-core-c-bridge/src/testing.rs +10 -10
  119. package/sdk-core/crates/sdk-core-c-bridge/src/tests/context.rs +46 -11
  120. package/sdk-core/crates/sdk-core-c-bridge/src/tests/mod.rs +103 -7
  121. package/sdk-core/crates/sdk-core-c-bridge/src/tests/utils.rs +6 -48
  122. package/sdk-core/crates/sdk-core-c-bridge/src/worker.rs +13 -17
  123. package/sdk-core/docker-cgroup-tests.sh +0 -0
  124. package/sdk-core/etc/cargo-tokio-console.sh +0 -0
  125. package/sdk-core/etc/integ-with-otel.sh +0 -0
  126. package/sdk-core/etc/regen-depgraph.sh +0 -0
  127. package/src/client.rs +30 -0
  128. package/src/helpers/try_into_js.rs +88 -2
  129. package/src/metrics.rs +272 -22
  130. package/src/runtime.rs +91 -41
  131. package/src/testing.rs +9 -16
  132. package/src/worker.rs +76 -55
  133. package/ts/native.ts +38 -2
  134. package/LICENSE +0 -21
  135. package/sdk-core/crates/macros/LICENSE.txt +0 -21
@@ -27,6 +27,8 @@ pub struct ByteArrayRef {
27
27
  pub size: libc::size_t,
28
28
  }
29
29
 
30
+ unsafe impl Sync for ByteArrayRef {}
31
+
30
32
  impl ByteArrayRef {
31
33
  pub fn empty() -> ByteArrayRef {
32
34
  static EMPTY: &str = "";
@@ -98,6 +100,24 @@ impl ByteArrayRef {
98
100
  .map(|(k, v)| (k.to_string(), v.to_string()))
99
101
  .collect()
100
102
  }
103
+
104
+ pub fn to_option_str_key_value_pair(&self) -> Option<(&str, ByteArrayRef)> {
105
+ if let Some(index) = self.to_slice().iter().position(|&x| x == b'\n') {
106
+ let key_str = unsafe {
107
+ std::str::from_utf8_unchecked(std::slice::from_raw_parts(self.data, index))
108
+ };
109
+ let value = ByteArrayRef {
110
+ data: unsafe { self.data.add(index + 1) },
111
+ size: self.size - index - 1,
112
+ };
113
+ let _value_str = unsafe {
114
+ std::str::from_utf8_unchecked(std::slice::from_raw_parts(value.data, value.size))
115
+ };
116
+ Some((key_str, value))
117
+ } else {
118
+ None
119
+ }
120
+ }
101
121
  }
102
122
 
103
123
  impl From<&str> for ByteArrayRef {
@@ -118,6 +138,15 @@ impl From<&[u8]> for ByteArrayRef {
118
138
  }
119
139
  }
120
140
 
141
+ impl From<&Vec<u8>> for ByteArrayRef {
142
+ fn from(value: &Vec<u8>) -> ByteArrayRef {
143
+ ByteArrayRef {
144
+ data: value.as_ptr(),
145
+ size: value.len(),
146
+ }
147
+ }
148
+ }
149
+
121
150
  impl<T> From<Option<T>> for ByteArrayRef
122
151
  where
123
152
  T: Into<ByteArrayRef>,
@@ -134,19 +163,74 @@ pub struct ByteArrayRefArray {
134
163
  }
135
164
 
136
165
  impl ByteArrayRefArray {
166
+ pub fn empty() -> ByteArrayRefArray {
167
+ static EMPTY: &[ByteArrayRef] = &[];
168
+ EMPTY.into()
169
+ }
170
+
171
+ pub fn to_slice(&self) -> &[ByteArrayRef] {
172
+ unsafe { std::slice::from_raw_parts(self.data, self.size) }
173
+ }
174
+
137
175
  pub fn to_str_vec(&self) -> Vec<&str> {
138
176
  if self.size == 0 {
139
177
  vec![]
140
178
  } else {
141
- let raw = unsafe { std::slice::from_raw_parts(self.data, self.size) };
142
- raw.iter().map(ByteArrayRef::to_str).collect()
179
+ self.to_slice().iter().map(ByteArrayRef::to_str).collect()
180
+ }
181
+ }
182
+
183
+ fn to_bytearrayref_map_on_newlines(&self) -> HashMap<&str, ByteArrayRef> {
184
+ if self.size == 0 {
185
+ HashMap::new()
186
+ } else {
187
+ self.to_slice()
188
+ .iter()
189
+ .filter_map(ByteArrayRef::to_option_str_key_value_pair)
190
+ .collect()
143
191
  }
144
192
  }
193
+
194
+ pub fn to_string_map_on_newlines(&self) -> HashMap<String, String> {
195
+ self.to_bytearrayref_map_on_newlines()
196
+ .iter()
197
+ .map(|(k, v)| (k.to_string(), v.to_string()))
198
+ .collect()
199
+ }
200
+
201
+ pub fn to_vec_map_on_newlines(&self) -> HashMap<String, Vec<u8>> {
202
+ self.to_bytearrayref_map_on_newlines()
203
+ .iter()
204
+ .map(|(k, v)| (k.to_string(), v.to_vec()))
205
+ .collect()
206
+ }
145
207
  }
146
208
 
147
- /// Metadata is `<key1>\n<value1>\n<key2>\n<value2>`. Metadata keys or
148
- /// values cannot contain a newline within.
149
- pub type MetadataRef = ByteArrayRef;
209
+ impl From<&[ByteArrayRef]> for ByteArrayRefArray {
210
+ fn from(value: &[ByteArrayRef]) -> ByteArrayRefArray {
211
+ ByteArrayRefArray {
212
+ data: value.as_ptr(),
213
+ size: value.len(),
214
+ }
215
+ }
216
+ }
217
+
218
+ impl<T> From<Option<T>> for ByteArrayRefArray
219
+ where
220
+ T: Into<ByteArrayRefArray>,
221
+ {
222
+ fn from(value: Option<T>) -> ByteArrayRefArray {
223
+ value.map(Into::into).unwrap_or(ByteArrayRefArray::empty())
224
+ }
225
+ }
226
+
227
+ /// Each ByteArrayRef is `<key>\n<value>`.
228
+ /// Keys cannot contain a newline.
229
+ pub type MetadataRef = ByteArrayRefArray;
230
+
231
+ /// Data is `<key1>\n<value1>\n<key2>\n<value2>`.
232
+ /// Keys and values cannot contain a newline within.
233
+ pub type NewlineDelimitedMapRef = ByteArrayRef;
150
234
 
151
235
  #[repr(C)]
152
236
  pub struct ByteArray {
@@ -231,12 +231,11 @@ pub extern "C" fn temporal_core_metric_record_duration(
231
231
 
232
232
  impl From<&MetricOptions> for metrics::MetricParameters {
233
233
  fn from(options: &MetricOptions) -> Self {
234
- metrics::MetricParametersBuilder::default()
234
+ metrics::MetricParameters::builder()
235
235
  .name(options.name.to_string())
236
236
  .description(options.description.to_string())
237
237
  .unit(options.unit.to_string())
238
238
  .build()
239
- .unwrap()
240
239
  }
241
240
  }
242
241
 
@@ -1,5 +1,5 @@
1
1
  use crate::{
2
- ByteArray, ByteArrayRef, MetadataRef,
2
+ ByteArray, ByteArrayRef, NewlineDelimitedMapRef,
3
3
  metric::{CustomMetricMeter, CustomMetricMeterRef},
4
4
  };
5
5
 
@@ -17,12 +17,11 @@ use std::{
17
17
  };
18
18
  use temporalio_common::telemetry::{
19
19
  CoreLog, CoreLogConsumer, HistogramBucketOverrides, Logger, MetricTemporality,
20
- OtelCollectorOptionsBuilder, PrometheusExporterOptionsBuilder,
21
- TelemetryOptions as CoreTelemetryOptions, TelemetryOptionsBuilder, metrics::CoreMeter,
20
+ OtelCollectorOptions, PrometheusExporterOptions, TelemetryOptions as CoreTelemetryOptions,
21
+ metrics::CoreMeter,
22
22
  };
23
23
  use temporalio_sdk_core::{
24
- CoreRuntime, RuntimeOptions as CoreRuntimeOptions,
25
- RuntimeOptionsBuilder as CoreRuntimeOptionsBuilder, TokioRuntimeBuilder,
24
+ CoreRuntime, RuntimeOptions as CoreRuntimeOptions, TokioRuntimeBuilder as TokioRuntime,
26
25
  telemetry::{build_otlp_metric_exporter, start_prometheus_metric_exporter},
27
26
  };
28
27
  use tracing::Level;
@@ -76,21 +75,21 @@ pub struct MetricsOptions {
76
75
  pub custom_meter: *const CustomMetricMeter,
77
76
 
78
77
  pub attach_service_name: bool,
79
- pub global_tags: MetadataRef,
78
+ pub global_tags: NewlineDelimitedMapRef,
80
79
  pub metric_prefix: ByteArrayRef,
81
80
  }
82
81
 
83
82
  #[repr(C)]
84
83
  pub struct OpenTelemetryOptions {
85
84
  pub url: ByteArrayRef,
86
- pub headers: MetadataRef,
85
+ pub headers: NewlineDelimitedMapRef,
87
86
  pub metric_periodicity_millis: u32,
88
87
  pub metric_temporality: OpenTelemetryMetricTemporality,
89
88
  pub durations_as_seconds: bool,
90
89
  pub protocol: OpenTelemetryProtocol,
91
90
  /// Histogram bucket overrides in form of
92
91
  /// `<metric1>\n<float>,<float>,<float>\n<metric2>\n<float>,<float>,<float>`
93
- pub histogram_bucket_overrides: MetadataRef,
92
+ pub histogram_bucket_overrides: NewlineDelimitedMapRef,
94
93
  }
95
94
 
96
95
  #[repr(C)]
@@ -113,7 +112,7 @@ pub struct PrometheusOptions {
113
112
  pub durations_as_seconds: bool,
114
113
  /// Histogram bucket overrides in form of
115
114
  /// `<metric1>\n<float>,<float>,<float>\n<metric2>\n<float>,<float>,<float>`
116
- pub histogram_bucket_overrides: MetadataRef,
115
+ pub histogram_bucket_overrides: NewlineDelimitedMapRef,
117
116
  }
118
117
 
119
118
  #[derive(Clone)]
@@ -143,11 +142,8 @@ pub extern "C" fn temporal_core_runtime_new(options: *const RuntimeOptions) -> R
143
142
  // freeable
144
143
  let mut runtime = Runtime {
145
144
  core: Arc::new(
146
- CoreRuntime::new(
147
- CoreRuntimeOptions::default(),
148
- TokioRuntimeBuilder::default(),
149
- )
150
- .unwrap(),
145
+ CoreRuntime::new(CoreRuntimeOptions::default(), TokioRuntime::default())
146
+ .unwrap(),
151
147
  ),
152
148
  log_forwarder: None,
153
149
  };
@@ -207,19 +203,15 @@ impl Runtime {
207
203
  // Build telemetry options
208
204
  let mut log_forwarder = None;
209
205
  let telemetry_options = if let Some(v) = unsafe { options.telemetry.as_ref() } {
210
- let mut build = TelemetryOptionsBuilder::default();
211
-
212
- // Metrics options (note, metrics meter is late-bound later)
213
- if let Some(v) = unsafe { v.metrics.as_ref() } {
214
- build.attach_service_name(v.attach_service_name);
215
- if let Some(metric_prefix) = v.metric_prefix.to_option_string() {
216
- build.metric_prefix(metric_prefix);
217
- }
218
- }
206
+ let (attach_service_name, metric_prefix) =
207
+ if let Some(v) = unsafe { v.metrics.as_ref() } {
208
+ (v.attach_service_name, v.metric_prefix.to_option_string())
209
+ } else {
210
+ (true, None)
211
+ };
219
212
 
220
- // Logging options
221
- if let Some(v) = unsafe { v.logging.as_ref() } {
222
- build.logging(if let Some(callback) = v.forward_to {
213
+ let logging = unsafe { v.logging.as_ref() }.map(|v| {
214
+ if let Some(callback) = v.forward_to {
223
215
  let consumer = Arc::new(LogForwarder {
224
216
  callback,
225
217
  active: AtomicBool::new(false),
@@ -233,28 +225,29 @@ impl Runtime {
233
225
  Logger::Console {
234
226
  filter: v.filter.to_string(),
235
227
  }
236
- });
237
- }
238
- build.build()?
239
- } else {
240
- CoreTelemetryOptions::default()
241
- };
228
+ }
229
+ });
242
230
 
243
- let heartbeat_interval = if options.worker_heartbeat_interval_millis == 0 {
244
- None
231
+ CoreTelemetryOptions::builder()
232
+ .attach_service_name(attach_service_name)
233
+ .maybe_metric_prefix(metric_prefix)
234
+ .maybe_logging(logging)
235
+ .build()
245
236
  } else {
246
- Some(Duration::from_millis(
247
- options.worker_heartbeat_interval_millis,
248
- ))
237
+ CoreTelemetryOptions::default()
249
238
  };
250
239
 
251
- let core_runtime_options = CoreRuntimeOptionsBuilder::default()
240
+ let core_runtime_options = CoreRuntimeOptions::builder()
252
241
  .telemetry_options(telemetry_options)
253
- .heartbeat_interval(heartbeat_interval)
254
- .build()?;
242
+ .heartbeat_interval(
243
+ (options.worker_heartbeat_interval_millis != 0)
244
+ .then(|| Duration::from_millis(options.worker_heartbeat_interval_millis)),
245
+ )
246
+ .build()
247
+ .map_err(|e| anyhow::anyhow!(e))?;
255
248
 
256
249
  // Build core runtime
257
- let mut core = CoreRuntime::new(core_runtime_options, TokioRuntimeBuilder::default())?;
250
+ let mut core = CoreRuntime::new(core_runtime_options, TokioRuntime::default())?;
258
251
 
259
252
  // We late-bind the metrics after core runtime is created since it needs
260
253
  // the Tokio handle
@@ -392,27 +385,28 @@ fn create_meter(
392
385
  ));
393
386
  }
394
387
  // Build OTel exporter
395
- let mut build = OtelCollectorOptionsBuilder::default();
396
- build
397
- .url(Url::parse(otel_options.url.to_str())?)
398
- .headers(otel_options.headers.to_string_map_on_newlines())
399
- .metric_temporality(match otel_options.metric_temporality {
400
- OpenTelemetryMetricTemporality::Cumulative => MetricTemporality::Cumulative,
401
- OpenTelemetryMetricTemporality::Delta => MetricTemporality::Delta,
402
- })
403
- .global_tags(options.global_tags.to_string_map_on_newlines())
404
- .use_seconds_for_durations(otel_options.durations_as_seconds)
405
- .histogram_bucket_overrides(HistogramBucketOverrides {
406
- overrides: parse_histogram_bucket_overrides(
407
- &otel_options.histogram_bucket_overrides,
408
- )?,
409
- });
410
- if otel_options.metric_periodicity_millis > 0 {
411
- build.metric_periodicity(Duration::from_millis(
412
- otel_options.metric_periodicity_millis.into(),
413
- ));
414
- }
415
- Ok(Arc::new(build_otlp_metric_exporter(build.build()?)?))
388
+ Ok(Arc::new(build_otlp_metric_exporter(
389
+ OtelCollectorOptions::builder()
390
+ .url(Url::parse(otel_options.url.to_str())?)
391
+ .headers(otel_options.headers.to_string_map_on_newlines())
392
+ .metric_temporality(match otel_options.metric_temporality {
393
+ OpenTelemetryMetricTemporality::Cumulative => MetricTemporality::Cumulative,
394
+ OpenTelemetryMetricTemporality::Delta => MetricTemporality::Delta,
395
+ })
396
+ .global_tags(options.global_tags.to_string_map_on_newlines())
397
+ .use_seconds_for_durations(otel_options.durations_as_seconds)
398
+ .histogram_bucket_overrides(HistogramBucketOverrides {
399
+ overrides: parse_histogram_bucket_overrides(
400
+ &otel_options.histogram_bucket_overrides,
401
+ )?,
402
+ })
403
+ .maybe_metric_periodicity(
404
+ (otel_options.metric_periodicity_millis > 0).then(|| {
405
+ Duration::from_millis(otel_options.metric_periodicity_millis.into())
406
+ }),
407
+ )
408
+ .build(),
409
+ )?))
416
410
  } else if let Some(prom_options) = unsafe { options.prometheus.as_ref() } {
417
411
  if custom_meter.is_some() {
418
412
  return Err(anyhow::anyhow!(
@@ -420,8 +414,7 @@ fn create_meter(
420
414
  ));
421
415
  }
422
416
  // Start prom exporter
423
- let mut build = PrometheusExporterOptionsBuilder::default();
424
- build
417
+ let build = PrometheusExporterOptions::builder()
425
418
  .socket_addr(SocketAddr::from_str(prom_options.bind_address.to_str())?)
426
419
  .global_tags(options.global_tags.to_string_map_on_newlines())
427
420
  .counters_total_suffix(prom_options.counters_total_suffix)
@@ -432,7 +425,7 @@ fn create_meter(
432
425
  &prom_options.histogram_bucket_overrides,
433
426
  )?,
434
427
  });
435
- Ok(start_prometheus_metric_exporter(build.build()?)?.meter)
428
+ Ok(start_prometheus_metric_exporter(build.build())?.meter)
436
429
  } else if let Some(custom_meter) = custom_meter {
437
430
  Ok(Arc::new(custom_meter))
438
431
  } else {
@@ -443,7 +436,7 @@ fn create_meter(
443
436
  }
444
437
 
445
438
  fn parse_histogram_bucket_overrides(
446
- raw: &MetadataRef,
439
+ raw: &NewlineDelimitedMapRef,
447
440
  ) -> anyhow::Result<HashMap<String, Vec<f64>>> {
448
441
  raw.to_string_map_on_newlines()
449
442
  .into_iter()
@@ -203,24 +203,24 @@ impl TryFrom<&DevServerOptions> for ephemeral_server::TemporalDevServerConfig {
203
203
 
204
204
  fn try_from(options: &DevServerOptions) -> anyhow::Result<Self> {
205
205
  let test_server_options = unsafe { &*options.test_server };
206
- Ok(ephemeral_server::TemporalDevServerConfigBuilder::default()
206
+ Ok(ephemeral_server::TemporalDevServerConfig::builder()
207
207
  .exe(test_server_options.exe())
208
208
  .namespace(options.namespace.to_string())
209
209
  .ip(options.ip.to_string())
210
- .port(test_server_options.port())
211
- .db_filename(options.database_filename.to_option_string())
210
+ .maybe_port(test_server_options.port())
211
+ .maybe_db_filename(options.database_filename.to_option_string())
212
212
  .ui(options.ui)
213
- .ui_port(if options.ui_port == 0 || !options.ui {
214
- None
215
- } else {
213
+ .maybe_ui_port(if options.ui_port != 0 && options.ui {
216
214
  Some(options.ui_port)
215
+ } else {
216
+ None
217
217
  })
218
218
  .log((
219
219
  options.log_format.to_string(),
220
220
  options.log_level.to_string(),
221
221
  ))
222
222
  .extra_args(test_server_options.extra_args())
223
- .build()?)
223
+ .build())
224
224
  }
225
225
  }
226
226
 
@@ -228,11 +228,11 @@ impl TryFrom<&TestServerOptions> for ephemeral_server::TestServerConfig {
228
228
  type Error = anyhow::Error;
229
229
 
230
230
  fn try_from(options: &TestServerOptions) -> anyhow::Result<Self> {
231
- Ok(ephemeral_server::TestServerConfigBuilder::default()
231
+ Ok(ephemeral_server::TestServerConfig::builder()
232
232
  .exe(options.exe())
233
- .port(options.port())
233
+ .maybe_port(options.port())
234
234
  .extra_args(options.extra_args())
235
- .build()?)
235
+ .build())
236
236
  }
237
237
  }
238
238
 
@@ -1,8 +1,8 @@
1
1
  use crate::{
2
2
  client::{
3
3
  Client, ClientHttpConnectProxyOptions, ClientKeepAliveOptions, ClientRetryOptions,
4
- ClientTlsOptions, RpcCallOptions, temporal_core_client_connect, temporal_core_client_free,
5
- temporal_core_client_rpc_call,
4
+ ClientTlsOptions, GrpcMetadataHolder, RpcCallOptions, temporal_core_client_connect,
5
+ temporal_core_client_free, temporal_core_client_rpc_call,
6
6
  },
7
7
  runtime::{
8
8
  Runtime, RuntimeOptions, RuntimeOrFail, temporal_core_byte_array_free,
@@ -17,13 +17,13 @@ use crate::{
17
17
  use crate::{
18
18
  ByteArray, ByteArrayRef,
19
19
  tests::utils::{
20
- MetadataMap, OwnedRpcCallOptions, RpcCallError, byte_array_to_string, byte_array_to_vec,
21
- pointer_or_null,
20
+ OwnedRpcCallOptions, RpcCallError, byte_array_to_string, byte_array_to_vec, pointer_or_null,
22
21
  },
23
22
  };
24
23
  use anyhow::anyhow;
25
24
  use std::{
26
25
  any::Any,
26
+ collections::HashMap,
27
27
  panic::{AssertUnwindSafe, UnwindSafe},
28
28
  ptr::NonNull,
29
29
  sync::{Arc, Condvar, Mutex, MutexGuard, PoisonError, Weak},
@@ -289,10 +289,10 @@ impl Context {
289
289
  grpc_override_callback: crate::client::ClientGrpcOverrideCallback,
290
290
  grpc_override_callback_user_data: *mut libc::c_void,
291
291
  ) -> anyhow::Result<()> {
292
- let metadata = options
293
- .headers
294
- .as_ref()
295
- .map(MetadataMap::serialize_from_map);
292
+ let metadata: Option<GrpcMetadataHolder> = options.headers.as_ref().map(Into::into);
293
+
294
+ let binary_metadata: Option<GrpcMetadataHolder> =
295
+ options.binary_headers.as_ref().map(Into::into);
296
296
 
297
297
  let tls_options = options.tls_options.as_ref().map(|tls_cfg| {
298
298
  let client_tls_cfg = tls_cfg.client_tls_options.as_ref();
@@ -344,7 +344,8 @@ impl Context {
344
344
  target_url: options.target_url.as_str().into(),
345
345
  client_name: options.client_name.as_str().into(),
346
346
  client_version: options.client_version.as_str().into(),
347
- metadata: metadata.as_deref().into(),
347
+ metadata: metadata.as_ref().into(),
348
+ binary_metadata: binary_metadata.as_ref().into(),
348
349
  api_key: options.api_key.as_deref().into(),
349
350
  identity: options.identity.as_str().into(),
350
351
  tls_options: pointer_or_null(tls_options.as_deref()),
@@ -362,6 +363,7 @@ impl Context {
362
363
  _allocations: Box::new((
363
364
  options,
364
365
  metadata,
366
+ binary_metadata,
365
367
  tls_options,
366
368
  retry_options,
367
369
  keep_alive_options,
@@ -390,14 +392,15 @@ impl Context {
390
392
 
391
393
  pub fn rpc_call(
392
394
  self: &Arc<Self>,
393
- mut options: Box<OwnedRpcCallOptions>,
395
+ options: Box<OwnedRpcCallOptions>,
394
396
  ) -> anyhow::Result<Vec<u8>> {
395
397
  let c_options = Box::new(RpcCallOptions {
396
398
  service: options.service,
397
399
  rpc: options.rpc.as_str().into(),
398
400
  req: options.req.as_slice().into(),
399
401
  retry: options.retry,
400
- metadata: options.metadata.as_mut().map(MetadataMap::as_str).into(),
402
+ metadata: options.metadata.as_ref().into(),
403
+ binary_metadata: options.binary_metadata.as_ref().into(),
401
404
  timeout_millis: options.timeout_millis,
402
405
  cancellation_token: options
403
406
  .cancellation_token
@@ -654,3 +657,35 @@ extern "C" fn rpc_call_callback(
654
657
  temporal_core_byte_array_free(std::ptr::null_mut(), failure_details);
655
658
  }
656
659
  }
660
+
661
+ impl From<&HashMap<String, String>> for GrpcMetadataHolder {
662
+ fn from(value: &HashMap<String, String>) -> GrpcMetadataHolder {
663
+ let refs: Vec<Vec<u8>> = value
664
+ .iter()
665
+ .map(|(k, v)| format!("{k}\n{v}").into_bytes())
666
+ .collect();
667
+
668
+ GrpcMetadataHolder {
669
+ data: refs.iter().map(ByteArrayRef::from).collect(),
670
+ _allocations: refs,
671
+ }
672
+ }
673
+ }
674
+
675
+ impl From<&HashMap<String, Vec<u8>>> for GrpcMetadataHolder {
676
+ fn from(value: &HashMap<String, Vec<u8>>) -> GrpcMetadataHolder {
677
+ let refs: Vec<Vec<u8>> = value
678
+ .iter()
679
+ .map(|(k, v)| {
680
+ let mut nv = format!("{k}\n").into_bytes();
681
+ nv.extend(v);
682
+ nv
683
+ })
684
+ .collect();
685
+
686
+ GrpcMetadataHolder {
687
+ data: refs.iter().map(ByteArrayRef::from).collect(),
688
+ _allocations: refs,
689
+ }
690
+ }
691
+ }