@temporalio/core-bridge 1.15.0 → 1.16.1

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 (209) hide show
  1. package/Cargo.lock +172 -70
  2. package/lib/native.d.ts +1 -1
  3. package/package.json +2 -2
  4. package/releases/aarch64-apple-darwin/index.node +0 -0
  5. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  6. package/releases/x86_64-apple-darwin/index.node +0 -0
  7. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  8. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  9. package/sdk-core/.github/workflows/per-pr.yml +6 -6
  10. package/sdk-core/AGENTS.md +41 -30
  11. package/sdk-core/Cargo.toml +3 -0
  12. package/sdk-core/README.md +15 -9
  13. package/sdk-core/crates/client/Cargo.toml +4 -0
  14. package/sdk-core/crates/client/README.md +139 -0
  15. package/sdk-core/crates/client/src/async_activity_handle.rs +297 -0
  16. package/sdk-core/crates/client/src/callback_based.rs +7 -0
  17. package/sdk-core/crates/client/src/errors.rs +294 -0
  18. package/sdk-core/crates/client/src/{raw.rs → grpc.rs} +280 -159
  19. package/sdk-core/crates/client/src/lib.rs +920 -1326
  20. package/sdk-core/crates/client/src/metrics.rs +24 -33
  21. package/sdk-core/crates/client/src/options_structs.rs +457 -0
  22. package/sdk-core/crates/client/src/replaceable.rs +5 -4
  23. package/sdk-core/crates/client/src/request_extensions.rs +8 -9
  24. package/sdk-core/crates/client/src/retry.rs +99 -54
  25. package/sdk-core/crates/client/src/{worker/mod.rs → worker.rs} +1 -1
  26. package/sdk-core/crates/client/src/workflow_handle.rs +826 -0
  27. package/sdk-core/crates/common/Cargo.toml +61 -2
  28. package/sdk-core/crates/common/build.rs +742 -12
  29. package/sdk-core/crates/common/protos/api_upstream/.github/workflows/ci.yml +2 -0
  30. package/sdk-core/crates/common/protos/api_upstream/Makefile +2 -1
  31. package/sdk-core/crates/common/protos/api_upstream/buf.yaml +0 -3
  32. package/sdk-core/crates/common/protos/api_upstream/cmd/check-path-conflicts/main.go +137 -0
  33. package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv2.json +1166 -770
  34. package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv3.yaml +1243 -750
  35. package/sdk-core/crates/common/protos/api_upstream/temporal/api/deployment/v1/message.proto +2 -2
  36. package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/workflow.proto +4 -3
  37. package/sdk-core/crates/common/protos/api_upstream/temporal/api/failure/v1/message.proto +1 -0
  38. package/sdk-core/crates/common/protos/api_upstream/temporal/api/history/v1/message.proto +4 -0
  39. package/sdk-core/crates/common/protos/api_upstream/temporal/api/namespace/v1/message.proto +6 -0
  40. package/sdk-core/crates/common/protos/api_upstream/temporal/api/nexus/v1/message.proto +16 -1
  41. package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +64 -6
  42. package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +88 -33
  43. package/sdk-core/crates/common/protos/local/temporal/sdk/core/nexus/nexus.proto +4 -2
  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 +5 -5
  46. package/sdk-core/crates/common/src/activity_definition.rs +20 -0
  47. package/sdk-core/crates/common/src/data_converters.rs +770 -0
  48. package/sdk-core/crates/common/src/envconfig.rs +5 -0
  49. package/sdk-core/crates/common/src/lib.rs +15 -211
  50. package/sdk-core/crates/common/src/payload_visitor.rs +648 -0
  51. package/sdk-core/crates/common/src/priority.rs +110 -0
  52. package/sdk-core/crates/common/src/protos/canned_histories.rs +3 -0
  53. package/sdk-core/crates/common/src/protos/history_builder.rs +45 -0
  54. package/sdk-core/crates/common/src/protos/history_info.rs +2 -0
  55. package/sdk-core/crates/common/src/protos/mod.rs +122 -27
  56. package/sdk-core/crates/common/src/protos/task_token.rs +3 -3
  57. package/sdk-core/crates/common/src/protos/utilities.rs +11 -0
  58. package/sdk-core/crates/{sdk-core → common}/src/telemetry/log_export.rs +5 -7
  59. package/sdk-core/crates/common/src/telemetry/metrics/core.rs +125 -0
  60. package/sdk-core/crates/common/src/telemetry/metrics.rs +268 -223
  61. package/sdk-core/crates/{sdk-core → common}/src/telemetry/otel.rs +8 -13
  62. package/sdk-core/crates/{sdk-core → common}/src/telemetry/prometheus_meter.rs +49 -50
  63. package/sdk-core/crates/{sdk-core → common}/src/telemetry/prometheus_server.rs +2 -3
  64. package/sdk-core/crates/common/src/telemetry.rs +264 -4
  65. package/sdk-core/crates/common/src/worker.rs +68 -603
  66. package/sdk-core/crates/common/src/workflow_definition.rs +60 -0
  67. package/sdk-core/crates/macros/Cargo.toml +5 -1
  68. package/sdk-core/crates/macros/src/activities_definitions.rs +585 -0
  69. package/sdk-core/crates/macros/src/fsm_impl.rs +507 -0
  70. package/sdk-core/crates/macros/src/lib.rs +138 -512
  71. package/sdk-core/crates/macros/src/macro_utils.rs +106 -0
  72. package/sdk-core/crates/macros/src/workflow_definitions.rs +1224 -0
  73. package/sdk-core/crates/sdk/Cargo.toml +19 -6
  74. package/sdk-core/crates/sdk/README.md +415 -0
  75. package/sdk-core/crates/sdk/src/activities.rs +417 -0
  76. package/sdk-core/crates/sdk/src/interceptors.rs +1 -1
  77. package/sdk-core/crates/sdk/src/lib.rs +757 -442
  78. package/sdk-core/crates/sdk/src/workflow_context/options.rs +45 -35
  79. package/sdk-core/crates/sdk/src/workflow_context.rs +1033 -289
  80. package/sdk-core/crates/sdk/src/workflow_future.rs +277 -213
  81. package/sdk-core/crates/sdk/src/workflows.rs +711 -0
  82. package/sdk-core/crates/sdk-core/Cargo.toml +57 -64
  83. package/sdk-core/crates/sdk-core/benches/workflow_replay_bench.rs +41 -35
  84. package/sdk-core/crates/sdk-core/machine_coverage/ActivityMachine_Coverage.puml +1 -1
  85. package/sdk-core/crates/sdk-core/src/abstractions.rs +6 -10
  86. package/sdk-core/crates/sdk-core/src/core_tests/activity_tasks.rs +6 -5
  87. package/sdk-core/crates/sdk-core/src/core_tests/mod.rs +13 -15
  88. package/sdk-core/crates/sdk-core/src/core_tests/queries.rs +21 -25
  89. package/sdk-core/crates/sdk-core/src/core_tests/replay_flag.rs +7 -10
  90. package/sdk-core/crates/sdk-core/src/core_tests/updates.rs +14 -17
  91. package/sdk-core/crates/sdk-core/src/core_tests/workers.rs +493 -26
  92. package/sdk-core/crates/sdk-core/src/core_tests/workflow_tasks.rs +4 -8
  93. package/sdk-core/crates/sdk-core/src/ephemeral_server/mod.rs +7 -7
  94. package/sdk-core/crates/sdk-core/src/histfetch.rs +20 -10
  95. package/sdk-core/crates/sdk-core/src/lib.rs +41 -111
  96. package/sdk-core/crates/sdk-core/src/pollers/mod.rs +4 -9
  97. package/sdk-core/crates/sdk-core/src/pollers/poll_buffer.rs +118 -19
  98. package/sdk-core/crates/sdk-core/src/protosext/mod.rs +2 -2
  99. package/sdk-core/crates/sdk-core/src/replay/mod.rs +14 -5
  100. package/sdk-core/crates/sdk-core/src/telemetry/metrics.rs +179 -196
  101. package/sdk-core/crates/sdk-core/src/telemetry/mod.rs +3 -280
  102. package/sdk-core/crates/sdk-core/src/test_help/integ_helpers.rs +6 -9
  103. package/sdk-core/crates/sdk-core/src/test_help/unit_helpers.rs +3 -6
  104. package/sdk-core/crates/sdk-core/src/worker/activities/local_activities.rs +11 -14
  105. package/sdk-core/crates/sdk-core/src/worker/activities.rs +16 -19
  106. package/sdk-core/crates/sdk-core/src/worker/client/mocks.rs +9 -5
  107. package/sdk-core/crates/sdk-core/src/worker/client.rs +103 -81
  108. package/sdk-core/crates/sdk-core/src/worker/heartbeat.rs +7 -11
  109. package/sdk-core/crates/sdk-core/src/worker/mod.rs +1124 -229
  110. package/sdk-core/crates/sdk-core/src/worker/nexus.rs +145 -23
  111. package/sdk-core/crates/sdk-core/src/worker/slot_provider.rs +2 -2
  112. package/sdk-core/crates/sdk-core/src/worker/tuner/fixed_size.rs +2 -2
  113. package/sdk-core/crates/sdk-core/src/worker/tuner/resource_based.rs +13 -13
  114. package/sdk-core/crates/sdk-core/src/worker/tuner.rs +28 -8
  115. package/sdk-core/crates/sdk-core/src/worker/workflow/driven_workflow.rs +9 -3
  116. package/sdk-core/crates/sdk-core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +21 -22
  117. package/sdk-core/crates/sdk-core/src/worker/workflow/machines/workflow_machines.rs +19 -4
  118. package/sdk-core/crates/sdk-core/src/worker/workflow/managed_run.rs +14 -18
  119. package/sdk-core/crates/sdk-core/src/worker/workflow/mod.rs +4 -6
  120. package/sdk-core/crates/sdk-core/src/worker/workflow/run_cache.rs +4 -7
  121. package/sdk-core/crates/sdk-core/src/worker/workflow/wft_extraction.rs +2 -4
  122. package/sdk-core/crates/sdk-core/src/worker/workflow/wft_poller.rs +8 -9
  123. package/sdk-core/crates/sdk-core/src/worker/workflow/workflow_stream.rs +1 -3
  124. package/sdk-core/crates/sdk-core/tests/activities_procmacro.rs +6 -0
  125. package/sdk-core/crates/sdk-core/tests/activities_trybuild/basic_pass.rs +54 -0
  126. package/sdk-core/crates/sdk-core/tests/activities_trybuild/invalid_self_type_fail.rs +18 -0
  127. package/sdk-core/crates/sdk-core/tests/activities_trybuild/invalid_self_type_fail.stderr +5 -0
  128. package/sdk-core/crates/sdk-core/tests/activities_trybuild/missing_context_fail.rs +14 -0
  129. package/sdk-core/crates/sdk-core/tests/activities_trybuild/missing_context_fail.stderr +5 -0
  130. package/sdk-core/crates/sdk-core/tests/activities_trybuild/multi_arg_pass.rs +48 -0
  131. package/sdk-core/crates/sdk-core/tests/activities_trybuild/no_input_pass.rs +14 -0
  132. package/sdk-core/crates/sdk-core/tests/activities_trybuild/no_return_type_pass.rs +19 -0
  133. package/sdk-core/crates/sdk-core/tests/cloud_tests.rs +14 -5
  134. package/sdk-core/crates/sdk-core/tests/common/activity_functions.rs +55 -0
  135. package/sdk-core/crates/sdk-core/tests/common/mod.rs +241 -196
  136. package/sdk-core/crates/sdk-core/tests/common/workflows.rs +41 -28
  137. package/sdk-core/crates/sdk-core/tests/global_metric_tests.rs +3 -5
  138. package/sdk-core/crates/sdk-core/tests/heavy_tests/fuzzy_workflow.rs +73 -64
  139. package/sdk-core/crates/sdk-core/tests/heavy_tests.rs +298 -252
  140. package/sdk-core/crates/sdk-core/tests/integ_tests/async_activity_client_tests.rs +230 -0
  141. package/sdk-core/crates/sdk-core/tests/integ_tests/client_tests.rs +94 -57
  142. package/sdk-core/crates/sdk-core/tests/integ_tests/data_converter_tests.rs +381 -0
  143. package/sdk-core/crates/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +16 -12
  144. package/sdk-core/crates/sdk-core/tests/integ_tests/heartbeat_tests.rs +48 -40
  145. package/sdk-core/crates/sdk-core/tests/integ_tests/metrics_tests.rs +327 -255
  146. package/sdk-core/crates/sdk-core/tests/integ_tests/pagination_tests.rs +50 -45
  147. package/sdk-core/crates/sdk-core/tests/integ_tests/polling_tests.rs +147 -126
  148. package/sdk-core/crates/sdk-core/tests/integ_tests/queries_tests.rs +103 -89
  149. package/sdk-core/crates/sdk-core/tests/integ_tests/update_tests.rs +609 -453
  150. package/sdk-core/crates/sdk-core/tests/integ_tests/visibility_tests.rs +80 -62
  151. package/sdk-core/crates/sdk-core/tests/integ_tests/worker_heartbeat_tests.rs +360 -231
  152. package/sdk-core/crates/sdk-core/tests/integ_tests/worker_tests.rs +248 -185
  153. package/sdk-core/crates/sdk-core/tests/integ_tests/worker_versioning_tests.rs +52 -43
  154. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_client_tests.rs +180 -0
  155. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/activities.rs +428 -315
  156. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +82 -56
  157. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +56 -28
  158. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +364 -243
  159. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/client_interactions.rs +552 -0
  160. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +101 -42
  161. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +243 -147
  162. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/eager.rs +98 -28
  163. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +1475 -1036
  164. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +73 -41
  165. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +397 -238
  166. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/patches.rs +414 -189
  167. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/queries.rs +415 -0
  168. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/replay.rs +96 -36
  169. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/resets.rs +154 -137
  170. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/signals.rs +183 -105
  171. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +85 -38
  172. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/timers.rs +142 -40
  173. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +73 -54
  174. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests.rs +363 -226
  175. package/sdk-core/crates/sdk-core/tests/main.rs +17 -15
  176. package/sdk-core/crates/sdk-core/tests/manual_tests.rs +207 -152
  177. package/sdk-core/crates/sdk-core/tests/shared_tests/mod.rs +65 -34
  178. package/sdk-core/crates/sdk-core/tests/shared_tests/priority.rs +107 -84
  179. package/sdk-core/crates/sdk-core/tests/workflows_procmacro.rs +6 -0
  180. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/async_query_fail.rs +26 -0
  181. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/async_query_fail.stderr +5 -0
  182. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/basic_pass.rs +49 -0
  183. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/minimal_pass.rs +21 -0
  184. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/mut_query_fail.rs +26 -0
  185. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/mut_query_fail.stderr +5 -0
  186. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/sync_run_fail.rs +21 -0
  187. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/sync_run_fail.stderr +5 -0
  188. package/sdk-core/crates/sdk-core-c-bridge/Cargo.toml +7 -1
  189. package/sdk-core/crates/sdk-core-c-bridge/include/temporal-sdk-core-c-bridge.h +14 -14
  190. package/sdk-core/crates/sdk-core-c-bridge/src/client.rs +83 -74
  191. package/sdk-core/crates/sdk-core-c-bridge/src/metric.rs +9 -14
  192. package/sdk-core/crates/sdk-core-c-bridge/src/runtime.rs +1 -2
  193. package/sdk-core/crates/sdk-core-c-bridge/src/tests/context.rs +13 -13
  194. package/sdk-core/crates/sdk-core-c-bridge/src/tests/mod.rs +6 -6
  195. package/sdk-core/crates/sdk-core-c-bridge/src/tests/utils.rs +3 -4
  196. package/sdk-core/crates/sdk-core-c-bridge/src/worker.rs +62 -75
  197. package/sdk-core/rustfmt.toml +2 -1
  198. package/src/client.rs +205 -318
  199. package/src/metrics.rs +22 -30
  200. package/src/runtime.rs +4 -5
  201. package/src/worker.rs +16 -19
  202. package/ts/native.ts +1 -1
  203. package/sdk-core/crates/client/src/workflow_handle/mod.rs +0 -212
  204. package/sdk-core/crates/common/src/errors.rs +0 -85
  205. package/sdk-core/crates/common/tests/worker_task_types_test.rs +0 -129
  206. package/sdk-core/crates/sdk/src/activity_context.rs +0 -238
  207. package/sdk-core/crates/sdk/src/app_data.rs +0 -37
  208. package/sdk-core/crates/sdk-core/tests/integ_tests/activity_functions.rs +0 -5
  209. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/appdata_propagation.rs +0 -61
