@temporalio/core-bridge 1.14.2-canary-release-testing.0 → 1.16.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 (233) hide show
  1. package/Cargo.lock +794 -650
  2. package/bridge-macros/src/derive_tryintojs.rs +40 -0
  3. package/lib/native.d.ts +24 -3
  4. package/package.json +4 -4
  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/.github/workflows/per-pr.yml +6 -6
  11. package/sdk-core/AGENTS.md +42 -31
  12. package/sdk-core/Cargo.toml +4 -1
  13. package/sdk-core/README.md +19 -13
  14. package/sdk-core/crates/client/Cargo.toml +4 -0
  15. package/sdk-core/crates/client/README.md +139 -0
  16. package/sdk-core/crates/client/src/async_activity_handle.rs +297 -0
  17. package/sdk-core/crates/client/src/callback_based.rs +7 -0
  18. package/sdk-core/crates/client/src/errors.rs +294 -0
  19. package/sdk-core/crates/client/src/{raw.rs → grpc.rs} +370 -159
  20. package/sdk-core/crates/client/src/lib.rs +920 -1326
  21. package/sdk-core/crates/client/src/metrics.rs +24 -33
  22. package/sdk-core/crates/client/src/options_structs.rs +457 -0
  23. package/sdk-core/crates/client/src/replaceable.rs +5 -4
  24. package/sdk-core/crates/client/src/request_extensions.rs +8 -9
  25. package/sdk-core/crates/client/src/retry.rs +99 -54
  26. package/sdk-core/crates/client/src/{worker/mod.rs → worker.rs} +104 -29
  27. package/sdk-core/crates/client/src/workflow_handle.rs +826 -0
  28. package/sdk-core/crates/common/Cargo.toml +62 -3
  29. package/sdk-core/crates/common/build.rs +742 -12
  30. package/sdk-core/crates/common/protos/api_upstream/.github/workflows/ci.yml +2 -0
  31. package/sdk-core/crates/common/protos/api_upstream/.github/workflows/create-release.yml +0 -5
  32. package/sdk-core/crates/common/protos/api_upstream/Makefile +2 -1
  33. package/sdk-core/crates/common/protos/api_upstream/README.md +8 -0
  34. package/sdk-core/crates/common/protos/api_upstream/cmd/check-path-conflicts/main.go +137 -0
  35. package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv2.json +3329 -2647
  36. package/sdk-core/crates/common/protos/api_upstream/openapi/openapiv3.yaml +2734 -708
  37. package/sdk-core/crates/common/protos/api_upstream/temporal/api/activity/v1/message.proto +155 -3
  38. package/sdk-core/crates/common/protos/api_upstream/temporal/api/command/v1/message.proto +26 -0
  39. package/sdk-core/crates/common/protos/api_upstream/temporal/api/common/v1/message.proto +8 -1
  40. package/sdk-core/crates/common/protos/api_upstream/temporal/api/deployment/v1/message.proto +27 -1
  41. package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/activity.proto +81 -0
  42. package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/event_type.proto +4 -0
  43. package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +4 -0
  44. package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/task_queue.proto +15 -0
  45. package/sdk-core/crates/common/protos/api_upstream/temporal/api/enums/v1/workflow.proto +63 -15
  46. package/sdk-core/crates/common/protos/api_upstream/temporal/api/errordetails/v1/message.proto +8 -0
  47. package/sdk-core/crates/common/protos/api_upstream/temporal/api/failure/v1/message.proto +1 -0
  48. package/sdk-core/crates/common/protos/api_upstream/temporal/api/history/v1/message.proto +111 -17
  49. package/sdk-core/crates/common/protos/api_upstream/temporal/api/namespace/v1/message.proto +21 -0
  50. package/sdk-core/crates/common/protos/api_upstream/temporal/api/nexus/v1/message.proto +20 -1
  51. package/sdk-core/crates/common/protos/api_upstream/temporal/api/operatorservice/v1/request_response.proto +4 -0
  52. package/sdk-core/crates/common/protos/api_upstream/temporal/api/schedule/v1/message.proto +2 -2
  53. package/sdk-core/crates/common/protos/api_upstream/temporal/api/taskqueue/v1/message.proto +2 -0
  54. package/sdk-core/crates/common/protos/api_upstream/temporal/api/worker/v1/message.proto +4 -7
  55. package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflow/v1/message.proto +80 -22
  56. package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +347 -23
  57. package/sdk-core/crates/common/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +242 -43
  58. package/sdk-core/crates/common/protos/local/temporal/sdk/core/core_interface.proto +15 -0
  59. package/sdk-core/crates/common/protos/local/temporal/sdk/core/nexus/nexus.proto +9 -2
  60. package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +8 -0
  61. package/sdk-core/crates/common/protos/local/temporal/sdk/core/workflow_commands/workflow_commands.proto +22 -5
  62. package/sdk-core/crates/common/src/activity_definition.rs +20 -0
  63. package/sdk-core/crates/common/src/data_converters.rs +770 -0
  64. package/sdk-core/crates/common/src/envconfig.rs +5 -0
  65. package/sdk-core/crates/common/src/lib.rs +15 -211
  66. package/sdk-core/crates/common/src/payload_visitor.rs +648 -0
  67. package/sdk-core/crates/common/src/priority.rs +110 -0
  68. package/sdk-core/crates/common/src/protos/canned_histories.rs +19 -0
  69. package/sdk-core/crates/common/src/protos/history_builder.rs +45 -0
  70. package/sdk-core/crates/common/src/protos/history_info.rs +2 -0
  71. package/sdk-core/crates/common/src/protos/mod.rs +134 -27
  72. package/sdk-core/crates/common/src/protos/task_token.rs +3 -3
  73. package/sdk-core/crates/common/src/protos/utilities.rs +11 -0
  74. package/sdk-core/crates/{sdk-core → common}/src/telemetry/log_export.rs +11 -16
  75. package/sdk-core/crates/common/src/telemetry/metrics/core.rs +125 -0
  76. package/sdk-core/crates/common/src/telemetry/metrics.rs +272 -225
  77. package/sdk-core/crates/{sdk-core → common}/src/telemetry/otel.rs +8 -13
  78. package/sdk-core/crates/{sdk-core → common}/src/telemetry/prometheus_meter.rs +49 -50
  79. package/sdk-core/crates/{sdk-core → common}/src/telemetry/prometheus_server.rs +2 -3
  80. package/sdk-core/crates/common/src/telemetry.rs +278 -19
  81. package/sdk-core/crates/common/src/worker.rs +68 -636
  82. package/sdk-core/crates/common/src/workflow_definition.rs +60 -0
  83. package/sdk-core/crates/macros/Cargo.toml +5 -1
  84. package/sdk-core/crates/macros/src/activities_definitions.rs +585 -0
  85. package/sdk-core/crates/macros/src/fsm_impl.rs +507 -0
  86. package/sdk-core/crates/macros/src/lib.rs +138 -512
  87. package/sdk-core/crates/macros/src/macro_utils.rs +106 -0
  88. package/sdk-core/crates/macros/src/workflow_definitions.rs +1224 -0
  89. package/sdk-core/crates/sdk/Cargo.toml +19 -6
  90. package/sdk-core/crates/sdk/README.md +415 -0
  91. package/sdk-core/crates/sdk/src/activities.rs +417 -0
  92. package/sdk-core/crates/sdk/src/interceptors.rs +1 -1
  93. package/sdk-core/crates/sdk/src/lib.rs +759 -442
  94. package/sdk-core/crates/sdk/src/workflow_context/options.rs +64 -35
  95. package/sdk-core/crates/sdk/src/workflow_context.rs +1033 -289
  96. package/sdk-core/crates/sdk/src/workflow_future.rs +277 -213
  97. package/sdk-core/crates/sdk/src/workflows.rs +711 -0
  98. package/sdk-core/crates/sdk-core/Cargo.toml +59 -65
  99. package/sdk-core/crates/sdk-core/benches/workflow_replay_bench.rs +45 -54
  100. package/sdk-core/crates/sdk-core/machine_coverage/ActivityMachine_Coverage.puml +1 -1
  101. package/sdk-core/crates/sdk-core/src/abstractions.rs +6 -10
  102. package/sdk-core/crates/sdk-core/src/core_tests/activity_tasks.rs +6 -5
  103. package/sdk-core/crates/sdk-core/src/core_tests/mod.rs +22 -21
  104. package/sdk-core/crates/sdk-core/src/core_tests/queries.rs +21 -25
  105. package/sdk-core/crates/sdk-core/src/core_tests/replay_flag.rs +7 -10
  106. package/sdk-core/crates/sdk-core/src/core_tests/updates.rs +14 -17
  107. package/sdk-core/crates/sdk-core/src/core_tests/workers.rs +647 -27
  108. package/sdk-core/crates/sdk-core/src/core_tests/workflow_tasks.rs +46 -41
  109. package/sdk-core/crates/sdk-core/src/ephemeral_server/mod.rs +13 -16
  110. package/sdk-core/crates/sdk-core/src/histfetch.rs +20 -10
  111. package/sdk-core/crates/sdk-core/src/lib.rs +60 -123
  112. package/sdk-core/crates/sdk-core/src/pollers/mod.rs +4 -9
  113. package/sdk-core/crates/sdk-core/src/pollers/poll_buffer.rs +411 -32
  114. package/sdk-core/crates/sdk-core/src/protosext/mod.rs +2 -2
  115. package/sdk-core/crates/sdk-core/src/replay/mod.rs +14 -5
  116. package/sdk-core/crates/sdk-core/src/telemetry/metrics.rs +183 -198
  117. package/sdk-core/crates/sdk-core/src/telemetry/mod.rs +3 -281
  118. package/sdk-core/crates/sdk-core/src/test_help/integ_helpers.rs +35 -16
  119. package/sdk-core/crates/sdk-core/src/test_help/unit_helpers.rs +3 -6
  120. package/sdk-core/crates/sdk-core/src/worker/activities/activity_heartbeat_manager.rs +1 -0
  121. package/sdk-core/crates/sdk-core/src/worker/activities/local_activities.rs +11 -14
  122. package/sdk-core/crates/sdk-core/src/worker/activities.rs +16 -19
  123. package/sdk-core/crates/sdk-core/src/worker/client/mocks.rs +11 -5
  124. package/sdk-core/crates/sdk-core/src/worker/client.rs +104 -86
  125. package/sdk-core/crates/sdk-core/src/worker/heartbeat.rs +10 -14
  126. package/sdk-core/crates/sdk-core/src/worker/mod.rs +1175 -241
  127. package/sdk-core/crates/sdk-core/src/worker/nexus.rs +150 -23
  128. package/sdk-core/crates/sdk-core/src/worker/slot_provider.rs +2 -2
  129. package/sdk-core/crates/sdk-core/src/worker/tuner/fixed_size.rs +2 -2
  130. package/sdk-core/crates/sdk-core/src/worker/tuner/resource_based.rs +25 -27
  131. package/sdk-core/crates/sdk-core/src/worker/tuner.rs +64 -44
  132. package/sdk-core/crates/sdk-core/src/worker/workflow/driven_workflow.rs +9 -3
  133. package/sdk-core/crates/sdk-core/src/worker/workflow/machines/patch_state_machine.rs +5 -8
  134. package/sdk-core/crates/sdk-core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +21 -22
  135. package/sdk-core/crates/sdk-core/src/worker/workflow/machines/workflow_machines.rs +28 -4
  136. package/sdk-core/crates/sdk-core/src/worker/workflow/managed_run.rs +20 -41
  137. package/sdk-core/crates/sdk-core/src/worker/workflow/mod.rs +50 -9
  138. package/sdk-core/crates/sdk-core/src/worker/workflow/run_cache.rs +4 -7
  139. package/sdk-core/crates/sdk-core/src/worker/workflow/wft_extraction.rs +2 -4
  140. package/sdk-core/crates/sdk-core/src/worker/workflow/wft_poller.rs +8 -9
  141. package/sdk-core/crates/sdk-core/src/worker/workflow/workflow_stream.rs +1 -3
  142. package/sdk-core/crates/sdk-core/tests/activities_procmacro.rs +6 -0
  143. package/sdk-core/crates/sdk-core/tests/activities_trybuild/basic_pass.rs +54 -0
  144. package/sdk-core/crates/sdk-core/tests/activities_trybuild/invalid_self_type_fail.rs +18 -0
  145. package/sdk-core/crates/sdk-core/tests/activities_trybuild/invalid_self_type_fail.stderr +5 -0
  146. package/sdk-core/crates/sdk-core/tests/activities_trybuild/missing_context_fail.rs +14 -0
  147. package/sdk-core/crates/sdk-core/tests/activities_trybuild/missing_context_fail.stderr +5 -0
  148. package/sdk-core/crates/sdk-core/tests/activities_trybuild/multi_arg_pass.rs +48 -0
  149. package/sdk-core/crates/sdk-core/tests/activities_trybuild/no_input_pass.rs +14 -0
  150. package/sdk-core/crates/sdk-core/tests/activities_trybuild/no_return_type_pass.rs +19 -0
  151. package/sdk-core/crates/sdk-core/tests/cloud_tests.rs +14 -5
  152. package/sdk-core/crates/sdk-core/tests/common/activity_functions.rs +55 -0
  153. package/sdk-core/crates/sdk-core/tests/common/mod.rs +281 -236
  154. package/sdk-core/crates/sdk-core/tests/common/workflows.rs +41 -28
  155. package/sdk-core/crates/sdk-core/tests/global_metric_tests.rs +9 -14
  156. package/sdk-core/crates/sdk-core/tests/heavy_tests/fuzzy_workflow.rs +73 -66
  157. package/sdk-core/crates/sdk-core/tests/heavy_tests.rs +306 -268
  158. package/sdk-core/crates/sdk-core/tests/integ_tests/async_activity_client_tests.rs +230 -0
  159. package/sdk-core/crates/sdk-core/tests/integ_tests/client_tests.rs +94 -57
  160. package/sdk-core/crates/sdk-core/tests/integ_tests/data_converter_tests.rs +381 -0
  161. package/sdk-core/crates/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +37 -38
  162. package/sdk-core/crates/sdk-core/tests/integ_tests/heartbeat_tests.rs +49 -40
  163. package/sdk-core/crates/sdk-core/tests/integ_tests/metrics_tests.rs +447 -300
  164. package/sdk-core/crates/sdk-core/tests/integ_tests/pagination_tests.rs +50 -45
  165. package/sdk-core/crates/sdk-core/tests/integ_tests/polling_tests.rs +157 -157
  166. package/sdk-core/crates/sdk-core/tests/integ_tests/queries_tests.rs +103 -89
  167. package/sdk-core/crates/sdk-core/tests/integ_tests/update_tests.rs +609 -463
  168. package/sdk-core/crates/sdk-core/tests/integ_tests/visibility_tests.rs +80 -62
  169. package/sdk-core/crates/sdk-core/tests/integ_tests/worker_heartbeat_tests.rs +389 -265
  170. package/sdk-core/crates/sdk-core/tests/integ_tests/worker_tests.rs +250 -185
  171. package/sdk-core/crates/sdk-core/tests/integ_tests/worker_versioning_tests.rs +52 -49
  172. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_client_tests.rs +180 -0
  173. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/activities.rs +437 -327
  174. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_external.rs +82 -58
  175. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/cancel_wf.rs +56 -30
  176. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/child_workflows.rs +364 -251
  177. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/client_interactions.rs +552 -0
  178. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/continue_as_new.rs +110 -46
  179. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/determinism.rs +243 -149
  180. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/eager.rs +98 -32
  181. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +1475 -1040
  182. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/modify_wf_properties.rs +73 -43
  183. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +402 -245
  184. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/patches.rs +343 -207
  185. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/queries.rs +415 -0
  186. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/replay.rs +96 -36
  187. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/resets.rs +155 -140
  188. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/signals.rs +183 -113
  189. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/stickyness.rs +85 -44
  190. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/timers.rs +142 -48
  191. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests/upsert_search_attrs.rs +73 -56
  192. package/sdk-core/crates/sdk-core/tests/integ_tests/workflow_tests.rs +365 -242
  193. package/sdk-core/crates/sdk-core/tests/main.rs +22 -16
  194. package/sdk-core/crates/sdk-core/tests/manual_tests.rs +233 -187
  195. package/sdk-core/crates/sdk-core/tests/runner.rs +4 -6
  196. package/sdk-core/crates/sdk-core/tests/shared_tests/mod.rs +73 -27
  197. package/sdk-core/crates/sdk-core/tests/shared_tests/priority.rs +107 -84
  198. package/sdk-core/crates/sdk-core/tests/workflows_procmacro.rs +6 -0
  199. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/async_query_fail.rs +26 -0
  200. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/async_query_fail.stderr +5 -0
  201. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/basic_pass.rs +49 -0
  202. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/minimal_pass.rs +21 -0
  203. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/mut_query_fail.rs +26 -0
  204. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/mut_query_fail.stderr +5 -0
  205. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/sync_run_fail.rs +21 -0
  206. package/sdk-core/crates/sdk-core/tests/workflows_trybuild/sync_run_fail.stderr +5 -0
  207. package/sdk-core/crates/sdk-core-c-bridge/Cargo.toml +8 -1
  208. package/sdk-core/crates/sdk-core-c-bridge/include/temporal-sdk-core-c-bridge.h +37 -26
  209. package/sdk-core/crates/sdk-core-c-bridge/src/client.rs +180 -87
  210. package/sdk-core/crates/sdk-core-c-bridge/src/lib.rs +89 -5
  211. package/sdk-core/crates/sdk-core-c-bridge/src/metric.rs +10 -16
  212. package/sdk-core/crates/sdk-core-c-bridge/src/runtime.rs +59 -67
  213. package/sdk-core/crates/sdk-core-c-bridge/src/testing.rs +10 -10
  214. package/sdk-core/crates/sdk-core-c-bridge/src/tests/context.rs +57 -22
  215. package/sdk-core/crates/sdk-core-c-bridge/src/tests/mod.rs +108 -12
  216. package/sdk-core/crates/sdk-core-c-bridge/src/tests/utils.rs +9 -52
  217. package/sdk-core/crates/sdk-core-c-bridge/src/worker.rs +74 -91
  218. package/sdk-core/rustfmt.toml +2 -1
  219. package/src/client.rs +206 -289
  220. package/src/helpers/try_into_js.rs +88 -2
  221. package/src/metrics.rs +277 -35
  222. package/src/runtime.rs +94 -45
  223. package/src/testing.rs +9 -16
  224. package/src/worker.rs +86 -68
  225. package/ts/native.ts +39 -3
  226. package/sdk-core/crates/client/src/workflow_handle/mod.rs +0 -212
  227. package/sdk-core/crates/common/src/errors.rs +0 -85
  228. package/sdk-core/crates/common/tests/worker_task_types_test.rs +0 -129
  229. package/sdk-core/crates/macros/LICENSE.txt +0 -21
  230. package/sdk-core/crates/sdk/src/activity_context.rs +0 -238
  231. package/sdk-core/crates/sdk/src/app_data.rs +0 -37
  232. package/sdk-core/crates/sdk-core/tests/integ_tests/activity_functions.rs +0 -5
  233. 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,137 +239,17 @@ 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
