@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,682 @@
1
+ use crate::{ByteArrayRef, runtime::Runtime};
2
+ use std::{any::Any, error::Error, sync::Arc, time::Duration};
3
+ use temporal_sdk_core_api::telemetry::metrics;
4
+
5
+ pub struct MetricMeter {
6
+ core: metrics::TemporalMeter,
7
+ }
8
+
9
+ #[unsafe(no_mangle)]
10
+ pub extern "C" fn temporal_core_metric_meter_new(runtime: *mut Runtime) -> *mut MetricMeter {
11
+ let runtime = unsafe { &mut *runtime };
12
+ if let Some(core) = runtime.core.telemetry().get_metric_meter() {
13
+ Box::into_raw(Box::new(MetricMeter { core }))
14
+ } else {
15
+ std::ptr::null_mut()
16
+ }
17
+ }
18
+
19
+ #[unsafe(no_mangle)]
20
+ pub extern "C" fn temporal_core_metric_meter_free(meter: *mut MetricMeter) {
21
+ unsafe {
22
+ let _ = Box::from_raw(meter);
23
+ }
24
+ }
25
+
26
+ pub struct MetricAttributes {
27
+ core: metrics::MetricAttributes,
28
+ }
29
+
30
+ #[repr(C)]
31
+ pub struct MetricAttribute {
32
+ pub key: ByteArrayRef,
33
+ pub value: MetricAttributeValue,
34
+ pub value_type: MetricAttributeValueType,
35
+ }
36
+
37
+ #[repr(C)]
38
+ pub enum MetricAttributeValueType {
39
+ String = 1,
40
+ Int,
41
+ Float,
42
+ Bool,
43
+ }
44
+
45
+ #[repr(C)]
46
+ pub union MetricAttributeValue {
47
+ pub string_value: std::mem::ManuallyDrop<ByteArrayRef>,
48
+ pub int_value: i64,
49
+ pub float_value: f64,
50
+ pub bool_value: bool,
51
+ }
52
+
53
+ #[unsafe(no_mangle)]
54
+ pub extern "C" fn temporal_core_metric_attributes_new(
55
+ meter: *const MetricMeter,
56
+ attrs: *const MetricAttribute,
57
+ size: libc::size_t,
58
+ ) -> *mut MetricAttributes {
59
+ let meter = unsafe { &*meter };
60
+ let orig = meter
61
+ .core
62
+ .inner
63
+ .new_attributes(meter.core.default_attribs.clone());
64
+ Box::into_raw(Box::new(metric_attributes_append(
65
+ meter, &orig, attrs, size,
66
+ )))
67
+ }
68
+
69
+ #[unsafe(no_mangle)]
70
+ pub extern "C" fn temporal_core_metric_attributes_new_append(
71
+ meter: *const MetricMeter,
72
+ orig: *const MetricAttributes,
73
+ attrs: *const MetricAttribute,
74
+ size: libc::size_t,
75
+ ) -> *mut MetricAttributes {
76
+ let meter = unsafe { &*meter };
77
+ let orig = unsafe { &*orig };
78
+ Box::into_raw(Box::new(metric_attributes_append(
79
+ meter, &orig.core, attrs, size,
80
+ )))
81
+ }
82
+
83
+ #[unsafe(no_mangle)]
84
+ pub extern "C" fn temporal_core_metric_attributes_free(attrs: *mut MetricAttributes) {
85
+ unsafe {
86
+ let _ = Box::from_raw(attrs);
87
+ }
88
+ }
89
+
90
+ fn metric_attributes_append(
91
+ meter: &MetricMeter,
92
+ orig: &metrics::MetricAttributes,
93
+ attrs: *const MetricAttribute,
94
+ size: libc::size_t,
95
+ ) -> MetricAttributes {
96
+ let attrs = unsafe { std::slice::from_raw_parts(attrs, size) };
97
+ let core = meter.core.inner.extend_attributes(
98
+ orig.clone(),
99
+ metrics::NewAttributes {
100
+ attributes: attrs.iter().map(metric_attribute_to_key_value).collect(),
101
+ },
102
+ );
103
+ MetricAttributes { core }
104
+ }
105
+
106
+ fn metric_attribute_to_key_value(attr: &MetricAttribute) -> metrics::MetricKeyValue {
107
+ metrics::MetricKeyValue {
108
+ key: attr.key.to_string(),
109
+ value: match attr.value_type {
110
+ MetricAttributeValueType::String => {
111
+ metrics::MetricValue::String(unsafe { attr.value.string_value.to_string() })
112
+ }
113
+ MetricAttributeValueType::Int => {
114
+ metrics::MetricValue::Int(unsafe { attr.value.int_value })
115
+ }
116
+ MetricAttributeValueType::Float => {
117
+ metrics::MetricValue::Float(unsafe { attr.value.float_value })
118
+ }
119
+ MetricAttributeValueType::Bool => {
120
+ metrics::MetricValue::Bool(unsafe { attr.value.bool_value })
121
+ }
122
+ },
123
+ }
124
+ }
125
+
126
+ #[repr(C)]
127
+ pub struct MetricOptions {
128
+ pub name: ByteArrayRef,
129
+ pub description: ByteArrayRef,
130
+ pub unit: ByteArrayRef,
131
+ pub kind: MetricKind,
132
+ }
133
+
134
+ #[repr(C)]
135
+ pub enum MetricKind {
136
+ CounterInteger = 1,
137
+ HistogramInteger,
138
+ HistogramFloat,
139
+ HistogramDuration,
140
+ GaugeInteger,
141
+ GaugeFloat,
142
+ }
143
+
144
+ pub enum Metric {
145
+ CounterInteger(metrics::Counter),
146
+ HistogramInteger(metrics::Histogram),
147
+ HistogramFloat(metrics::HistogramF64),
148
+ HistogramDuration(metrics::HistogramDuration),
149
+ GaugeInteger(metrics::Gauge),
150
+ GaugeFloat(metrics::GaugeF64),
151
+ }
152
+
153
+ #[unsafe(no_mangle)]
154
+ pub extern "C" fn temporal_core_metric_new(
155
+ meter: *const MetricMeter,
156
+ options: *const MetricOptions,
157
+ ) -> *mut Metric {
158
+ let meter = unsafe { &*meter };
159
+ let options = unsafe { &*options };
160
+ Box::into_raw(Box::new(match options.kind {
161
+ MetricKind::CounterInteger => {
162
+ Metric::CounterInteger(meter.core.inner.counter(options.into()))
163
+ }
164
+ MetricKind::HistogramInteger => {
165
+ Metric::HistogramInteger(meter.core.inner.histogram(options.into()))
166
+ }
167
+ MetricKind::HistogramFloat => {
168
+ Metric::HistogramFloat(meter.core.inner.histogram_f64(options.into()))
169
+ }
170
+ MetricKind::HistogramDuration => {
171
+ Metric::HistogramDuration(meter.core.inner.histogram_duration(options.into()))
172
+ }
173
+ MetricKind::GaugeInteger => Metric::GaugeInteger(meter.core.inner.gauge(options.into())),
174
+ MetricKind::GaugeFloat => Metric::GaugeFloat(meter.core.inner.gauge_f64(options.into())),
175
+ }))
176
+ }
177
+
178
+ #[unsafe(no_mangle)]
179
+ pub extern "C" fn temporal_core_metric_free(metric: *mut Metric) {
180
+ unsafe {
181
+ let _ = Box::from_raw(metric);
182
+ }
183
+ }
184
+
185
+ #[unsafe(no_mangle)]
186
+ pub extern "C" fn temporal_core_metric_record_integer(
187
+ metric: *const Metric,
188
+ value: u64,
189
+ attrs: *const MetricAttributes,
190
+ ) {
191
+ let metric = unsafe { &*metric };
192
+ let attrs = unsafe { &*attrs };
193
+ match metric {
194
+ Metric::CounterInteger(counter) => counter.add(value, &attrs.core),
195
+ Metric::HistogramInteger(histogram) => histogram.record(value, &attrs.core),
196
+ Metric::GaugeInteger(gauge) => gauge.record(value, &attrs.core),
197
+ _ => panic!("Not an integer type"),
198
+ }
199
+ }
200
+
201
+ #[unsafe(no_mangle)]
202
+ pub extern "C" fn temporal_core_metric_record_float(
203
+ metric: *const Metric,
204
+ value: f64,
205
+ attrs: *const MetricAttributes,
206
+ ) {
207
+ let metric = unsafe { &*metric };
208
+ let attrs = unsafe { &*attrs };
209
+ match metric {
210
+ Metric::HistogramFloat(histogram) => histogram.record(value, &attrs.core),
211
+ Metric::GaugeFloat(gauge) => gauge.record(value, &attrs.core),
212
+ _ => panic!("Not a float type"),
213
+ }
214
+ }
215
+
216
+ #[unsafe(no_mangle)]
217
+ pub extern "C" fn temporal_core_metric_record_duration(
218
+ metric: *const Metric,
219
+ value_ms: u64,
220
+ attrs: *const MetricAttributes,
221
+ ) {
222
+ let metric = unsafe { &*metric };
223
+ let attrs = unsafe { &*attrs };
224
+ match metric {
225
+ Metric::HistogramDuration(histogram) => {
226
+ histogram.record(Duration::from_millis(value_ms), &attrs.core)
227
+ }
228
+ _ => panic!("Not a duration type"),
229
+ }
230
+ }
231
+
232
+ impl From<&MetricOptions> for metrics::MetricParameters {
233
+ fn from(options: &MetricOptions) -> Self {
234
+ metrics::MetricParametersBuilder::default()
235
+ .name(options.name.to_string())
236
+ .description(options.description.to_string())
237
+ .unit(options.unit.to_string())
238
+ .build()
239
+ .unwrap()
240
+ }
241
+ }
242
+
243
+ pub type CustomMetricMeterMetricNewCallback = unsafe extern "C" fn(
244
+ name: ByteArrayRef,
245
+ description: ByteArrayRef,
246
+ unit: ByteArrayRef,
247
+ kind: MetricKind,
248
+ ) -> *const libc::c_void;
249
+
250
+ pub type CustomMetricMeterMetricFreeCallback = unsafe extern "C" fn(metric: *const libc::c_void);
251
+
252
+ pub type CustomMetricMeterMetricRecordIntegerCallback =
253
+ unsafe extern "C" fn(metric: *const libc::c_void, value: u64, attributes: *const libc::c_void);
254
+
255
+ pub type CustomMetricMeterMetricRecordFloatCallback =
256
+ unsafe extern "C" fn(metric: *const libc::c_void, value: f64, attributes: *const libc::c_void);
257
+
258
+ pub type CustomMetricMeterMetricRecordDurationCallback = unsafe extern "C" fn(
259
+ metric: *const libc::c_void,
260
+ value_ms: u64,
261
+ attributes: *const libc::c_void,
262
+ );
263
+
264
+ pub type CustomMetricMeterAttributesNewCallback = unsafe extern "C" fn(
265
+ append_from: *const libc::c_void,
266
+ attributes: *const CustomMetricAttribute,
267
+ attributes_size: libc::size_t,
268
+ ) -> *const libc::c_void;
269
+
270
+ pub type CustomMetricMeterAttributesFreeCallback =
271
+ unsafe extern "C" fn(attributes: *const libc::c_void);
272
+
273
+ pub type CustomMetricMeterMeterFreeCallback = unsafe extern "C" fn(meter: *const CustomMetricMeter);
274
+
275
+ /// No parameters in the callbacks below should be assumed to live beyond the
276
+ /// callbacks unless they are pointers to things that were created lang-side
277
+ /// originally. There are no guarantees on which thread these calls may be
278
+ /// invoked on.
279
+ ///
280
+ /// Attribute pointers may be null when recording if no attributes are associated with the metric.
281
+ #[repr(C)]
282
+ pub struct CustomMetricMeter {
283
+ pub metric_new: CustomMetricMeterMetricNewCallback,
284
+ pub metric_free: CustomMetricMeterMetricFreeCallback,
285
+ pub metric_record_integer: CustomMetricMeterMetricRecordIntegerCallback,
286
+ pub metric_record_float: CustomMetricMeterMetricRecordFloatCallback,
287
+ pub metric_record_duration: CustomMetricMeterMetricRecordDurationCallback,
288
+ pub attributes_new: CustomMetricMeterAttributesNewCallback,
289
+ pub attributes_free: CustomMetricMeterAttributesFreeCallback,
290
+ pub meter_free: CustomMetricMeterMeterFreeCallback,
291
+ }
292
+
293
+ #[repr(C)]
294
+ pub struct CustomMetricAttribute {
295
+ pub key: ByteArrayRef,
296
+ pub value: CustomMetricAttributeValue,
297
+ pub value_type: MetricAttributeValueType,
298
+ }
299
+
300
+ #[repr(C)]
301
+ pub union CustomMetricAttributeValue {
302
+ pub string_value: CustomMetricAttributeValueString,
303
+ pub int_value: i64,
304
+ pub float_value: f64,
305
+ pub bool_value: bool,
306
+ }
307
+
308
+ // We create this type because we want it to implement Copy
309
+ #[repr(C)]
310
+ #[derive(Copy, Clone)]
311
+ pub struct CustomMetricAttributeValueString {
312
+ pub data: *const u8,
313
+ pub size: libc::size_t,
314
+ }
315
+
316
+ #[derive(Debug)]
317
+ pub struct CustomMetricMeterRef {
318
+ meter_impl: Arc<CustomMetricMeterImpl>,
319
+ }
320
+
321
+ unsafe impl Send for CustomMetricMeterRef {}
322
+ unsafe impl Sync for CustomMetricMeterRef {}
323
+
324
+ impl metrics::CoreMeter for CustomMetricMeterRef {
325
+ fn new_attributes(&self, attribs: metrics::NewAttributes) -> metrics::MetricAttributes {
326
+ self.build_attributes(None, attribs)
327
+ }
328
+
329
+ fn extend_attributes(
330
+ &self,
331
+ existing: metrics::MetricAttributes,
332
+ attribs: metrics::NewAttributes,
333
+ ) -> metrics::MetricAttributes {
334
+ self.build_attributes(Some(existing), attribs)
335
+ }
336
+
337
+ fn counter(&self, params: metrics::MetricParameters) -> metrics::Counter {
338
+ metrics::Counter::new(Arc::new(
339
+ self.new_metric(params, MetricKind::CounterInteger),
340
+ ))
341
+ }
342
+
343
+ fn histogram(&self, params: metrics::MetricParameters) -> metrics::Histogram {
344
+ metrics::Histogram::new(Arc::new(
345
+ self.new_metric(params, MetricKind::HistogramInteger),
346
+ ))
347
+ }
348
+
349
+ fn histogram_f64(&self, params: metrics::MetricParameters) -> metrics::HistogramF64 {
350
+ metrics::HistogramF64::new(Arc::new(
351
+ self.new_metric(params, MetricKind::HistogramFloat),
352
+ ))
353
+ }
354
+
355
+ fn histogram_duration(&self, params: metrics::MetricParameters) -> metrics::HistogramDuration {
356
+ metrics::HistogramDuration::new(Arc::new(
357
+ self.new_metric(params, MetricKind::HistogramDuration),
358
+ ))
359
+ }
360
+
361
+ fn gauge(&self, params: metrics::MetricParameters) -> metrics::Gauge {
362
+ metrics::Gauge::new(Arc::new(self.new_metric(params, MetricKind::GaugeInteger)))
363
+ }
364
+
365
+ fn gauge_f64(&self, params: metrics::MetricParameters) -> metrics::GaugeF64 {
366
+ metrics::GaugeF64::new(Arc::new(self.new_metric(params, MetricKind::GaugeFloat)))
367
+ }
368
+ }
369
+
370
+ impl CustomMetricMeterRef {
371
+ pub fn new(meter: *const CustomMetricMeter) -> CustomMetricMeterRef {
372
+ CustomMetricMeterRef {
373
+ meter_impl: Arc::new(CustomMetricMeterImpl(meter)),
374
+ }
375
+ }
376
+
377
+ fn build_attributes(
378
+ &self,
379
+ append_from: Option<metrics::MetricAttributes>,
380
+ attribs: metrics::NewAttributes,
381
+ ) -> metrics::MetricAttributes {
382
+ unsafe {
383
+ let meter = &*(self.meter_impl.0);
384
+ let append_from = match append_from {
385
+ Some(metrics::MetricAttributes::Dynamic(v)) => {
386
+ v.clone()
387
+ .as_any()
388
+ .downcast::<CustomMetricAttributes>()
389
+ .expect("Attributes not CustomMetricAttributes as expected")
390
+ .attributes
391
+ }
392
+ _ => std::ptr::null(),
393
+ };
394
+ // Build a set of CustomMetricAttributes with _references_ to the
395
+ // pieces in attribs. We count on both this vec and the attribs vec
396
+ // living beyond the callback invocation.
397
+ let attrs: Vec<CustomMetricAttribute> = attribs
398
+ .attributes
399
+ .iter()
400
+ .map(|kv| {
401
+ let (value, value_type) = match kv.value {
402
+ metrics::MetricValue::String(ref v) => (
403
+ CustomMetricAttributeValue {
404
+ string_value: CustomMetricAttributeValueString {
405
+ data: v.as_ptr(),
406
+ size: v.len(),
407
+ },
408
+ },
409
+ MetricAttributeValueType::String,
410
+ ),
411
+ metrics::MetricValue::Int(v) => (
412
+ CustomMetricAttributeValue { int_value: v },
413
+ MetricAttributeValueType::Int,
414
+ ),
415
+ metrics::MetricValue::Float(v) => (
416
+ CustomMetricAttributeValue { float_value: v },
417
+ MetricAttributeValueType::Float,
418
+ ),
419
+ metrics::MetricValue::Bool(v) => (
420
+ CustomMetricAttributeValue { bool_value: v },
421
+ MetricAttributeValueType::Bool,
422
+ ),
423
+ };
424
+ CustomMetricAttribute {
425
+ key: kv.key.as_str().into(),
426
+ value,
427
+ value_type,
428
+ }
429
+ })
430
+ .collect();
431
+ let raw_attrs = (meter.attributes_new)(append_from, attrs.as_ptr(), attrs.len());
432
+ // This is just to confirm we don't move the attribute by accident
433
+ // above before the callback is called
434
+ let _ = attribs;
435
+ metrics::MetricAttributes::Dynamic(Arc::new(CustomMetricAttributes {
436
+ meter_impl: self.meter_impl.clone(),
437
+ attributes: raw_attrs,
438
+ }))
439
+ }
440
+ }
441
+
442
+ fn new_metric(&self, params: metrics::MetricParameters, kind: MetricKind) -> CustomMetric {
443
+ unsafe {
444
+ let meter = &*(self.meter_impl.0);
445
+ let metric = (meter.metric_new)(
446
+ params.name.as_ref().into(),
447
+ params.description.as_ref().into(),
448
+ params.unit.as_ref().into(),
449
+ kind,
450
+ );
451
+ // Ignore this lint because we want to refcount the pointer
452
+ #[allow(clippy::arc_with_non_send_sync)]
453
+ CustomMetric {
454
+ meter_impl: self.meter_impl.clone(),
455
+ metric: Arc::new(metric),
456
+ bound_attributes: None,
457
+ }
458
+ }
459
+ }
460
+ }
461
+
462
+ // Needed so we can have a drop impl
463
+ #[derive(Debug)]
464
+ struct CustomMetricMeterImpl(*const CustomMetricMeter);
465
+
466
+ unsafe impl Send for CustomMetricMeterImpl {}
467
+ unsafe impl Sync for CustomMetricMeterImpl {}
468
+
469
+ impl Drop for CustomMetricMeterImpl {
470
+ fn drop(&mut self) {
471
+ unsafe {
472
+ let meter = &*(self.0);
473
+ (meter.meter_free)(self.0);
474
+ }
475
+ }
476
+ }
477
+
478
+ #[derive(Debug)]
479
+ struct CustomMetricAttributes {
480
+ meter_impl: Arc<CustomMetricMeterImpl>,
481
+ attributes: *const libc::c_void,
482
+ }
483
+
484
+ unsafe impl Send for CustomMetricAttributes {}
485
+ unsafe impl Sync for CustomMetricAttributes {}
486
+
487
+ impl metrics::CustomMetricAttributes for CustomMetricAttributes {
488
+ fn as_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync> {
489
+ self as Arc<dyn Any + Send + Sync>
490
+ }
491
+ }
492
+
493
+ impl Drop for CustomMetricAttributes {
494
+ fn drop(&mut self) {
495
+ unsafe {
496
+ let meter = &*(self.meter_impl.0);
497
+ (meter.attributes_free)(self.attributes);
498
+ }
499
+ }
500
+ }
501
+
502
+ struct CustomMetric {
503
+ meter_impl: Arc<CustomMetricMeterImpl>,
504
+ metric: Arc<*const libc::c_void>,
505
+ bound_attributes: Option<metrics::MetricAttributes>,
506
+ }
507
+ impl CustomMetric {
508
+ fn attr_ptr(&self) -> *const libc::c_void {
509
+ match &self.bound_attributes {
510
+ Some(ptr) => raw_custom_metric_attributes(ptr),
511
+ None => std::ptr::null(),
512
+ }
513
+ }
514
+ }
515
+
516
+ unsafe impl Send for CustomMetric {}
517
+ unsafe impl Sync for CustomMetric {}
518
+
519
+ impl metrics::MetricAttributable<Box<dyn metrics::CounterBase>> for CustomMetric {
520
+ fn with_attributes(
521
+ &self,
522
+ atts: &metrics::MetricAttributes,
523
+ ) -> Result<Box<dyn metrics::CounterBase>, Box<dyn Error>> {
524
+ Ok(Box::new(CustomMetric {
525
+ meter_impl: self.meter_impl.clone(),
526
+ metric: self.metric.clone(),
527
+ bound_attributes: Some(atts.clone()),
528
+ }))
529
+ }
530
+ }
531
+
532
+ impl metrics::CounterBase for CustomMetric {
533
+ fn adds(&self, value: u64) {
534
+ unsafe {
535
+ let meter = &*(self.meter_impl.0);
536
+ let attr_ptr = self.attr_ptr();
537
+ (meter.metric_record_integer)(*self.metric, value, attr_ptr);
538
+ }
539
+ }
540
+ }
541
+
542
+ impl metrics::MetricAttributable<Box<dyn metrics::HistogramBase>> for CustomMetric {
543
+ fn with_attributes(
544
+ &self,
545
+ atts: &metrics::MetricAttributes,
546
+ ) -> Result<Box<dyn metrics::HistogramBase>, Box<dyn Error>> {
547
+ Ok(Box::new(CustomMetric {
548
+ meter_impl: self.meter_impl.clone(),
549
+ metric: self.metric.clone(),
550
+ bound_attributes: Some(atts.clone()),
551
+ }))
552
+ }
553
+ }
554
+
555
+ impl metrics::HistogramBase for CustomMetric {
556
+ fn records(&self, value: u64) {
557
+ unsafe {
558
+ let meter = &*(self.meter_impl.0);
559
+ let attr_ptr = self.attr_ptr();
560
+ (meter.metric_record_integer)(*self.metric, value, attr_ptr);
561
+ }
562
+ }
563
+ }
564
+
565
+ impl metrics::MetricAttributable<Box<dyn metrics::HistogramF64Base>> for CustomMetric {
566
+ fn with_attributes(
567
+ &self,
568
+ atts: &metrics::MetricAttributes,
569
+ ) -> Result<Box<dyn metrics::HistogramF64Base>, Box<dyn Error>> {
570
+ Ok(Box::new(CustomMetric {
571
+ meter_impl: self.meter_impl.clone(),
572
+ metric: self.metric.clone(),
573
+ bound_attributes: Some(atts.clone()),
574
+ }))
575
+ }
576
+ }
577
+
578
+ impl metrics::HistogramF64Base for CustomMetric {
579
+ fn records(&self, value: f64) {
580
+ unsafe {
581
+ let meter = &*(self.meter_impl.0);
582
+ let attr_ptr = self.attr_ptr();
583
+ (meter.metric_record_float)(*self.metric, value, attr_ptr);
584
+ }
585
+ }
586
+ }
587
+
588
+ impl metrics::MetricAttributable<Box<dyn metrics::HistogramDurationBase>> for CustomMetric {
589
+ fn with_attributes(
590
+ &self,
591
+ atts: &metrics::MetricAttributes,
592
+ ) -> Result<Box<dyn metrics::HistogramDurationBase>, Box<dyn Error>> {
593
+ Ok(Box::new(CustomMetric {
594
+ meter_impl: self.meter_impl.clone(),
595
+ metric: self.metric.clone(),
596
+ bound_attributes: Some(atts.clone()),
597
+ }))
598
+ }
599
+ }
600
+
601
+ impl metrics::HistogramDurationBase for CustomMetric {
602
+ fn records(&self, value: Duration) {
603
+ unsafe {
604
+ let meter = &*(self.meter_impl.0);
605
+ let attr_ptr = self.attr_ptr();
606
+ (meter.metric_record_duration)(
607
+ *self.metric,
608
+ value.as_millis().try_into().unwrap_or(u64::MAX),
609
+ attr_ptr,
610
+ );
611
+ }
612
+ }
613
+ }
614
+
615
+ impl metrics::MetricAttributable<Box<dyn metrics::GaugeBase>> for CustomMetric {
616
+ fn with_attributes(
617
+ &self,
618
+ atts: &metrics::MetricAttributes,
619
+ ) -> Result<Box<dyn metrics::GaugeBase>, Box<dyn Error>> {
620
+ Ok(Box::new(CustomMetric {
621
+ meter_impl: self.meter_impl.clone(),
622
+ metric: self.metric.clone(),
623
+ bound_attributes: Some(atts.clone()),
624
+ }))
625
+ }
626
+ }
627
+
628
+ impl metrics::GaugeBase for CustomMetric {
629
+ fn records(&self, value: u64) {
630
+ unsafe {
631
+ let meter = &*(self.meter_impl.0);
632
+ let attr_ptr = self.attr_ptr();
633
+ (meter.metric_record_integer)(*self.metric, value, attr_ptr);
634
+ }
635
+ }
636
+ }
637
+
638
+ impl metrics::MetricAttributable<Box<dyn metrics::GaugeF64Base>> for CustomMetric {
639
+ fn with_attributes(
640
+ &self,
641
+ atts: &metrics::MetricAttributes,
642
+ ) -> Result<Box<dyn metrics::GaugeF64Base>, Box<dyn Error>> {
643
+ Ok(Box::new(CustomMetric {
644
+ meter_impl: self.meter_impl.clone(),
645
+ metric: self.metric.clone(),
646
+ bound_attributes: Some(atts.clone()),
647
+ }))
648
+ }
649
+ }
650
+
651
+ impl metrics::GaugeF64Base for CustomMetric {
652
+ fn records(&self, value: f64) {
653
+ unsafe {
654
+ let meter = &*(self.meter_impl.0);
655
+ let attr_ptr = self.attr_ptr();
656
+ (meter.metric_record_float)(*self.metric, value, attr_ptr);
657
+ }
658
+ }
659
+ }
660
+
661
+ fn raw_custom_metric_attributes(attributes: &metrics::MetricAttributes) -> *const libc::c_void {
662
+ if let metrics::MetricAttributes::Dynamic(v) = attributes {
663
+ v.clone()
664
+ .as_any()
665
+ .downcast::<CustomMetricAttributes>()
666
+ .expect("Attributes not CustomMetricAttributes as expected")
667
+ .attributes
668
+ } else {
669
+ panic!("Unexpected attribute type")
670
+ }
671
+ }
672
+
673
+ impl Drop for CustomMetric {
674
+ fn drop(&mut self) {
675
+ unsafe {
676
+ let meter = &*(self.meter_impl.0);
677
+ if let Some(mptr) = Arc::get_mut(&mut self.metric) {
678
+ (meter.metric_free)(*mptr);
679
+ }
680
+ }
681
+ }
682
+ }