@@ -1,6 +1,5 @@
1
1
  use crate::{dbg_panic, telemetry::TaskQueueLabelStrategy};
2
2
  use std::{
3
- any::Any,
4
3
  borrow::Cow,
5
4
  collections::{BTreeMap, HashMap},
6
5
  fmt::{Debug, Display},
@@ -12,6 +11,99 @@ use std::{
12
11
  time::Duration,
13
12
  };
14
13
 
14
+ #[cfg(feature = "core-based-sdk")]
15
+ pub mod core;
16
+
17
+ /// The string name (which may be prefixed) for this metric
18
+ pub const WORKFLOW_E2E_LATENCY_HISTOGRAM_NAME: &str = "workflow_endtoend_latency";
19
+ /// The string name (which may be prefixed) for this metric
20
+ pub const WORKFLOW_TASK_SCHED_TO_START_LATENCY_HISTOGRAM_NAME: &str =
21
+ "workflow_task_schedule_to_start_latency";
22
+ /// The string name (which may be prefixed) for this metric
23
+ pub const WORKFLOW_TASK_REPLAY_LATENCY_HISTOGRAM_NAME: &str = "workflow_task_replay_latency";
24
+ /// The string name (which may be prefixed) for this metric
25
+ pub const WORKFLOW_TASK_EXECUTION_LATENCY_HISTOGRAM_NAME: &str = "workflow_task_execution_latency";
26
+ /// The string name (which may be prefixed) for this metric
27
+ pub const ACTIVITY_SCHED_TO_START_LATENCY_HISTOGRAM_NAME: &str =
28
+ "activity_schedule_to_start_latency";
29
+ /// The string name (which may be prefixed) for this metric
30
+ pub const ACTIVITY_EXEC_LATENCY_HISTOGRAM_NAME: &str = "activity_execution_latency";
31
+
32
+ /// Helps define buckets once in terms of millis, but also generates a seconds version
33
+ macro_rules! define_latency_buckets {
34
+ ($(($metric_name:pat, $name:ident, $sec_name:ident, [$($bucket:expr),*])),*) => {
35
+ $(
36
+ pub(super) static $name: &[f64] = &[$($bucket,)*];
37
+ pub(super) static $sec_name: &[f64] = &[$( $bucket / 1000.0, )*];
38
+ )*
39
+
40
+ /// Returns the default histogram buckets that lang should use for a given metric name if
41
+ /// they have not been overridden by the user. If `use_seconds` is true, returns buckets
42
+ /// in terms of seconds rather than milliseconds.
43
+ ///
44
+ /// The name must *not* be prefixed with `temporal_`
45
+ pub fn default_buckets_for(histo_name: &str, use_seconds: bool) -> &'static [f64] {
46
+ match histo_name {
47
+ $(
48
+ $metric_name => { if use_seconds { &$sec_name } else { &$name } },
49
+ )*
50
+ }
51
+ }
52
+ };
53
+ }
54
+
55
+ define_latency_buckets!(
56
+ (
57
+ WORKFLOW_E2E_LATENCY_HISTOGRAM_NAME,
58
+ WF_LATENCY_MS_BUCKETS,
59
+ WF_LATENCY_S_BUCKETS,
60
+ [
61
+ 100.,
62
+ 500.,
63
+ 1000.,
64
+ 1500.,
65
+ 2000.,
66
+ 5000.,
67
+ 10_000.,
68
+ 30_000.,
69
+ 60_000.,
70
+ 120_000.,
71
+ 300_000.,
72
+ 600_000.,
73
+ 1_800_000., // 30 min
74
+ 3_600_000., // 1 hr
75
+ 30_600_000., // 10 hrs
76
+ 8.64e7 // 24 hrs
77
+ ]
78
+ ),
79
+ (
80
+ WORKFLOW_TASK_EXECUTION_LATENCY_HISTOGRAM_NAME
81
+ | WORKFLOW_TASK_REPLAY_LATENCY_HISTOGRAM_NAME,
82
+ WF_TASK_MS_BUCKETS,
83
+ WF_TASK_S_BUCKETS,
84
+ [1., 10., 20., 50., 100., 200., 500., 1000.]
85
+ ),
86
+ (
87
+ ACTIVITY_EXEC_LATENCY_HISTOGRAM_NAME,
88
+ ACT_EXE_MS_BUCKETS,
89
+ ACT_EXE_S_BUCKETS,
90
+ [50., 100., 500., 1000., 5000., 10_000., 60_000.]
91
+ ),
92
+ (
93
+ WORKFLOW_TASK_SCHED_TO_START_LATENCY_HISTOGRAM_NAME
94
+ | ACTIVITY_SCHED_TO_START_LATENCY_HISTOGRAM_NAME,
95
+ TASK_SCHED_TO_START_MS_BUCKETS,
96
+ TASK_SCHED_TO_START_S_BUCKETS,
97
+ [100., 500., 1000., 5000., 10_000., 100_000., 1_000_000.]
98
+ ),
99
+ (
100
+ _,
101
+ DEFAULT_MS_BUCKETS,
102
+ DEFAULT_S_BUCKETS,
103
+ [50., 100., 500., 1000., 2500., 10_000.]
104
+ )
105
+ );
106
+
15
107
  /// Implementors of this trait are expected to be defined in each language's bridge.