- pub activity_execution_latency: Arc<AtomicU64>,
204
- pub local_activity_execution_latency: Arc<AtomicU64>,
205
- pub workflow_task_execution_latency: Arc<AtomicU64>,
206
- pub nexus_task_execution_latency: Arc<AtomicU64>,
207
- }
208
-
209
- impl WorkerHeartbeatMetrics {
210
- pub fn get_metric(&self, name: &str) -> Option<HeartbeatMetricType> {
211
- match name {
212
- "sticky_cache_size" => Some(HeartbeatMetricType::Individual(
213
- self.sticky_cache_size.clone(),
214
- )),
215
- "sticky_cache_hit" => Some(HeartbeatMetricType::Individual(
216
- self.total_sticky_cache_hit.clone(),
217
- )),
218
- "sticky_cache_miss" => Some(HeartbeatMetricType::Individual(
219
- self.total_sticky_cache_miss.clone(),
220
- )),
221
- "num_pollers" => Some(HeartbeatMetricType::WithLabel {
222
- label_key: "poller_type".to_string(),
223
- metrics: self.num_pollers.as_map(),
224
- }),
225
- "worker_task_slots_used" => Some(HeartbeatMetricType::WithLabel {
226
- label_key: "worker_type".to_string(),
227
- metrics: self.worker_task_slots_used.as_map(),
228
- }),
229
- "worker_task_slots_available" => Some(HeartbeatMetricType::WithLabel {
230
- label_key: "worker_type".to_string(),
231
- metrics: self.worker_task_slots_available.as_map(),
232
- }),
233
- "workflow_task_execution_failed" => Some(HeartbeatMetricType::Individual(
234
- self.workflow_task_execution_failed.clone(),
235
- )),
236
- "activity_execution_failed" => Some(HeartbeatMetricType::Individual(
237
- self.activity_execution_failed.clone(),
238
- )),
239
- "nexus_task_execution_failed" => Some(HeartbeatMetricType::Individual(
240
- self.nexus_task_execution_failed.clone(),
241
- )),
242
- "local_activity_execution_failed" => Some(HeartbeatMetricType::Individual(
243
- self.local_activity_execution_failed.clone(),
244
- )),
245
- "activity_execution_latency" => Some(HeartbeatMetricType::Individual(
246
- self.activity_execution_latency.clone(),
247
- )),
248
- "local_activity_execution_latency" => Some(HeartbeatMetricType::Individual(
249
- self.local_activity_execution_latency.clone(),
250
- )),
251
- "workflow_task_execution_latency" => Some(HeartbeatMetricType::Individual(
252
- self.workflow_task_execution_latency.clone(),
253
- )),
254
- "nexus_task_execution_latency" => Some(HeartbeatMetricType::Individual(
255
- self.nexus_task_execution_latency.clone(),
256
- )),
257
- _ => None,
258
- }
259
- }
260
- }
261
-
262
- #[derive(Debug, Clone, derive_builder::Builder)]
242
+ /// Parameters used when creating a new metric instrument (name, description, unit).
243
+ #[derive(Debug, Clone, bon::Builder)]
263
244
  pub struct MetricParameters {
264
245
  /// The name for the new metric/instrument
265
- #[builder(setter(into))]
246
+ #[builder(into)]
266
247
  pub name: Cow<'static, str>,
267
248
  /// A description that will appear in metadata if the backend supports it
268
- #[builder(setter(into), default = "\"\".into()")]
249
+ #[builder(into, default = Cow::Borrowed(""))]
269
250
  pub description: Cow<'static, str>,
270
251
  /// Unit information that will appear in metadata if the backend supports it
271
- #[builder(setter(into), default = "\"\".into()")]
252
+ #[builder(into, default = Cow::Borrowed(""))]
272
253
  pub unit: Cow<'static, str>,
273
254
  }
274
255
  impl From<&'static str> for MetricParameters {
@@ -282,11 +263,50 @@ impl From<&'static str> for MetricParameters {
282
263
  }
283
264
 
284
265
  /// Wraps a [CoreMeter] to enable the attaching of default labels to metrics. Cloning is cheap.
285
- #[derive(derive_more::Constructor, Clone, Debug)]
266
+ #[derive(Clone, Debug)]
286
267
  pub struct TemporalMeter {
287
- pub inner: Arc<dyn CoreMeter>,
288
- pub default_attribs: NewAttributes,
289
- 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
+ }
290
310
  }
291
311
 
292
312
  impl Deref for TemporalMeter {
@@ -338,32 +358,37 @@ impl CoreMeter for Arc<dyn CoreMeter> {
338
358
  #[derive(Clone, Debug)]
339
359
  #[non_exhaustive]
340
360
  pub enum MetricAttributes {
341
- #[cfg(feature = "otel_impls")]
361
+ /// OpenTelemetry-backed attributes with key-value pairs.
362
+ #[cfg(feature = "otel")]
342
363
  OTel {
364
+ /// The OpenTelemetry key-value pairs for this attribute set.
343
365
  kvs: Arc<Vec<opentelemetry::KeyValue>>,
344
366
  },
367
+ /// Prometheus-backed attributes with ordered labels.
345
368
  Prometheus {
369
+ /// The ordered label set.
346
370
  labels: Arc<OrderedPromLabelSet>,
347
371
  },
348
- Buffer(BufferAttributes),
349
- 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.
350
379
  NoOp(Arc<HashMap<String, String>>),
380
+ /// Empty placeholder attributes.
351
381
  Empty,
352
382
  }
353
383
 
354
- /// A reference to some attributes created lang side.
355
- pub trait CustomMetricAttributes: Debug + Send + Sync {
356
- /// Must be implemented to work around existing type system restrictions, see
357
- /// [here](https://internals.rust-lang.org/t/downcast-not-from-any-but-from-any-trait/16736/12)
358
- fn as_any(self: Arc<Self>) -> Arc<dyn Any + Send + Sync>;
359
- }
360
-
361
384
  /// Options that are attached to metrics on a per-call basis
362
385
  #[derive(Clone, Debug, Default, derive_more::Constructor)]
363
386
  pub struct NewAttributes {
387
+ /// The key-value pairs for this attribute set.
364
388
  pub attributes: Vec<MetricKeyValue>,
365
389
  }
366
390
  impl NewAttributes {
391
+ /// Append additional key-value pairs to this attribute set.
367
392
  pub fn extend(&mut self, new_kvs: impl IntoIterator<Item = MetricKeyValue>) {
368
393
  self.attributes.extend(new_kvs)
369
394
  }
@@ -392,10 +417,13 @@ impl From<NewAttributes> for HashMap<String, String> {
392
417
  /// A K/V pair that can be used to label a specific recording of a metric
393
418
  #[derive(Clone, Debug, PartialEq)]
394
419
  pub struct MetricKeyValue {
420
+ /// The label key.
395
421
  pub key: String,
422
+ /// The label value.
396
423
  pub value: MetricValue,
397
424
  }
398
425
  impl MetricKeyValue {
426
+ /// Create a new key-value pair.
399
427
  pub fn new(key: impl Into<String>, value: impl Into<MetricValue>) -> Self {
400
428
  Self {
401
429
  key: key.into(),
@@ -407,9 +435,13 @@ impl MetricKeyValue {
407
435
  /// Values metric labels may assume
408
436
  #[derive(Clone, Debug, PartialEq, derive_more::From)]
409
437
  pub enum MetricValue {
438
+ /// A string label value.
410
439
  String(String),
440
+ /// An integer label value.
411
441
  Int(i64),
442
+ /// A floating-point label value.
412
443
  Float(f64),
444
+ /// A boolean label value.
413
445
  Bool(bool),
414
446
  // can add array if needed
415
447
  }
@@ -429,6 +461,7 @@ impl Display for MetricValue {
429
461
  }
430
462
  }
431
463
 
464
+ /// Trait for metric instruments that can be bound to a set of attributes.
432
465
  pub trait MetricAttributable<Base> {
433
466
  /// Replace any existing attributes on this metric with new ones, and return a new copy
434
467
  /// of the metric, or a base version, which can be used to record values.
@@ -445,6 +478,7 @@ pub trait MetricAttributable<Base> {
445
478
  ) -> Result<Base, Box<dyn std::error::Error>>;
446
479
  }
447
480
 
481
+ /// A metric that lazily binds to its attributes on first use, caching the result.
448
482
  #[derive(Clone)]
449
483
  pub struct LazyBoundMetric<T, B> {
450
484
  metric: T,
@@ -452,27 +486,33 @@ pub struct LazyBoundMetric<T, B> {
452
486
  bound_cache: OnceLock<B>,
453
487
  }
454
488
  impl<T, B> LazyBoundMetric<T, B> {
489
+ /// Replace the attributes and invalidate the cached binding.
455
490
  pub fn update_attributes(&mut self, new_attributes: MetricAttributes) {
456
491
  self.attributes = new_attributes;
457
492
  self.bound_cache = OnceLock::new();
458
493
  }
459
494
  }
460
495
 
496
+ /// Base trait for counter implementations.
461
497
  pub trait CounterBase: Send + Sync {
498
+ /// Increment the counter by `value`.
462
499
  fn adds(&self, value: u64);
463
500
  }
464
501
 
502
+ /// The lazy-bound inner type for [`Counter`].
465
503
  pub type CounterImpl = LazyBoundMetric<
466
504
  Arc<dyn MetricAttributable<Box<dyn CounterBase>> + Send + Sync>,
467
505
  Arc<dyn CounterBase>,
468
506
  >;
469
507
 
508
+ /// A counter metric instrument that optionally tracks values in memory for heartbeating.
470
509
  #[derive(Clone)]
471
510
  pub struct Counter {
472
511
  primary: CounterImpl,
473
512
  in_memory: Option<HeartbeatMetricType>,
474
513
  }
475
514
  impl Counter {
515
+ /// Create a new counter from an attributable metric source.
476
516
  pub fn new(inner: Arc<dyn MetricAttributable<Box<dyn CounterBase>> + Send + Sync>) -> Self {
477
517
  Self {
478
518
  primary: LazyBoundMetric {
@@ -484,6 +524,7 @@ impl Counter {
484
524
  }
485
525
  }
486
526
 
527
+ /// Create a new counter with an additional in-memory tracker for heartbeat reporting.
487
528
  pub fn new_with_in_memory(
488
529
  primary: Arc<dyn MetricAttributable<Box<dyn CounterBase>> + Send + Sync>,
489
530
  in_memory: HeartbeatMetricType,
@@ -498,6 +539,7 @@ impl Counter {
498
539
  }
499
540
  }
500
541
 
542
+ /// Increment the counter by `value` with the given attributes.
501
543
  pub fn add(&self, value: u64, attributes: &MetricAttributes) {
502
544
  match self.primary.metric.with_attributes(attributes) {
503
545
  Ok(base) => base.adds(value),
@@ -511,6 +553,7 @@ impl Counter {
511
553
  }
512
554
  }
513
555
 
556
+ /// Replace the attributes on the primary metric.
514
557
  pub fn update_attributes(&mut self, new_attributes: MetricAttributes) {
515
558
  self.primary.update_attributes(new_attributes.clone());
516
559
  }
@@ -554,14 +597,18 @@ impl MetricAttributable<Counter> for Counter {
554
597
  }
555
598
  }
556
599
 
600
+ /// Base trait for `u64` histogram implementations.
557
601
  pub trait HistogramBase: Send + Sync {
602
+ /// Record a `u64` observation.
558
603
  fn records(&self, value: u64);
559
604
  }
605
+ /// A `u64` histogram metric instrument.
560
606
  pub type Histogram = LazyBoundMetric<
561
607
  Arc<dyn MetricAttributable<Box<dyn HistogramBase>> + Send + Sync>,
562
608
  Arc<dyn HistogramBase>,
563
609
  >;
564
610
  impl Histogram {
611
+ /// Create a new histogram from an attributable metric source.
565
612
  pub fn new(inner: Arc<dyn MetricAttributable<Box<dyn HistogramBase>> + Send + Sync>) -> Self {
566
613
  Self {
567
614
  metric: inner,
@@ -569,6 +616,7 @@ impl Histogram {
569
616
  bound_cache: OnceLock::new(),
570
617
  }
571
618
  }
619
+ /// Record a `u64` value with the given attributes.
572
620
  pub fn record(&self, value: u64, attributes: &MetricAttributes) {
573
621
  match self.metric.with_attributes(attributes) {
574
622
  Ok(base) => {
@@ -607,14 +655,18 @@ impl MetricAttributable<Histogram> for Histogram {
607
655
  }
608
656
  }
609
657
 
658
+ /// Base trait for `f64` histogram implementations.
610
659
  pub trait HistogramF64Base: Send + Sync {
660
+ /// Record an `f64` observation.
611
661
  fn records(&self, value: f64);
612
662
  }
663
+ /// An `f64` histogram metric instrument.
613
664
  pub type HistogramF64 = LazyBoundMetric<
614
665
  Arc<dyn MetricAttributable<Box<dyn HistogramF64Base>> + Send + Sync>,
615
666
  Arc<dyn HistogramF64Base>,
616
667
  >;
617
668
  impl HistogramF64 {
669
+ /// Create a new `f64` histogram from an attributable metric source.
618
670
  pub fn new(
619
671
  inner: Arc<dyn MetricAttributable<Box<dyn HistogramF64Base>> + Send + Sync>,
620
672
  ) -> Self {
@@ -624,6 +676,7 @@ impl HistogramF64 {
624
676
  bound_cache: OnceLock::new(),
625
677
  }
626
678
  }
679
+ /// Record an `f64` value with the given attributes.
627
680
  pub fn record(&self, value: f64, attributes: &MetricAttributes) {
628
681
  match self.metric.with_attributes(attributes) {
629
682
  Ok(base) => {
@@ -662,21 +715,26 @@ impl MetricAttributable<HistogramF64> for HistogramF64 {
662
715
  }
663
716
  }
664
717
 
718
+ /// Base trait for duration histogram implementations.
665
719
  pub trait HistogramDurationBase: Send + Sync {
720
+ /// Record a duration observation.
666
721
  fn records(&self, value: Duration);
667
722
  }
668
723
 
724
+ /// The lazy-bound inner type for [`HistogramDuration`].
669
725
  pub type HistogramDurationImpl = LazyBoundMetric<
670
726
  Arc<dyn MetricAttributable<Box<dyn HistogramDurationBase>> + Send + Sync>,
671
727
  Arc<dyn HistogramDurationBase>,
672
728
  >;
673
729
 
730
+ /// A histogram that records [`Duration`] values, optionally tracking in memory for heartbeating.
674
731
  #[derive(Clone)]
675
732
  pub struct HistogramDuration {
676
733
  primary: HistogramDurationImpl,
677
734
  in_memory: Option<HeartbeatMetricType>,
678
735
  }
679
736
  impl HistogramDuration {
737
+ /// Create a new duration histogram from an attributable metric source.
680
738
  pub fn new(
681
739
  inner: Arc<dyn MetricAttributable<Box<dyn HistogramDurationBase>> + Send + Sync>,
682
740
  ) -> Self {
@@ -689,6 +747,7 @@ impl HistogramDuration {
689
747
  in_memory: None,
690
748
  }
691
749
  }
750
+ /// Create a new duration histogram with an additional in-memory tracker for heartbeat reporting.
692
751
  pub fn new_with_in_memory(
693
752
  primary: Arc<dyn MetricAttributable<Box<dyn HistogramDurationBase>> + Send + Sync>,
694
753
  in_memory: HeartbeatMetricType,
@@ -702,6 +761,7 @@ impl HistogramDuration {
702
761
  in_memory: Some(in_memory),
703
762
  }
704
763
  }
764
+ /// Record a duration value with the given attributes.
705
765
  pub fn record(&self, value: Duration, attributes: &MetricAttributes) {
706
766
  match self.primary.metric.with_attributes(attributes) {
707
767
  Ok(base) => {
@@ -717,6 +777,7 @@ impl HistogramDuration {
717
777
  }
718
778
  }
719
779
 
780
+ /// Replace the attributes on the primary metric.
720
781
  pub fn update_attributes(&mut self, new_attributes: MetricAttributes) {
721
782
  self.primary.update_attributes(new_attributes.clone());
722
783
  }
@@ -758,21 +819,26 @@ impl MetricAttributable<HistogramDuration> for HistogramDuration {
758
819
  }
759
820
  }
760
821
 
822
+ /// Base trait for `u64` gauge implementations.
761
823
  pub trait GaugeBase: Send + Sync {
824
+ /// Record a `u64` gauge value.
762
825
  fn records(&self, value: u64);
763
826
  }
764
827
 
828
+ /// The lazy-bound inner type for [`Gauge`].
765
829
  pub type GaugeImpl = LazyBoundMetric<
766
830
  Arc<dyn MetricAttributable<Box<dyn GaugeBase>> + Send + Sync>,
767
831
  Arc<dyn GaugeBase>,
768
832
  >;
769
833
 
834
+ /// A gauge metric instrument that optionally tracks values in memory for heartbeating.
770
835
  #[derive(Clone)]
771
836
  pub struct Gauge {
772
837
  primary: GaugeImpl,
773
838
  in_memory: Option<HeartbeatMetricType>,
774
839
  }
775
840
  impl Gauge {
841
+ /// Create a new gauge from an attributable metric source.
776
842
  pub fn new(inner: Arc<dyn MetricAttributable<Box<dyn GaugeBase>> + Send + Sync>) -> Self {
777
843
  Self {
778
844
  primary: LazyBoundMetric {
@@ -784,6 +850,7 @@ impl Gauge {
784
850
  }
785
851
  }
786
852
 
853
+ /// Create a new gauge with an additional in-memory tracker for heartbeat reporting.
787
854
  pub fn new_with_in_memory(
788
855
  primary: Arc<dyn MetricAttributable<Box<dyn GaugeBase>> + Send + Sync>,
789
856
  in_memory: HeartbeatMetricType,
@@ -798,6 +865,7 @@ impl Gauge {
798
865
  }
799
866
  }
800
867
 
868
+ /// Record a `u64` gauge value with the given attributes.
801
869
  pub fn record(&self, value: u64, attributes: &MetricAttributes) {
802
870
  match self.primary.metric.with_attributes(attributes) {
803
871
  Ok(base) => base.records(value),
@@ -811,6 +879,7 @@ impl Gauge {
811
879
  }
812
880
  }
813
881
 
882
+ /// Replace the attributes on the primary metric.
814
883
  pub fn update_attributes(&mut self, new_attributes: MetricAttributes) {
815
884
  self.primary.update_attributes(new_attributes.clone());
816
885
  }
@@ -852,14 +921,18 @@ impl MetricAttributable<Gauge> for Gauge {
852
921
  }
853
922
  }
854
923
 
924
+ /// Base trait for `f64` gauge implementations.
855
925
  pub trait GaugeF64Base: Send + Sync {
926
+ /// Record an `f64` gauge value.
856
927
  fn records(&self, value: f64);
857
928
  }
929
+ /// An `f64` gauge metric instrument.
858
930
  pub type GaugeF64 = LazyBoundMetric<
859
931
  Arc<dyn MetricAttributable<Box<dyn GaugeF64Base>> + Send + Sync>,
860
932
  Arc<dyn GaugeF64Base>,
861
933
  >;
862
934
  impl GaugeF64 {
935
+ /// Create a new `f64` gauge from an attributable metric source.
863
936
  pub fn new(inner: Arc<dyn MetricAttributable<Box<dyn GaugeF64Base>> + Send + Sync>) -> Self {
864
937
  Self {
865
938
  metric: inner,
@@ -867,6 +940,7 @@ impl GaugeF64 {
867
940
  bound_cache: OnceLock::new(),
868
941
  }
869
942
  }
943
+ /// Record an `f64` gauge value with the given attributes.
870
944
  pub fn record(&self, value: f64, attributes: &MetricAttributes) {
871
945
  match self.metric.with_attributes(attributes) {
872
946
  Ok(base) => {
@@ -905,88 +979,7 @@ impl MetricAttributable<GaugeF64> for GaugeF64 {
905
979
  }
906
980
  }
907
981
 
908
- #[derive(Debug, Clone)]
909
- pub enum MetricEvent<I: BufferInstrumentRef> {
910
- Create {
911
- params: MetricParameters,
912
- /// Once you receive this event, call `set` on this with the initialized instrument
913
- /// reference
914
- populate_into: LazyBufferInstrument<I>,
915
- kind: MetricKind,
916
- },
917
- CreateAttributes {
918
- /// Once you receive this event, call `set` on this with the initialized attributes
919
- populate_into: BufferAttributes,
920
- /// If not `None`, use these already-initialized attributes as the base (extended with
921
- /// `attributes`) for the ones you are about to initialize.
922
- append_from: Option<BufferAttributes>,
923
- attributes: Vec<MetricKeyValue>,
924
- },
925
- Update {
926
- instrument: LazyBufferInstrument<I>,
927
- attributes: BufferAttributes,
928
- update: MetricUpdateVal,
929
- },
930
- }
931
- #[derive(Debug, Clone, Copy)]
932
- pub enum MetricKind {
933
- Counter,
934
- Gauge,
935
- GaugeF64,
936
- Histogram,
937
- HistogramF64,
938
- HistogramDuration,
939
- }
940
- #[derive(Debug, Clone, Copy)]
941
- pub enum MetricUpdateVal {
942
- Delta(u64),
943
- DeltaF64(f64),
944
- Value(u64),
945
- ValueF64(f64),
946
- Duration(Duration),
947
- }
948
-
949
- pub trait MetricCallBufferer<I: BufferInstrumentRef>: Send + Sync {
950
- fn retrieve(&self) -> Vec<MetricEvent<I>>;
951
- }
952
-
953
- /// A lazy reference to some metrics buffer attributes
954
- pub type BufferAttributes = LazyRef<Arc<dyn CustomMetricAttributes + 'static>>;
955
-
956
- /// Types lang uses to contain references to its lang-side defined instrument references must
957
- /// implement this marker trait
958
- pub trait BufferInstrumentRef {}
959
- /// A lazy reference to a metrics buffer instrument
960
- pub type LazyBufferInstrument<T> = LazyRef<Arc<T>>;
961
-
962
- #[derive(Debug, Clone)]
963
- pub struct LazyRef<T> {
964
- to_be_initted: Arc<OnceLock<T>>,
965
- }
966
- impl<T> LazyRef<T> {
967
- pub fn hole() -> Self {
968
- Self {
969
- to_be_initted: Arc::new(OnceLock::new()),
970
- }
971
- }
972
-
973
- /// Get the reference you previously initialized
974
- ///
975
- /// # Panics
976
- /// If `set` has not already been called. You must set the reference before using it.
977
- pub fn get(&self) -> &T {
978
- self.to_be_initted
979
- .get()
980
- .expect("You must initialize the reference before using it")
981
- }
982
-
983
- /// Assigns a value to fill this reference.
984
- /// Returns according to semantics of [OnceLock].
985
- pub fn set(&self, val: T) -> Result<(), T> {
986
- self.to_be_initted.set(val)
987
- }
988
- }
989
-
982
+ /// A [`CoreMeter`] implementation that discards all metric recordings.
990
983
  #[derive(Debug)]
991
984
  pub struct NoOpCoreMeter;
992
985
  impl CoreMeter for NoOpCoreMeter {
@@ -1047,6 +1040,7 @@ macro_rules! impl_metric_attributable {
1047
1040
  };
1048
1041
  }
1049
1042
 
1043
+ /// A no-op metric instrument that discards all recordings.
1050
1044
  pub struct NoOpInstrument;
1051
1045
  macro_rules! impl_no_op {
1052
1046
  ($base_trait:ident, $value_type:ty) => {
@@ -1107,8 +1101,8 @@ mod tests {
1107
1101
  }
1108
1102
  }
1109
1103
 
1110
- #[cfg(feature = "otel_impls")]
1111
- mod otel_impls {
1104
+ #[cfg(feature = "otel")]
1105
+ mod otel {
1112
1106
  use super::*;
1113
1107
  use opentelemetry::{KeyValue, metrics};
1114
1108
 
@@ -1253,14 +1247,17 @@ pub struct OrderedPromLabelSet {
1253
1247
  }
1254
1248
 
1255
1249
  impl OrderedPromLabelSet {
1250
+ /// Create an empty label set.
1256
1251
  pub const fn new() -> Self {
1257
1252
  Self {
1258
1253
  attributes: BTreeMap::new(),
1259
1254
  }
1260
1255
  }
1256
+ /// Iterate over label keys in sorted order.
1261
1257
  pub fn keys_ordered(&self) -> impl Iterator<Item = &str> {
1262
1258
  self.attributes.keys().map(|s| s.as_str())
1263
1259
  }
1260
+ /// Return a map of label keys to their string values, suitable for Prometheus.
1264
1261
  pub fn as_prom_labels(&self) -> HashMap<&str, String> {
1265
1262
  let mut labels = HashMap::new();
1266
1263
  for (k, v) in self.attributes.iter() {
@@ -1268,6 +1265,7 @@ impl OrderedPromLabelSet {
1268
1265
  }
1269
1266
  labels
1270
1267
  }
1268
+ /// Insert a key-value pair, replacing dashes with underscores per Prometheus conventions.
1271
1269
  pub fn add_kv(&mut self, kv: MetricKeyValue) {
1272
1270
  // Replace '-' with '_' per Prom naming requirements
1273
1271
  self.attributes.insert(kv.key.replace('-', "_"), kv.value);
@@ -1283,3 +1281,52 @@ impl From<NewAttributes> for OrderedPromLabelSet {
1283
1281
  me
1284
1282
  }
1285
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
+ }