16
108
  /// The implementor is responsible for the allocation/instantiation of new metric meters which
17
109
  /// Core has requested.
@@ -28,6 +120,7 @@ pub trait CoreMeter: Send + Sync + Debug {
28
120
  existing: MetricAttributes,
29
121
  attribs: NewAttributes,
30
122
  ) -> MetricAttributes;
123
+ /// Create a new counter instrument.
31
124
  fn counter(&self, params: MetricParameters) -> Counter;
32
125
 
33
126
  /// Create a counter with in-memory tracking for worker heartbeating reporting
@@ -41,7 +134,9 @@ pub trait CoreMeter: Send + Sync + Debug {
41
134
  Counter::new_with_in_memory(primary_counter.primary.metric.clone(), in_memory_counter)
42
135
  }
43
136
 
137
+ /// Create a new histogram instrument recording `u64` values.
44
138
  fn histogram(&self, params: MetricParameters) -> Histogram;
139
+ /// Create a new histogram instrument recording `f64` values.
45
140
  fn histogram_f64(&self, params: MetricParameters) -> HistogramF64;
46
141
  /// Create a histogram which records Durations. Implementations should choose to emit in
47
142
  /// either milliseconds or seconds depending on how they have been configured.
@@ -59,6 +154,7 @@ pub trait CoreMeter: Send + Sync + Debug {
59
154
 
60
155
  HistogramDuration::new_with_in_memory(primary_hist.primary.metric.clone(), in_memory_hist)
61
156
  }
157
+ /// Create a new gauge instrument recording `u64` values.
62
158
  fn gauge(&self, params: MetricParameters) -> Gauge;
63
159
 
64
160
  /// Create a gauge with in-memory tracking for worker heartbeating reporting
@@ -71,6 +167,7 @@ pub trait CoreMeter: Send + Sync + Debug {
71
167
  Gauge::new_with_in_memory(primary_gauge.primary.metric.clone(), in_memory_metrics)
72
168
  }
73
169
 
170
+ /// Create a new gauge instrument recording `f64` values.
74
171
  fn gauge_f64(&self, params: MetricParameters) -> GaugeF64;
75
172
  }
76
173
 
@@ -79,9 +176,13 @@ pub trait CoreMeter: Send + Sync + Debug {
79
176
  /// that vary by a set of labels for the same metric.
80
177
  #[derive(Clone, Debug)]
81
178
  pub enum HeartbeatMetricType {
179
+ /// A single counter shared across all label values.
82
180
  Individual(Arc<AtomicU64>),
181
+ /// Per-label-value counters, keyed by a specific label.
83
182
  WithLabel {
183
+ /// The label key to match against metric attributes.
84
184
  label_key: String,
185
+ /// Map from label value to its atomic counter.
85
186
  metrics: HashMap<String, Arc<AtomicU64>>,
86
187
  },
87
188
  }
@@ -128,7 +229,7 @@ impl HeartbeatMetricType {
128
229
  fn label_value_from_attributes(attributes: &MetricAttributes, key: &str) -> Option<String> {
129
230
  match attributes {
130
231
  MetricAttributes::Prometheus { labels } => labels.as_prom_labels().get(key).cloned(),
131
- #[cfg(feature = "otel_impls")]
232
+ #[cfg(feature = "otel")]
132
233
  MetricAttributes::OTel { kvs } => kvs
133
234
  .iter()
134
235
  .find(|kv| kv.key.as_str() == key)
@@ -138,129 +239,7 @@ fn label_value_from_attributes(attributes: &MetricAttributes, key: &str) -> Opti
138
239
  }
139
240
  }
140
241
 
141
- #[derive(Default, Debug)]
142
- pub struct NumPollersMetric {
143
- pub wft_current_pollers: Arc<AtomicU64>,
144
- pub sticky_wft_current_pollers: Arc<AtomicU64>,
145
- pub activity_current_pollers: Arc<AtomicU64>,
146
- pub nexus_current_pollers: Arc<AtomicU64>,
147
- }
148
-
149
- impl NumPollersMetric {
150
- pub fn as_map(&self) -> HashMap<String, Arc<AtomicU64>> {
151
- HashMap::from([
152
- (
153
- "workflow_task".to_string(),
154
- self.wft_current_pollers.clone(),
155
- ),
156
- (
157
- "sticky_workflow_task".to_string(),
158
- self.sticky_wft_current_pollers.clone(),
159
- ),
160
- (
161
- "activity_task".to_string(),
162
- self.activity_current_pollers.clone(),
163
- ),
164
- ("nexus_task".to_string(), self.nexus_current_pollers.clone()),
165
- ])
166
- }
167
- }
168
-
169
- #[derive(Default, Debug)]
170
- pub struct SlotMetrics {
171
- pub workflow_worker: Arc<AtomicU64>,
172
- pub activity_worker: Arc<AtomicU64>,
173
- pub nexus_worker: Arc<AtomicU64>,
174
- pub local_activity_worker: Arc<AtomicU64>,
175
- }
176
-
177
- impl SlotMetrics {
178
- pub fn as_map(&self) -> HashMap<String, Arc<AtomicU64>> {
179
- HashMap::from([
180
- ("WorkflowWorker".to_string(), self.workflow_worker.clone()),
181
- ("ActivityWorker".to_string(), self.activity_worker.clone()),
182
- ("NexusWorker".to_string(), self.nexus_worker.clone()),
183
- (
184
- "LocalActivityWorker".to_string(),
185
- self.local_activity_worker.clone(),
186
- ),
187
- ])
188
- }
189
- }
190
-
191
- #[derive(Default, Debug)]
192
- pub struct WorkerHeartbeatMetrics {
193
- pub sticky_cache_size: Arc<AtomicU64>,
194
- pub total_sticky_cache_hit: Arc<AtomicU64>,
195
- pub total_sticky_cache_miss: Arc<AtomicU64>,
196
- pub num_pollers: NumPollersMetric,
197
- pub worker_task_slots_used: SlotMetrics,
198
- pub worker_task_slots_available: SlotMetrics,
199
- pub workflow_task_execution_failed: Arc<AtomicU64>,
200
- pub activity_execution_failed: Arc<AtomicU64>,
201
- pub nexus_task_execution_failed: Arc<AtomicU64>,
202
- pub local_activity_execution_failed: Arc<AtomicU64>,
203
- // Although latency metrics here are histograms, we are using the number of times they're called
204
- // to represent the `total_processed_tasks` heartbeat field
205
- pub activity_execution_latency: Arc<AtomicU64>,
206
- pub local_activity_execution_latency: Arc<AtomicU64>,
207
- pub workflow_task_execution_latency: Arc<AtomicU64>,
208
- pub nexus_task_execution_latency: Arc<AtomicU64>,
209
- }
210
-
211
- impl WorkerHeartbeatMetrics {
212
- pub fn get_metric(&self, name: &str) -> Option<HeartbeatMetricType> {
213
- match name {
214
- "sticky_cache_size" => Some(HeartbeatMetricType::Individual(
215
- self.sticky_cache_size.clone(),
216
- )),
217
- "sticky_cache_hit" => Some(HeartbeatMetricType::Individual(
218
- self.total_sticky_cache_hit.clone(),
219
- )),
220
- "sticky_cache_miss" => Some(HeartbeatMetricType::Individual(
221
- self.total_sticky_cache_miss.clone(),
222
- )),
223
- "num_pollers" => Some(HeartbeatMetricType::WithLabel {
224
- label_key: "poller_type".to_string(),
225
- metrics: self.num_pollers.as_map(),
226
- }),
227
- "worker_task_slots_used" => Some(HeartbeatMetricType::WithLabel {
228
- label_key: "worker_type".to_string(),
229
- metrics: self.worker_task_slots_used.as_map(),
230
- }),
231
- "worker_task_slots_available" => Some(HeartbeatMetricType::WithLabel {
232
- label_key: "worker_type".to_string(),
233
- metrics: self.worker_task_slots_available.as_map(),
234
- }),
235
- "workflow_task_execution_failed" => Some(HeartbeatMetricType::Individual(
236
- self.workflow_task_execution_failed.clone(),
237
- )),
238
- "activity_execution_failed" => Some(HeartbeatMetricType::Individual(
239
- self.activity_execution_failed.clone(),
240
- )),
241
- "nexus_task_execution_failed" => Some(HeartbeatMetricType::Individual(
242
- self.nexus_task_execution_failed.clone(),
243
- )),
244
- "local_activity_execution_failed" => Some(HeartbeatMetricType::Individual(
245
- self.local_activity_execution_failed.clone(),
246
- )),
247
- "activity_execution_latency" => Some(HeartbeatMetricType::Individual(
248
- self.activity_execution_latency.clone(),
249
- )),
250
- "local_activity_execution_latency" => Some(HeartbeatMetricType::Individual(
251
- self.local_activity_execution_latency.clone(),
252
- )),
253
- "workflow_task_execution_latency" => Some(HeartbeatMetricType::Individual(
254
- self.workflow_task_execution_latency.clone(),
255
- )),
256
- "nexus_task_execution_latency" => Some(HeartbeatMetricType::Individual(
257
- self.nexus_task_execution_latency.clone(),
258
- )),
259
- _ => None,
260
- }
261
- }
262
- }
263
-
242
+ /// Parameters used when creating a new metric instrument (name, description, unit).
264
243
  #[derive(Debug, Clone, bon::Builder)]
265
244
  pub struct MetricParameters {
266
245
  /// The name for the new metric/instrument
@@ -284,11 +263,50 @@ impl From<&'static str> for MetricParameters {
284
263
  }
285
264
 
286
265
  /// Wraps a [CoreMeter] to enable the attaching of default labels to metrics. Cloning is cheap.
287
- #[derive(derive_more::Constructor, Clone, Debug)]
266
+ #[derive(Clone, Debug)]
288
267
  pub struct TemporalMeter {
289
- pub inner: Arc<dyn CoreMeter>,
290
- pub default_attribs: NewAttributes,
291
- pub task_queue_label_strategy: TaskQueueLabelStrategy,
268
+ inner: Arc<dyn CoreMeter>,
269
+ default_attribs: MetricAttributes,
270
+ task_queue_label_strategy: TaskQueueLabelStrategy,
271
+ }
272
+
273
+ impl TemporalMeter {
274
+ /// Create a new TemporalMeter.
275
+ pub fn new(
276
+ meter: Arc<dyn CoreMeter>,
277
+ default_attribs: NewAttributes,
278
+ task_queue_label_strategy: TaskQueueLabelStrategy,
279
+ ) -> Self {
280
+ Self {
281
+ default_attribs: meter.new_attributes(default_attribs),
282
+ inner: meter,
283
+ task_queue_label_strategy,
284
+ }
285
+ }
286
+
287
+ /// Creates a TemporalMeter that records nothing
288
+ pub fn no_op() -> Self {
289
+ Self {
290
+ inner: Arc::new(NoOpCoreMeter),
291
+ default_attribs: MetricAttributes::NoOp(Arc::new(Default::default())),
292
+ task_queue_label_strategy: TaskQueueLabelStrategy::UseNormal,
293
+ }
294
+ }
295
+
296
+ /// Returns the default attributes this meter uses.
297
+ pub fn get_default_attributes(&self) -> &MetricAttributes {
298
+ &self.default_attribs
299
+ }
300
+
301
+ /// Returns the Task Queue labeling strategy this meter uses.
302
+ pub fn get_task_queue_label_strategy(&self) -> &TaskQueueLabelStrategy {
303
+ &self.task_queue_label_strategy
304
+ }
305
+
306
+ /// Add some new attributes to the default set already in this meter.
307
+ pub fn merge_attributes(&mut self, new_attribs: NewAttributes) {
308
+ self.default_attribs = self.extend_attributes(self.default_attribs.clone(), new_attribs);
309
+ }
292
310
  }
293
311
 
294
312
  impl Deref for TemporalMeter {
@@ -340,32 +358,37 @@ impl CoreMeter for Arc<dyn CoreMeter> {
340
358
  #[derive(Clone, Debug)]
341
359
  #[non_exhaustive]
342
360
  pub enum MetricAttributes {
343
- #[cfg(feature = "otel_impls")]
361
+ /// OpenTelemetry-backed attributes with key-value pairs.
362
+ #[cfg(feature = "otel")]
344
363
  OTel {
364
+ /// The OpenTelemetry key-value pairs for this attribute set.
345
365
  kvs: Arc<Vec<opentelemetry::KeyValue>>,
346
366
  },
367
+ /// Prometheus-backed attributes with ordered labels.
347
368
  Prometheus {
369
+ /// The ordered label set.
348
370
  labels: Arc<OrderedPromLabelSet>,
349
371
  },
350
- Buffer(BufferAttributes),
351
- Dynamic(Arc<dyn CustomMetricAttributes>),
372
+ /// Buffered attributes used by core-based SDKs for deferred metric initialization.
373
+ #[cfg(feature = "core-based-sdk")]
374
+ Buffer(core::BufferAttributes),
375
+ /// Dynamic attributes backed by a lang-side custom implementation.
376
+ #[cfg(feature = "core-based-sdk")]
377
+ Dynamic(Arc<dyn core::CustomMetricAttributes>),
378
+ /// No-op attributes that store labels but do not record.
352
379
  NoOp(Arc<HashMap<String, String>>),
380
+ /// Empty placeholder attributes.
353
381
  Empty,
354
382
  }
355
383
 
356
- /// A reference to some attributes created lang side.
357
- pub trait CustomMetricAttributes: Debug + Send + Sync {
358
- /// Must be implemented to work around existing type system restrictions, see
359
- /// [here](https://internals.rust-lang.org/t/downcast-not-from-any-but-from-any-trait/16736/12)
360
- fn as_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync>;
361
- }
362
-
363
384
  /// Options that are attached to metrics on a per-call basis
364
385
  #[derive(Clone, Debug, Default, derive_more::Constructor)]
365
386
  pub struct NewAttributes {
387
+ /// The key-value pairs for this attribute set.
366
388
  pub attributes: Vec<MetricKeyValue>,
367
389
  }
368
390
  impl NewAttributes {
391
+ /// Append additional key-value pairs to this attribute set.
369
392
  pub fn extend(&mut self, new_kvs: impl IntoIterator<Item = MetricKeyValue>) {
370
393
  self.attributes.extend(new_kvs)
371
394
  }
@@ -394,10 +417,13 @@ impl From<NewAttributes> for HashMap<String, String> {
394
417
  /// A K/V pair that can be used to label a specific recording of a metric
395
418
  #[derive(Clone, Debug, PartialEq)]
396
419
  pub struct MetricKeyValue {
420
+ /// The label key.
397
421
  pub key: String,
422
+ /// The label value.
398
423
  pub value: MetricValue,
399
424
  }
400
425
  impl MetricKeyValue {
426
+ /// Create a new key-value pair.
401
427
  pub fn new(key: impl Into<String>, value: impl Into<MetricValue>) -> Self {
402
428
  Self {
403
429
  key: key.into(),
@@ -409,9 +435,13 @@ impl MetricKeyValue {
409
435
  /// Values metric labels may assume
410
436
  #[derive(Clone, Debug, PartialEq, derive_more::From)]
411
437
  pub enum MetricValue {
438
+ /// A string label value.
412
439
  String(String),
440
+ /// An integer label value.
413
441
  Int(i64),
442
+ /// A floating-point label value.
414
443
  Float(f64),
444
+ /// A boolean label value.
415
445
  Bool(bool),
416
446
  // can add array if needed
417
447
  }
@@ -431,6 +461,7 @@ impl Display for MetricValue {
431
461
  }
432
462
  }
433
463
 
464
+ /// Trait for metric instruments that can be bound to a set of attributes.
434
465
  pub trait MetricAttributable<Base> {
435
466
  /// Replace any existing attributes on this metric with new ones, and return a new copy
436
467
  /// of the metric, or a base version, which can be used to record values.
@@ -447,6 +478,7 @@ pub trait MetricAttributable<Base> {
447
478
  ) -> Result<Base, Box<dyn std::error::Error>>;
448
479
  }
449
480
 
481
+ /// A metric that lazily binds to its attributes on first use, caching the result.
450
482
  #[derive(Clone)]
451
483
  pub struct LazyBoundMetric<T, B> {
452
484
  metric: T,
@@ -454,27 +486,33 @@ pub struct LazyBoundMetric<T, B> {
454
486
  bound_cache: OnceLock<B>,
455
487
  }
456
488
  impl<T, B> LazyBoundMetric<T, B> {
489
+ /// Replace the attributes and invalidate the cached binding.
457
490
  pub fn update_attributes(&mut self, new_attributes: MetricAttributes) {
458
491
  self.attributes = new_attributes;
459
492
  self.bound_cache = OnceLock::new();
460
493
  }
461
494
  }
462
495
 
496
+ /// Base trait for counter implementations.
463
497
  pub trait CounterBase: Send + Sync {
498
+ /// Increment the counter by `value`.
464
499
  fn adds(&self, value: u64);
465
500
  }
466
501
 
502
+ /// The lazy-bound inner type for [`Counter`].
467
503
  pub type CounterImpl = LazyBoundMetric<
468
504
  Arc<dyn MetricAttributable<Box<dyn CounterBase>> + Send + Sync>,
469
505
  Arc<dyn CounterBase>,
470
506
  >;
471
507
 
508
+ /// A counter metric instrument that optionally tracks values in memory for heartbeating.
472
509
  #[derive(Clone)]
473
510
  pub struct Counter {
474
511
  primary: CounterImpl,
475
512
  in_memory: Option<HeartbeatMetricType>,
476
513
  }
477
514
  impl Counter {
515
+ /// Create a new counter from an attributable metric source.
478
516
  pub fn new(inner: Arc<dyn MetricAttributable<Box<dyn CounterBase>> + Send + Sync>) -> Self {
479
517
  Self {
480
518
  primary: LazyBoundMetric {
@@ -486,6 +524,7 @@ impl Counter {
486
524
  }
487
525
  }
488
526
 
527
+ /// Create a new counter with an additional in-memory tracker for heartbeat reporting.
489
528
  pub fn new_with_in_memory(
490
529
  primary: Arc<dyn MetricAttributable<Box<dyn CounterBase>> + Send + Sync>,
491
530
  in_memory: HeartbeatMetricType,
@@ -500,6 +539,7 @@ impl Counter {
500
539
  }
501
540
  }
502
541
 
542
+ /// Increment the counter by `value` with the given attributes.
503
543
  pub fn add(&self, value: u64, attributes: &MetricAttributes) {
504
544
  match self.primary.metric.with_attributes(attributes) {
505
545
  Ok(base) => base.adds(value),
@@ -513,6 +553,7 @@ impl Counter {
513
553
  }
514
554
  }
515
555
 
556
+ /// Replace the attributes on the primary metric.
516
557
  pub fn update_attributes(&mut self, new_attributes: MetricAttributes) {
517
558
  self.primary.update_attributes(new_attributes.clone());
518
559
  }
@@ -556,14 +597,18 @@ impl MetricAttributable<Counter> for Counter {
556
597
  }
557
598
  }
558
599
 
600
+ /// Base trait for `u64` histogram implementations.
559
601
  pub trait HistogramBase: Send + Sync {
602
+ /// Record a `u64` observation.
560
603
  fn records(&self, value: u64);
561
604
  }
605
+ /// A `u64` histogram metric instrument.
562
606
  pub type Histogram = LazyBoundMetric<
563
607
  Arc<dyn MetricAttributable<Box<dyn HistogramBase>> + Send + Sync>,
564
608
  Arc<dyn HistogramBase>,
565
609
  >;
566
610
  impl Histogram {
611
+ /// Create a new histogram from an attributable metric source.
567
612
  pub fn new(inner: Arc<dyn MetricAttributable<Box<dyn HistogramBase>> + Send + Sync>) -> Self {
568
613
  Self {
569
614
  metric: inner,
@@ -571,6 +616,7 @@ impl Histogram {
571
616
  bound_cache: OnceLock::new(),
572
617
  }
573
618
  }
619
+ /// Record a `u64` value with the given attributes.
574
620
  pub fn record(&self, value: u64, attributes: &MetricAttributes) {
575
621
  match self.metric.with_attributes(attributes) {
576
622
  Ok(base) => {
@@ -609,14 +655,18 @@ impl MetricAttributable<Histogram> for Histogram {
609
655
  }
610
656
  }
611
657
 
658
+ /// Base trait for `f64` histogram implementations.
612
659
  pub trait HistogramF64Base: Send + Sync {
660
+ /// Record an `f64` observation.
613
661
  fn records(&self, value: f64);
614
662
  }
663
+ /// An `f64` histogram metric instrument.
615
664
  pub type HistogramF64 = LazyBoundMetric<
616
665
  Arc<dyn MetricAttributable<Box<dyn HistogramF64Base>> + Send + Sync>,
617
666
  Arc<dyn HistogramF64Base>,
618
667
  >;
619
668
  impl HistogramF64 {
669
+ /// Create a new `f64` histogram from an attributable metric source.
620
670
  pub fn new(
621
671
  inner: Arc<dyn MetricAttributable<Box<dyn HistogramF64Base>> + Send + Sync>,
622
672
  ) -> Self {
@@ -626,6 +676,7 @@ impl HistogramF64 {
626
676
  bound_cache: OnceLock::new(),
627
677
  }
628
678
  }
679
+ /// Record an `f64` value with the given attributes.
629
680
  pub fn record(&self, value: f64, attributes: &MetricAttributes) {
630
681
  match self.metric.with_attributes(attributes) {
631
682
  Ok(base) => {
@@ -664,21 +715,26 @@ impl MetricAttributable<HistogramF64> for HistogramF64 {
664
715
  }
665
716
  }
666
717
 
718
+ /// Base trait for duration histogram implementations.
667
719
  pub trait HistogramDurationBase: Send + Sync {
720
+ /// Record a duration observation.
668
721
  fn records(&self, value: Duration);
669
722
  }
670
723
 
724
+ /// The lazy-bound inner type for [`HistogramDuration`].
671
725
  pub type HistogramDurationImpl = LazyBoundMetric<
672
726
  Arc<dyn MetricAttributable<Box<dyn HistogramDurationBase>> + Send + Sync>,
673
727
  Arc<dyn HistogramDurationBase>,
674
728
  >;
675
729
 
730
+ /// A histogram that records [`Duration`] values, optionally tracking in memory for heartbeating.
676
731
  #[derive(Clone)]
677
732
  pub struct HistogramDuration {
678
733
  primary: HistogramDurationImpl,
679
734
  in_memory: Option<HeartbeatMetricType>,
680
735
  }
681
736
  impl HistogramDuration {
737
+ /// Create a new duration histogram from an attributable metric source.
682
738
  pub fn new(
683
739
  inner: Arc<dyn MetricAttributable<Box<dyn HistogramDurationBase>> + Send + Sync>,
684
740
  ) -> Self {
@@ -691,6 +747,7 @@ impl HistogramDuration {
691
747
  in_memory: None,
692
748
  }
693
749
  }
750
+ /// Create a new duration histogram with an additional in-memory tracker for heartbeat reporting.
694
751
  pub fn new_with_in_memory(
695
752
  primary: Arc<dyn MetricAttributable<Box<dyn HistogramDurationBase>> + Send + Sync>,
696
753
  in_memory: HeartbeatMetricType,
@@ -704,6 +761,7 @@ impl HistogramDuration {
704
761
  in_memory: Some(in_memory),
705
762
  }
706
763
  }
764
+ /// Record a duration value with the given attributes.
707
765
  pub fn record(&self, value: Duration, attributes: &MetricAttributes) {
708
766
  match self.primary.metric.with_attributes(attributes) {
709
767
  Ok(base) => {
@@ -719,6 +777,7 @@ impl HistogramDuration {
719
777
  }
720
778
  }
721
779
 
780
+ /// Replace the attributes on the primary metric.
722
781
  pub fn update_attributes(&mut self, new_attributes: MetricAttributes) {
723
782
  self.primary.update_attributes(new_attributes.clone());
724
783
  }
@@ -760,21 +819,26 @@ impl MetricAttributable<HistogramDuration> for HistogramDuration {
760
819
  }
761
820
  }
762
821
 
822
+ /// Base trait for `u64` gauge implementations.
763
823
  pub trait GaugeBase: Send + Sync {
824
+ /// Record a `u64` gauge value.
764
825
  fn records(&self, value: u64);
765
826
  }
766
827
 
828
+ /// The lazy-bound inner type for [`Gauge`].
767
829
  pub type GaugeImpl = LazyBoundMetric<
768
830
  Arc<dyn MetricAttributable<Box<dyn GaugeBase>> + Send + Sync>,
769
831
  Arc<dyn GaugeBase>,
770
832
  >;
771
833
 
834
+ /// A gauge metric instrument that optionally tracks values in memory for heartbeating.
772
835
  #[derive(Clone)]
773
836
  pub struct Gauge {
774
837
  primary: GaugeImpl,
775
838
  in_memory: Option<HeartbeatMetricType>,
776
839
  }
777
840
  impl Gauge {
841
+ /// Create a new gauge from an attributable metric source.
778
842
  pub fn new(inner: Arc<dyn MetricAttributable<Box<dyn GaugeBase>> + Send + Sync>) -> Self {
779
843
  Self {
780
844
  primary: LazyBoundMetric {
@@ -786,6 +850,7 @@ impl Gauge {
786
850
  }
787
851
  }
788
852
 
853
+ /// Create a new gauge with an additional in-memory tracker for heartbeat reporting.
789
854
  pub fn new_with_in_memory(
790
855
  primary: Arc<dyn MetricAttributable<Box<dyn GaugeBase>> + Send + Sync>,
791
856
  in_memory: HeartbeatMetricType,
@@ -800,6 +865,7 @@ impl Gauge {
800
865
  }
801
866
  }
802
867
 
868
+ /// Record a `u64` gauge value with the given attributes.
803
869
  pub fn record(&self, value: u64, attributes: &MetricAttributes) {
804
870
  match self.primary.metric.with_attributes(attributes) {
805
871
  Ok(base) => base.records(value),
@@ -813,6 +879,7 @@ impl Gauge {
813
879
  }
814
880
  }
815
881
 
882
+ /// Replace the attributes on the primary metric.
816
883
  pub fn update_attributes(&mut self, new_attributes: MetricAttributes) {
817
884
  self.primary.update_attributes(new_attributes.clone());
818
885
  }
@@ -854,14 +921,18 @@ impl MetricAttributable<Gauge> for Gauge {
854
921
  }
855
922
  }
856
923
 
924
+ /// Base trait for `f64` gauge implementations.
857
925
  pub trait GaugeF64Base: Send + Sync {
926
+ /// Record an `f64` gauge value.
858
927
  fn records(&self, value: f64);
859
928
  }
929
+ /// An `f64` gauge metric instrument.
860
930
  pub type GaugeF64 = LazyBoundMetric<
861
931
  Arc<dyn MetricAttributable<Box<dyn GaugeF64Base>> + Send + Sync>,
862
932
  Arc<dyn GaugeF64Base>,
863
933
  >;
864
934
  impl GaugeF64 {
935
+ /// Create a new `f64` gauge from an attributable metric source.
865
936
  pub fn new(inner: Arc<dyn MetricAttributable<Box<dyn GaugeF64Base>> + Send + Sync>) -> Self {
866
937
  Self {
867
938
  metric: inner,
@@ -869,6 +940,7 @@ impl GaugeF64 {
869
940
  bound_cache: OnceLock::new(),
870
941
  }
871
942
  }
943
+ /// Record an `f64` gauge value with the given attributes.
872
944
  pub fn record(&self, value: f64, attributes: &MetricAttributes) {
873
945
  match self.metric.with_attributes(attributes) {
874
946
  Ok(base) => {
@@ -907,88 +979,7 @@ impl MetricAttributable<GaugeF64> for GaugeF64 {
907
979
  }
908
980
  }
909
981
 
910
- #[derive(Debug, Clone)]
911
- pub enum MetricEvent<I: BufferInstrumentRef> {
912
- Create {
913
- params: MetricParameters,
914
- /// Once you receive this event, call `set` on this with the initialized instrument
915
- /// reference
916
- populate_into: LazyBufferInstrument<I>,
917
- kind: MetricKind,
918
- },
919
- CreateAttributes {
920
- /// Once you receive this event, call `set` on this with the initialized attributes
921
- populate_into: BufferAttributes,
922
- /// If not `None`, use these already-initialized attributes as the base (extended with
923
- /// `attributes`) for the ones you are about to initialize.
924
- append_from: Option<BufferAttributes>,
925
- attributes: Vec<MetricKeyValue>,
926
- },
927
- Update {
928
- instrument: LazyBufferInstrument<I>,
929
- attributes: BufferAttributes,
930
- update: MetricUpdateVal,
931
- },
932
- }
933
- #[derive(Debug, Clone, Copy)]
934
- pub enum MetricKind {
935
- Counter,
936
- Gauge,
937
- GaugeF64,
938
- Histogram,
939
- HistogramF64,
940
- HistogramDuration,
941
- }
942
- #[derive(Debug, Clone, Copy)]
943
- pub enum MetricUpdateVal {
944
- Delta(u64),
945
- DeltaF64(f64),
946
- Value(u64),
947
- ValueF64(f64),
948
- Duration(Duration),
949
- }
950
-
951
- pub trait MetricCallBufferer<I: BufferInstrumentRef>: Send + Sync {
952
- fn retrieve(&self) -> Vec<MetricEvent<I>>;
953
- }
954
-
955
- /// A lazy reference to some metrics buffer attributes
956
- pub type BufferAttributes = LazyRef<Arc<dyn CustomMetricAttributes + 'static>>;
957
-
958
- /// Types lang uses to contain references to its lang-side defined instrument references must
959
- /// implement this marker trait
960
- pub trait BufferInstrumentRef {}
961
- /// A lazy reference to a metrics buffer instrument
962
- pub type LazyBufferInstrument<T> = LazyRef<Arc<T>>;
963
-
964
- #[derive(Debug, Clone)]
965
- pub struct LazyRef<T> {
966
- to_be_initted: Arc<OnceLock<T>>,
967
- }
968
- impl<T> LazyRef<T> {
969
- pub fn hole() -> Self {
970
- Self {
971
- to_be_initted: Arc::new(OnceLock::new()),
972
- }
973
- }
974
-
975
- /// Get the reference you previously initialized
976
- ///
977
- /// # Panics
978
- /// If `set` has not already been called. You must set the reference before using it.
979
- pub fn get(&self) -> &T {
980
- self.to_be_initted
981
- .get()
982
- .expect("You must initialize the reference before using it")
983
- }
984
-
985
- /// Assigns a value to fill this reference.
986
- /// Returns according to semantics of [OnceLock].
987
- pub fn set(&self, val: T) -> Result<(), T> {
988
- self.to_be_initted.set(val)
989
- }
990
- }
991
-
982
+ /// A [`CoreMeter`] implementation that discards all metric recordings.
992
983
  #[derive(Debug)]
993
984
  pub struct NoOpCoreMeter;
994
985
  impl CoreMeter for NoOpCoreMeter {
@@ -1049,6 +1040,7 @@ macro_rules! impl_metric_attributable {
1049
1040
  };
1050
1041
  }
1051
1042
 
1043
+ /// A no-op metric instrument that discards all recordings.
1052
1044
  pub struct NoOpInstrument;
1053
1045
  macro_rules! impl_no_op {
1054
1046
  ($base_trait:ident, $value_type:ty) => {
@@ -1109,8 +1101,8 @@ mod tests {
1109
1101
  }
1110
1102
  }
1111
1103
 
1112
- #[cfg(feature = "otel_impls")]
1113
- mod otel_impls {
1104
+ #[cfg(feature = "otel")]
1105
+ mod otel {
1114
1106
  use super::*;
1115
1107
  use opentelemetry::{KeyValue, metrics};
1116
1108
 
@@ -1255,14 +1247,17 @@ pub struct OrderedPromLabelSet {
1255
1247
  }
1256
1248
 
1257
1249
  impl OrderedPromLabelSet {
1250
+ /// Create an empty label set.
1258
1251
  pub const fn new() -> Self {
1259
1252
  Self {
1260
1253
  attributes: BTreeMap::new(),
1261
1254
  }
1262
1255
  }
1256
+ /// Iterate over label keys in sorted order.
1263
1257
  pub fn keys_ordered(&self) -> impl Iterator<Item = &str> {
1264
1258
  self.attributes.keys().map(|s| s.as_str())
1265
1259
  }
1260
+ /// Return a map of label keys to their string values, suitable for Prometheus.
1266
1261
  pub fn as_prom_labels(&self) -> HashMap<&str, String> {
1267
1262
  let mut labels = HashMap::new();
1268
1263
  for (k, v) in self.attributes.iter() {
@@ -1270,6 +1265,7 @@ impl OrderedPromLabelSet {
1270
1265
  }
1271
1266
  labels
1272
1267
  }
1268
+ /// Insert a key-value pair, replacing dashes with underscores per Prometheus conventions.
1273
1269
  pub fn add_kv(&mut self, kv: MetricKeyValue) {
1274
1270
  // Replace '-' with '_' per Prom naming requirements
1275
1271
  self.attributes.insert(kv.key.replace('-', "_"), kv.value);
@@ -1285,3 +1281,52 @@ impl From<NewAttributes> for OrderedPromLabelSet {
1285
1281
  me
1286
1282
  }
1287
1283
  }
1284
+
1285
+ #[derive(Debug, derive_more::Constructor)]
1286
+ pub(crate) struct PrefixedMetricsMeter<CM> {
1287
+ prefix: String,
1288
+ meter: CM,
1289
+ }
1290
+ impl<CM: CoreMeter> CoreMeter for PrefixedMetricsMeter<CM> {
1291
+ fn new_attributes(&self, attribs: NewAttributes) -> MetricAttributes {
1292
+ self.meter.new_attributes(attribs)
1293
+ }
1294
+
1295
+ fn extend_attributes(
1296
+ &self,
1297
+ existing: MetricAttributes,
1298
+ attribs: NewAttributes,
1299
+ ) -> MetricAttributes {
1300
+ self.meter.extend_attributes(existing, attribs)
1301
+ }
1302
+
1303
+ fn counter(&self, mut params: MetricParameters) -> Counter {
1304
+ params.name = (self.prefix.clone() + &*params.name).into();
1305
+ self.meter.counter(params)
1306
+ }
1307
+
1308
+ fn histogram(&self, mut params: MetricParameters) -> Histogram {
1309
+ params.name = (self.prefix.clone() + &*params.name).into();
1310
+ self.meter.histogram(params)
1311
+ }
1312
+
1313
+ fn histogram_f64(&self, mut params: MetricParameters) -> HistogramF64 {
1314
+ params.name = (self.prefix.clone() + &*params.name).into();
1315
+ self.meter.histogram_f64(params)
1316
+ }
1317
+
1318
+ fn histogram_duration(&self, mut params: MetricParameters) -> HistogramDuration {
1319
+ params.name = (self.prefix.clone() + &*params.name).into();
1320
+ self.meter.histogram_duration(params)
1321
+ }
1322
+
1323
+ fn gauge(&self, mut params: MetricParameters) -> Gauge {
1324
+ params.name = (self.prefix.clone() + &*params.name).into();
1325
+ self.meter.gauge(params)
1326
+ }
1327
+
1328
+ fn gauge_f64(&self, mut params: MetricParameters) -> GaugeF64 {
1329
+ params.name = (self.prefix.clone() + &*params.name).into();
1330
+ self.meter.gauge_f64(params)
1331
+ }
1332
+ }