@temporalio/core-bridge 1.12.0 → 1.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/Cargo.lock +64 -119
  2. package/Cargo.toml +1 -1
  3. package/index.js +3 -2
  4. package/package.json +3 -3
  5. package/releases/aarch64-apple-darwin/index.node +0 -0
  6. package/releases/aarch64-unknown-linux-gnu/index.node +0 -0
  7. package/releases/x86_64-apple-darwin/index.node +0 -0
  8. package/releases/x86_64-pc-windows-msvc/index.node +0 -0
  9. package/releases/x86_64-unknown-linux-gnu/index.node +0 -0
  10. package/sdk-core/.cargo/config.toml +1 -2
  11. package/sdk-core/.github/workflows/per-pr.yml +2 -0
  12. package/sdk-core/AGENTS.md +7 -0
  13. package/sdk-core/Cargo.toml +9 -5
  14. package/sdk-core/README.md +6 -5
  15. package/sdk-core/client/Cargo.toml +3 -2
  16. package/sdk-core/client/src/lib.rs +17 -8
  17. package/sdk-core/client/src/metrics.rs +57 -23
  18. package/sdk-core/client/src/raw.rs +33 -15
  19. package/sdk-core/core/Cargo.toml +11 -9
  20. package/sdk-core/core/benches/workflow_replay.rs +114 -15
  21. package/sdk-core/core/src/core_tests/activity_tasks.rs +18 -18
  22. package/sdk-core/core/src/core_tests/child_workflows.rs +4 -4
  23. package/sdk-core/core/src/core_tests/determinism.rs +6 -6
  24. package/sdk-core/core/src/core_tests/local_activities.rs +20 -20
  25. package/sdk-core/core/src/core_tests/mod.rs +40 -5
  26. package/sdk-core/core/src/core_tests/queries.rs +25 -16
  27. package/sdk-core/core/src/core_tests/replay_flag.rs +3 -3
  28. package/sdk-core/core/src/core_tests/updates.rs +3 -3
  29. package/sdk-core/core/src/core_tests/workers.rs +9 -7
  30. package/sdk-core/core/src/core_tests/workflow_tasks.rs +40 -42
  31. package/sdk-core/core/src/ephemeral_server/mod.rs +1 -19
  32. package/sdk-core/core/src/lib.rs +10 -1
  33. package/sdk-core/core/src/pollers/poll_buffer.rs +2 -2
  34. package/sdk-core/core/src/replay/mod.rs +3 -3
  35. package/sdk-core/core/src/telemetry/metrics.rs +306 -152
  36. package/sdk-core/core/src/telemetry/mod.rs +11 -4
  37. package/sdk-core/core/src/telemetry/otel.rs +134 -131
  38. package/sdk-core/core/src/telemetry/prometheus_meter.rs +885 -0
  39. package/sdk-core/core/src/telemetry/prometheus_server.rs +48 -28
  40. package/sdk-core/core/src/test_help/mod.rs +27 -12
  41. package/sdk-core/core/src/worker/activities/activity_heartbeat_manager.rs +7 -7
  42. package/sdk-core/core/src/worker/activities.rs +4 -4
  43. package/sdk-core/core/src/worker/client/mocks.rs +10 -3
  44. package/sdk-core/core/src/worker/client.rs +68 -5
  45. package/sdk-core/core/src/worker/heartbeat.rs +229 -0
  46. package/sdk-core/core/src/worker/mod.rs +35 -14
  47. package/sdk-core/core/src/worker/tuner/resource_based.rs +4 -4
  48. package/sdk-core/core/src/worker/workflow/history_update.rs +71 -19
  49. package/sdk-core/core/src/worker/workflow/machines/cancel_external_state_machine.rs +1 -2
  50. package/sdk-core/core/src/worker/workflow/machines/child_workflow_state_machine.rs +1 -1
  51. package/sdk-core/core/src/worker/workflow/machines/nexus_operation_state_machine.rs +31 -48
  52. package/sdk-core/core/src/worker/workflow/machines/signal_external_state_machine.rs +1 -2
  53. package/sdk-core/core/src/worker/workflow/machines/upsert_search_attributes_state_machine.rs +3 -3
  54. package/sdk-core/core/src/worker/workflow/machines/workflow_machines.rs +4 -1
  55. package/sdk-core/core/src/worker/workflow/managed_run.rs +1 -1
  56. package/sdk-core/core/src/worker/workflow/mod.rs +15 -15
  57. package/sdk-core/core-api/Cargo.toml +2 -2
  58. package/sdk-core/core-api/src/envconfig.rs +204 -99
  59. package/sdk-core/core-api/src/lib.rs +9 -0
  60. package/sdk-core/core-api/src/telemetry/metrics.rs +548 -100
  61. package/sdk-core/core-api/src/worker.rs +11 -5
  62. package/sdk-core/core-c-bridge/Cargo.toml +49 -0
  63. package/sdk-core/core-c-bridge/build.rs +26 -0
  64. package/sdk-core/core-c-bridge/include/temporal-sdk-core-c-bridge.h +817 -0
  65. package/sdk-core/core-c-bridge/src/client.rs +679 -0
  66. package/sdk-core/core-c-bridge/src/lib.rs +245 -0
  67. package/sdk-core/core-c-bridge/src/metric.rs +682 -0
  68. package/sdk-core/core-c-bridge/src/random.rs +61 -0
  69. package/sdk-core/core-c-bridge/src/runtime.rs +445 -0
  70. package/sdk-core/core-c-bridge/src/testing.rs +282 -0
  71. package/sdk-core/core-c-bridge/src/tests/context.rs +644 -0
  72. package/sdk-core/core-c-bridge/src/tests/mod.rs +178 -0
  73. package/sdk-core/core-c-bridge/src/tests/utils.rs +108 -0
  74. package/sdk-core/core-c-bridge/src/worker.rs +1069 -0
  75. package/sdk-core/etc/deps.svg +64 -64
  76. package/sdk-core/sdk/src/activity_context.rs +6 -4
  77. package/sdk-core/sdk/src/lib.rs +49 -27
  78. package/sdk-core/sdk/src/workflow_future.rs +18 -25
  79. package/sdk-core/sdk-core-protos/protos/api_upstream/README.md +4 -0
  80. package/sdk-core/sdk-core-protos/protos/api_upstream/buf.yaml +0 -2
  81. package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv2.json +630 -83
  82. package/sdk-core/sdk-core-protos/protos/api_upstream/openapi/openapiv3.yaml +632 -78
  83. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/batch/v1/message.proto +4 -4
  84. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/command/v1/message.proto +6 -4
  85. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/common/v1/message.proto +2 -2
  86. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/deployment/v1/message.proto +32 -2
  87. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/common.proto +10 -1
  88. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/deployment.proto +26 -0
  89. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/failed_cause.proto +2 -0
  90. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/enums/v1/reset.proto +4 -4
  91. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/failure/v1/message.proto +2 -2
  92. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/history/v1/message.proto +47 -31
  93. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/nexus/v1/message.proto +4 -4
  94. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/schedule/v1/message.proto +7 -1
  95. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/worker/v1/message.proto +134 -0
  96. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflow/v1/message.proto +14 -11
  97. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/request_response.proto +148 -37
  98. package/sdk-core/sdk-core-protos/protos/api_upstream/temporal/api/workflowservice/v1/service.proto +21 -0
  99. package/sdk-core/sdk-core-protos/protos/local/temporal/sdk/core/workflow_activation/workflow_activation.proto +4 -4
  100. package/sdk-core/sdk-core-protos/src/history_builder.rs +9 -5
  101. package/sdk-core/sdk-core-protos/src/lib.rs +96 -6
  102. package/sdk-core/test-utils/src/lib.rs +11 -3
  103. package/sdk-core/tests/cloud_tests.rs +3 -3
  104. package/sdk-core/tests/heavy_tests.rs +11 -3
  105. package/sdk-core/tests/integ_tests/client_tests.rs +12 -13
  106. package/sdk-core/tests/integ_tests/ephemeral_server_tests.rs +1 -1
  107. package/sdk-core/tests/integ_tests/metrics_tests.rs +188 -83
  108. package/sdk-core/tests/integ_tests/polling_tests.rs +1 -1
  109. package/sdk-core/tests/integ_tests/queries_tests.rs +56 -40
  110. package/sdk-core/tests/integ_tests/update_tests.rs +2 -7
  111. package/sdk-core/tests/integ_tests/worker_tests.rs +3 -4
  112. package/sdk-core/tests/integ_tests/worker_versioning_tests.rs +3 -7
  113. package/sdk-core/tests/integ_tests/workflow_tests/local_activities.rs +3 -5
  114. package/sdk-core/tests/integ_tests/workflow_tests/nexus.rs +24 -17
  115. package/src/client.rs +6 -0
  116. package/src/metrics.rs +6 -6
@@ -7,19 +7,17 @@ use std::{
7
7
  time::Duration,
8
8
  };
9
9
  use temporal_sdk_core_api::telemetry::metrics::{
10
- BufferAttributes, BufferInstrumentRef, CoreMeter, Counter, Gauge, GaugeF64, Histogram,
11
- HistogramDuration, HistogramF64, LazyBufferInstrument, MetricAttributes, MetricCallBufferer,
12
- MetricEvent, MetricKeyValue, MetricKind, MetricParameters, MetricUpdateVal, NewAttributes,
13
- NoOpCoreMeter,
10
+ BufferAttributes, BufferInstrumentRef, CoreMeter, Counter, CounterBase, Gauge, GaugeBase,
11
+ GaugeF64, GaugeF64Base, Histogram, HistogramBase, HistogramDuration, HistogramDurationBase,
12
+ HistogramF64, HistogramF64Base, LazyBufferInstrument, MetricAttributable, MetricAttributes,
13
+ MetricCallBufferer, MetricEvent, MetricKeyValue, MetricKind, MetricParameters, MetricUpdateVal,
14
+ NewAttributes, NoOpCoreMeter,
14
15
  };
15
16
  use temporal_sdk_core_protos::temporal::api::{
16
17
  enums::v1::WorkflowTaskFailedCause, failure::v1::Failure,
17
18
  };
18
19
 
19
20
  /// Used to track context associated with metrics, and record/update them
20
- ///
21
- /// Possible improvement: make generic over some type tag so that methods are only exposed if the
22
- /// appropriate k/vs have already been set.
23
21
  #[derive(Clone)]
24
22
  pub(crate) struct MetricsContext {
25
23
  meter: Arc<dyn CoreMeter>,
@@ -27,50 +25,53 @@ pub(crate) struct MetricsContext {
27
25
  instruments: Arc<Instruments>,
28
26
  }
29
27
 
28
+ #[derive(Clone)]
30
29
  struct Instruments {
31
- wf_completed_counter: Arc<dyn Counter>,
32
- wf_canceled_counter: Arc<dyn Counter>,
33
- wf_failed_counter: Arc<dyn Counter>,
34
- wf_cont_counter: Arc<dyn Counter>,
35
- wf_e2e_latency: Arc<dyn HistogramDuration>,
36
- wf_task_queue_poll_empty_counter: Arc<dyn Counter>,
37
- wf_task_queue_poll_succeed_counter: Arc<dyn Counter>,
38
- wf_task_execution_failure_counter: Arc<dyn Counter>,
39
- wf_task_sched_to_start_latency: Arc<dyn HistogramDuration>,
40
- wf_task_replay_latency: Arc<dyn HistogramDuration>,
41
- wf_task_execution_latency: Arc<dyn HistogramDuration>,
42
- act_poll_no_task: Arc<dyn Counter>,
43
- act_task_received_counter: Arc<dyn Counter>,
44
- act_execution_failed: Arc<dyn Counter>,
45
- act_sched_to_start_latency: Arc<dyn HistogramDuration>,
46
- act_exec_latency: Arc<dyn HistogramDuration>,
47
- act_exec_succeeded_latency: Arc<dyn HistogramDuration>,
48
- la_execution_cancelled: Arc<dyn Counter>,
49
- la_execution_failed: Arc<dyn Counter>,
50
- la_exec_latency: Arc<dyn HistogramDuration>,
51
- la_exec_succeeded_latency: Arc<dyn HistogramDuration>,
52
- la_total: Arc<dyn Counter>,
53
- nexus_poll_no_task: Arc<dyn Counter>,
54
- nexus_task_schedule_to_start_latency: Arc<dyn HistogramDuration>,
55
- nexus_task_e2e_latency: Arc<dyn HistogramDuration>,
56
- nexus_task_execution_latency: Arc<dyn HistogramDuration>,
57
- nexus_task_execution_failed: Arc<dyn Counter>,
58
- worker_registered: Arc<dyn Counter>,
59
- num_pollers: Arc<dyn Gauge>,
60
- task_slots_available: Arc<dyn Gauge>,
61
- task_slots_used: Arc<dyn Gauge>,
62
- sticky_cache_hit: Arc<dyn Counter>,
63
- sticky_cache_miss: Arc<dyn Counter>,
64
- sticky_cache_size: Arc<dyn Gauge>,
65
- sticky_cache_forced_evictions: Arc<dyn Counter>,
30
+ wf_completed_counter: Counter,
31
+ wf_canceled_counter: Counter,
32
+ wf_failed_counter: Counter,
33
+ wf_cont_counter: Counter,
34
+ wf_e2e_latency: HistogramDuration,
35
+ wf_task_queue_poll_empty_counter: Counter,
36
+ wf_task_queue_poll_succeed_counter: Counter,
37
+ wf_task_execution_failure_counter: Counter,
38
+ wf_task_sched_to_start_latency: HistogramDuration,
39
+ wf_task_replay_latency: HistogramDuration,
40
+ wf_task_execution_latency: HistogramDuration,
41
+ act_poll_no_task: Counter,
42
+ act_task_received_counter: Counter,
43
+ act_execution_failed: Counter,
44
+ act_sched_to_start_latency: HistogramDuration,
45
+ act_exec_latency: HistogramDuration,
46
+ act_exec_succeeded_latency: HistogramDuration,
47
+ la_execution_cancelled: Counter,
48
+ la_execution_failed: Counter,
49
+ la_exec_latency: HistogramDuration,
50
+ la_exec_succeeded_latency: HistogramDuration,
51
+ la_total: Counter,
52
+ nexus_poll_no_task: Counter,
53
+ nexus_task_schedule_to_start_latency: HistogramDuration,
54
+ nexus_task_e2e_latency: HistogramDuration,
55
+ nexus_task_execution_latency: HistogramDuration,
56
+ nexus_task_execution_failed: Counter,
57
+ worker_registered: Counter,
58
+ num_pollers: Gauge,
59
+ task_slots_available: Gauge,
60
+ task_slots_used: Gauge,
61
+ sticky_cache_hit: Counter,
62
+ sticky_cache_miss: Counter,
63
+ sticky_cache_size: Gauge,
64
+ sticky_cache_forced_evictions: Counter,
66
65
  }
67
66
 
68
67
  impl MetricsContext {
69
68
  pub(crate) fn no_op() -> Self {
70
69
  let meter = Arc::new(NoOpCoreMeter);
70
+ let kvs = meter.new_attributes(Default::default());
71
+ let instruments = Arc::new(Instruments::new(meter.as_ref()));
71
72
  Self {
72
- kvs: meter.new_attributes(Default::default()),
73
- instruments: Arc::new(Instruments::new(meter.as_ref())),
73
+ kvs,
74
+ instruments,
74
75
  meter,
75
76
  }
76
77
  }
@@ -83,9 +84,11 @@ impl MetricsContext {
83
84
  .push(MetricKeyValue::new(KEY_NAMESPACE, namespace));
84
85
  meter.default_attribs.attributes.push(task_queue(tq));
85
86
  let kvs = meter.inner.new_attributes(meter.default_attribs);
87
+ let mut instruments = Instruments::new(meter.inner.as_ref());
88
+ instruments.update_attributes(&kvs);
86
89
  Self {
87
90
  kvs,
88
- instruments: Arc::new(Instruments::new(meter.inner.as_ref())),
91
+ instruments: Arc::new(instruments),
89
92
  meter: meter.inner,
90
93
  }
91
94
  } else {
@@ -101,212 +104,186 @@ impl MetricsContext {
101
104
  let kvs = self
102
105
  .meter
103
106
  .extend_attributes(self.kvs.clone(), new_attrs.into());
107
+ let mut instruments = (*self.instruments).clone();
108
+ instruments.update_attributes(&kvs);
104
109
  Self {
110
+ instruments: Arc::new(instruments),
105
111
  kvs,
106
- instruments: self.instruments.clone(),
107
112
  meter: self.meter.clone(),
108
113
  }
109
114
  }
110
115
 
111
116
  /// A workflow task queue poll succeeded
112
117
  pub(crate) fn wf_tq_poll_ok(&self) {
113
- self.instruments
114
- .wf_task_queue_poll_succeed_counter
115
- .add(1, &self.kvs);
118
+ self.instruments.wf_task_queue_poll_succeed_counter.adds(1);
116
119
  }
117
120
 
118
121
  /// A workflow task queue poll timed out / had empty response
119
122
  pub(crate) fn wf_tq_poll_empty(&self) {
120
- self.instruments
121
- .wf_task_queue_poll_empty_counter
122
- .add(1, &self.kvs);
123
+ self.instruments.wf_task_queue_poll_empty_counter.adds(1);
123
124
  }
124
125
 
125
126
  /// A workflow task execution failed
126
127
  pub(crate) fn wf_task_failed(&self) {
127
- self.instruments
128
- .wf_task_execution_failure_counter
129
- .add(1, &self.kvs);
128
+ self.instruments.wf_task_execution_failure_counter.adds(1);
130
129
  }
131
130
 
132
131
  /// A workflow completed successfully
133
132
  pub(crate) fn wf_completed(&self) {
134
- self.instruments.wf_completed_counter.add(1, &self.kvs);
133
+ self.instruments.wf_completed_counter.adds(1);
135
134
  }
136
135
 
137
136
  /// A workflow ended cancelled
138
137
  pub(crate) fn wf_canceled(&self) {
139
- self.instruments.wf_canceled_counter.add(1, &self.kvs);
138
+ self.instruments.wf_canceled_counter.adds(1);
140
139
  }
141
140
 
142
141
  /// A workflow ended failed
143
142
  pub(crate) fn wf_failed(&self) {
144
- self.instruments.wf_failed_counter.add(1, &self.kvs);
143
+ self.instruments.wf_failed_counter.adds(1);
145
144
  }
146
145
 
147
146
  /// A workflow continued as new
148
147
  pub(crate) fn wf_continued_as_new(&self) {
149
- self.instruments.wf_cont_counter.add(1, &self.kvs);
148
+ self.instruments.wf_cont_counter.adds(1);
150
149
  }
151
150
 
152
151
  /// Record workflow total execution time in milliseconds
153
152
  pub(crate) fn wf_e2e_latency(&self, dur: Duration) {
154
- self.instruments.wf_e2e_latency.record(dur, &self.kvs);
153
+ self.instruments.wf_e2e_latency.records(dur);
155
154
  }
156
155
 
157
156
  /// Record workflow task schedule to start time in millis
158
157
  pub(crate) fn wf_task_sched_to_start_latency(&self, dur: Duration) {
159
- self.instruments
160
- .wf_task_sched_to_start_latency
161
- .record(dur, &self.kvs);
158
+ self.instruments.wf_task_sched_to_start_latency.records(dur);
162
159
  }
163
160
 
164
161
  /// Record workflow task execution time in milliseconds
165
162
  pub(crate) fn wf_task_latency(&self, dur: Duration) {
166
- self.instruments
167
- .wf_task_execution_latency
168
- .record(dur, &self.kvs);
163
+ self.instruments.wf_task_execution_latency.records(dur);
169
164
  }
170
165
 
171
166
  /// Record time it takes to catch up on replaying a WFT
172
167
  pub(crate) fn wf_task_replay_latency(&self, dur: Duration) {
173
- self.instruments
174
- .wf_task_replay_latency
175
- .record(dur, &self.kvs);
168
+ self.instruments.wf_task_replay_latency.records(dur);
176
169
  }
177
170
 
178
171
  /// An activity long poll timed out
179
172
  pub(crate) fn act_poll_timeout(&self) {
180
- self.instruments.act_poll_no_task.add(1, &self.kvs);
173
+ self.instruments.act_poll_no_task.adds(1);
181
174
  }
182
175
 
183
176
  /// A count of activity tasks received
184
177
  pub(crate) fn act_task_received(&self) {
185
- self.instruments.act_task_received_counter.add(1, &self.kvs);
178
+ self.instruments.act_task_received_counter.adds(1);
186
179
  }
187
180
 
188
181
  /// An activity execution failed
189
182
  pub(crate) fn act_execution_failed(&self) {
190
- self.instruments.act_execution_failed.add(1, &self.kvs);
183
+ self.instruments.act_execution_failed.adds(1);
191
184
  }
192
185
 
193
186
  /// Record end-to-end (sched-to-complete) time for successful activity executions
194
187
  pub(crate) fn act_execution_succeeded(&self, dur: Duration) {
195
- self.instruments
196
- .act_exec_succeeded_latency
197
- .record(dur, &self.kvs);
188
+ self.instruments.act_exec_succeeded_latency.records(dur);
198
189
  }
199
190
 
200
191
  /// Record activity task schedule to start time in millis
201
192
  pub(crate) fn act_sched_to_start_latency(&self, dur: Duration) {
202
- self.instruments
203
- .act_sched_to_start_latency
204
- .record(dur, &self.kvs);
193
+ self.instruments.act_sched_to_start_latency.records(dur);
205
194
  }
206
195
 
207
196
  /// Record time it took to complete activity execution, from the time core generated the
208
197
  /// activity task, to the time lang responded with a completion (failure or success).
209
198
  pub(crate) fn act_execution_latency(&self, dur: Duration) {
210
- self.instruments.act_exec_latency.record(dur, &self.kvs);
199
+ self.instruments.act_exec_latency.records(dur);
211
200
  }
212
201
 
213
202
  pub(crate) fn la_execution_cancelled(&self) {
214
- self.instruments.la_execution_cancelled.add(1, &self.kvs);
203
+ self.instruments.la_execution_cancelled.adds(1);
215
204
  }
216
205
 
217
206
  pub(crate) fn la_execution_failed(&self) {
218
- self.instruments.la_execution_failed.add(1, &self.kvs);
207
+ self.instruments.la_execution_failed.adds(1);
219
208
  }
220
209
 
221
210
  pub(crate) fn la_exec_latency(&self, dur: Duration) {
222
- self.instruments.la_exec_latency.record(dur, &self.kvs);
211
+ self.instruments.la_exec_latency.records(dur);
223
212
  }
224
213
 
225
214
  pub(crate) fn la_exec_succeeded_latency(&self, dur: Duration) {
226
- self.instruments
227
- .la_exec_succeeded_latency
228
- .record(dur, &self.kvs);
215
+ self.instruments.la_exec_succeeded_latency.records(dur);
229
216
  }
230
217
 
231
218
  pub(crate) fn la_executed(&self) {
232
- self.instruments.la_total.add(1, &self.kvs);
219
+ self.instruments.la_total.adds(1);
233
220
  }
234
221
 
235
222
  /// A nexus long poll timed out
236
223
  pub(crate) fn nexus_poll_timeout(&self) {
237
- self.instruments.nexus_poll_no_task.add(1, &self.kvs);
224
+ self.instruments.nexus_poll_no_task.adds(1);
238
225
  }
239
226
 
240
227
  /// Record nexus task schedule to start time
241
228
  pub(crate) fn nexus_task_sched_to_start_latency(&self, dur: Duration) {
242
229
  self.instruments
243
230
  .nexus_task_schedule_to_start_latency
244
- .record(dur, &self.kvs);
231
+ .records(dur);
245
232
  }
246
233
 
247
234
  /// Record nexus task end-to-end time
248
235
  pub(crate) fn nexus_task_e2e_latency(&self, dur: Duration) {
249
- self.instruments
250
- .nexus_task_e2e_latency
251
- .record(dur, &self.kvs);
236
+ self.instruments.nexus_task_e2e_latency.records(dur);
252
237
  }
253
238
 
254
239
  /// Record nexus task execution time
255
240
  pub(crate) fn nexus_task_execution_latency(&self, dur: Duration) {
256
- self.instruments
257
- .nexus_task_execution_latency
258
- .record(dur, &self.kvs);
241
+ self.instruments.nexus_task_execution_latency.records(dur);
259
242
  }
260
243
 
261
244
  /// Record a nexus task execution failure
262
245
  pub(crate) fn nexus_task_execution_failed(&self) {
263
- self.instruments
264
- .nexus_task_execution_failed
265
- .add(1, &self.kvs);
246
+ self.instruments.nexus_task_execution_failed.adds(1);
266
247
  }
267
248
 
268
249
  /// A worker was registered
269
250
  pub(crate) fn worker_registered(&self) {
270
- self.instruments.worker_registered.add(1, &self.kvs);
251
+ self.instruments.worker_registered.adds(1);
271
252
  }
272
253
 
273
254
  /// Record current number of available task slots. Context should have worker type set.
274
255
  pub(crate) fn available_task_slots(&self, num: usize) {
275
- self.instruments
276
- .task_slots_available
277
- .record(num as u64, &self.kvs)
256
+ self.instruments.task_slots_available.records(num as u64)
278
257
  }
279
258
 
280
259
  /// Record current number of used task slots. Context should have worker type set.
281
260
  pub(crate) fn task_slots_used(&self, num: u64) {
282
- self.instruments.task_slots_used.record(num, &self.kvs)
261
+ self.instruments.task_slots_used.records(num)
283
262
  }
284
263
 
285
264
  /// Record current number of pollers. Context should include poller type / task queue tag.
286
265
  pub(crate) fn record_num_pollers(&self, num: usize) {
287
- self.instruments.num_pollers.record(num as u64, &self.kvs);
266
+ self.instruments.num_pollers.records(num as u64);
288
267
  }
289
268
 
290
269
  /// A workflow task found a cached workflow to run against
291
270
  pub(crate) fn sticky_cache_hit(&self) {
292
- self.instruments.sticky_cache_hit.add(1, &self.kvs);
271
+ self.instruments.sticky_cache_hit.adds(1);
293
272
  }
294
273
 
295
274
  /// A workflow task did not find a cached workflow
296
275
  pub(crate) fn sticky_cache_miss(&self) {
297
- self.instruments.sticky_cache_miss.add(1, &self.kvs);
276
+ self.instruments.sticky_cache_miss.adds(1);
298
277
  }
299
278
 
300
279
  /// Record current cache size (in number of wfs, not bytes)
301
280
  pub(crate) fn cache_size(&self, size: u64) {
302
- self.instruments.sticky_cache_size.record(size, &self.kvs);
281
+ self.instruments.sticky_cache_size.records(size);
303
282
  }
304
283
 
305
284
  /// Count a workflow being evicted from the cache
306
285
  pub(crate) fn forced_cache_eviction(&self) {
307
- self.instruments
308
- .sticky_cache_forced_evictions
309
- .add(1, &self.kvs);
286
+ self.instruments.sticky_cache_forced_evictions.adds(1);
310
287
  }
311
288
  }
312
289
 
@@ -497,6 +474,77 @@ impl Instruments {
497
474
  }),
498
475
  }
499
476
  }
477
+
478
+ fn update_attributes(&mut self, new_attributes: &MetricAttributes) {
479
+ self.wf_completed_counter
480
+ .update_attributes(new_attributes.clone());
481
+ self.wf_canceled_counter
482
+ .update_attributes(new_attributes.clone());
483
+ self.wf_failed_counter
484
+ .update_attributes(new_attributes.clone());
485
+ self.wf_cont_counter
486
+ .update_attributes(new_attributes.clone());
487
+ self.wf_e2e_latency
488
+ .update_attributes(new_attributes.clone());
489
+ self.wf_task_queue_poll_empty_counter
490
+ .update_attributes(new_attributes.clone());
491
+ self.wf_task_queue_poll_succeed_counter
492
+ .update_attributes(new_attributes.clone());
493
+ self.wf_task_execution_failure_counter
494
+ .update_attributes(new_attributes.clone());
495
+ self.wf_task_sched_to_start_latency
496
+ .update_attributes(new_attributes.clone());
497
+ self.wf_task_replay_latency
498
+ .update_attributes(new_attributes.clone());
499
+ self.wf_task_execution_latency
500
+ .update_attributes(new_attributes.clone());
501
+ self.act_poll_no_task
502
+ .update_attributes(new_attributes.clone());
503
+ self.act_task_received_counter
504
+ .update_attributes(new_attributes.clone());
505
+ self.act_execution_failed
506
+ .update_attributes(new_attributes.clone());
507
+ self.act_sched_to_start_latency
508
+ .update_attributes(new_attributes.clone());
509
+ self.act_exec_latency
510
+ .update_attributes(new_attributes.clone());
511
+ self.act_exec_succeeded_latency
512
+ .update_attributes(new_attributes.clone());
513
+ self.la_execution_cancelled
514
+ .update_attributes(new_attributes.clone());
515
+ self.la_execution_failed
516
+ .update_attributes(new_attributes.clone());
517
+ self.la_exec_latency
518
+ .update_attributes(new_attributes.clone());
519
+ self.la_exec_succeeded_latency
520
+ .update_attributes(new_attributes.clone());
521
+ self.la_total.update_attributes(new_attributes.clone());
522
+ self.nexus_poll_no_task
523
+ .update_attributes(new_attributes.clone());
524
+ self.nexus_task_schedule_to_start_latency
525
+ .update_attributes(new_attributes.clone());
526
+ self.nexus_task_e2e_latency
527
+ .update_attributes(new_attributes.clone());
528
+ self.nexus_task_execution_latency
529
+ .update_attributes(new_attributes.clone());
530
+ self.nexus_task_execution_failed
531
+ .update_attributes(new_attributes.clone());
532
+ self.worker_registered
533
+ .update_attributes(new_attributes.clone());
534
+ self.num_pollers.update_attributes(new_attributes.clone());
535
+ self.task_slots_available
536
+ .update_attributes(new_attributes.clone());
537
+ self.task_slots_used
538
+ .update_attributes(new_attributes.clone());
539
+ self.sticky_cache_hit
540
+ .update_attributes(new_attributes.clone());
541
+ self.sticky_cache_miss
542
+ .update_attributes(new_attributes.clone());
543
+ self.sticky_cache_size
544
+ .update_attributes(new_attributes.clone());
545
+ self.sticky_cache_forced_evictions
546
+ .update_attributes(new_attributes.clone());
547
+ }
500
548
  }
501
549
 
502
550
  const KEY_NAMESPACE: &str = "namespace";
@@ -757,28 +805,30 @@ where
757
805
  }
758
806
  }
759
807
 
760
- fn counter(&self, params: MetricParameters) -> Arc<dyn Counter> {
761
- Arc::new(self.new_instrument(params, MetricKind::Counter))
808
+ fn counter(&self, params: MetricParameters) -> Counter {
809
+ Counter::new(Arc::new(self.new_instrument(params, MetricKind::Counter)))
762
810
  }
763
811
 
764
- fn histogram(&self, params: MetricParameters) -> Arc<dyn Histogram> {
765
- Arc::new(self.new_instrument(params, MetricKind::Histogram))
812
+ fn histogram(&self, params: MetricParameters) -> Histogram {
813
+ Histogram::new(Arc::new(self.new_instrument(params, MetricKind::Histogram)))
766
814
  }
767
815
 
768
- fn histogram_f64(&self, params: MetricParameters) -> Arc<dyn HistogramF64> {
769
- Arc::new(self.new_instrument(params, MetricKind::HistogramF64))
816
+ fn histogram_f64(&self, params: MetricParameters) -> HistogramF64 {
817
+ HistogramF64::new(Arc::new(self.new_instrument(params, MetricKind::Histogram)))
770
818
  }
771
819
 
772
- fn histogram_duration(&self, params: MetricParameters) -> Arc<dyn HistogramDuration> {
773
- Arc::new(self.new_instrument(params, MetricKind::HistogramDuration))
820
+ fn histogram_duration(&self, params: MetricParameters) -> HistogramDuration {
821
+ HistogramDuration::new(Arc::new(
822
+ self.new_instrument(params, MetricKind::HistogramDuration),
823
+ ))
774
824
  }
775
825
 
776
- fn gauge(&self, params: MetricParameters) -> Arc<dyn Gauge> {
777
- Arc::new(self.new_instrument(params, MetricKind::Gauge))
826
+ fn gauge(&self, params: MetricParameters) -> Gauge {
827
+ Gauge::new(Arc::new(self.new_instrument(params, MetricKind::Gauge)))
778
828
  }
779
829
 
780
- fn gauge_f64(&self, params: MetricParameters) -> Arc<dyn GaugeF64> {
781
- Arc::new(self.new_instrument(params, MetricKind::GaugeF64))
830
+ fn gauge_f64(&self, params: MetricParameters) -> GaugeF64 {
831
+ GaugeF64::new(Arc::new(self.new_instrument(params, MetricKind::Gauge)))
782
832
  }
783
833
  }
784
834
  impl<I> MetricCallBufferer<I> for MetricsCallBuffer<I>
@@ -790,6 +840,7 @@ where
790
840
  }
791
841
  }
792
842
 
843
+ #[derive(Clone)]
793
844
  struct BufferInstrument<I: BufferInstrumentRef> {
794
845
  instrument_ref: LazyBufferInstrument<I>,
795
846
  tx: LogErrOnFullSender<MetricEvent<I>>,
@@ -801,7 +852,7 @@ where
801
852
  fn send(&self, value: MetricUpdateVal, attributes: &MetricAttributes) {
802
853
  let attributes = match attributes {
803
854
  MetricAttributes::Buffer(l) => l.clone(),
804
- _ => panic!("MetricsCallBuffer only works with MetricAttributes::Lang"),
855
+ _ => panic!("MetricsCallBuffer only works with MetricAttributes::Buffer"),
805
856
  };
806
857
  self.tx.send(MetricEvent::Update {
807
858
  instrument: self.instrument_ref.clone(),
@@ -810,52 +861,154 @@ where
810
861
  });
811
862
  }
812
863
  }
813
- impl<I> Counter for BufferInstrument<I>
864
+
865
+ #[derive(Clone)]
866
+ struct InstrumentWithAttributes<I> {
867
+ inner: I,
868
+ attributes: MetricAttributes,
869
+ }
870
+
871
+ impl<I> MetricAttributable<Box<dyn CounterBase>> for BufferInstrument<I>
872
+ where
873
+ I: BufferInstrumentRef + Send + Sync + Clone + 'static,
874
+ {
875
+ fn with_attributes(
876
+ &self,
877
+ attributes: &MetricAttributes,
878
+ ) -> Result<Box<dyn CounterBase>, Box<dyn std::error::Error>> {
879
+ Ok(Box::new(InstrumentWithAttributes {
880
+ inner: self.clone(),
881
+ attributes: attributes.clone(),
882
+ }))
883
+ }
884
+ }
885
+
886
+ impl<I> MetricAttributable<Box<dyn HistogramBase>> for BufferInstrument<I>
887
+ where
888
+ I: BufferInstrumentRef + Send + Sync + Clone + 'static,
889
+ {
890
+ fn with_attributes(
891
+ &self,
892
+ attributes: &MetricAttributes,
893
+ ) -> Result<Box<dyn HistogramBase>, Box<dyn std::error::Error>> {
894
+ Ok(Box::new(InstrumentWithAttributes {
895
+ inner: self.clone(),
896
+ attributes: attributes.clone(),
897
+ }))
898
+ }
899
+ }
900
+
901
+ impl<I> MetricAttributable<Box<dyn HistogramF64Base>> for BufferInstrument<I>
902
+ where
903
+ I: BufferInstrumentRef + Send + Sync + Clone + 'static,
904
+ {
905
+ fn with_attributes(
906
+ &self,
907
+ attributes: &MetricAttributes,
908
+ ) -> Result<Box<dyn HistogramF64Base>, Box<dyn std::error::Error>> {
909
+ Ok(Box::new(InstrumentWithAttributes {
910
+ inner: self.clone(),
911
+ attributes: attributes.clone(),
912
+ }))
913
+ }
914
+ }
915
+
916
+ impl<I> MetricAttributable<Box<dyn HistogramDurationBase>> for BufferInstrument<I>
917
+ where
918
+ I: BufferInstrumentRef + Send + Sync + Clone + 'static,
919
+ {
920
+ fn with_attributes(
921
+ &self,
922
+ attributes: &MetricAttributes,
923
+ ) -> Result<Box<dyn HistogramDurationBase>, Box<dyn std::error::Error>> {
924
+ Ok(Box::new(InstrumentWithAttributes {
925
+ inner: self.clone(),
926
+ attributes: attributes.clone(),
927
+ }))
928
+ }
929
+ }
930
+
931
+ impl<I> MetricAttributable<Box<dyn GaugeBase>> for BufferInstrument<I>
932
+ where
933
+ I: BufferInstrumentRef + Send + Sync + Clone + 'static,
934
+ {
935
+ fn with_attributes(
936
+ &self,
937
+ attributes: &MetricAttributes,
938
+ ) -> Result<Box<dyn GaugeBase>, Box<dyn std::error::Error>> {
939
+ Ok(Box::new(InstrumentWithAttributes {
940
+ inner: self.clone(),
941
+ attributes: attributes.clone(),
942
+ }))
943
+ }
944
+ }
945
+
946
+ impl<I> MetricAttributable<Box<dyn GaugeF64Base>> for BufferInstrument<I>
947
+ where
948
+ I: BufferInstrumentRef + Send + Sync + Clone + 'static,
949
+ {
950
+ fn with_attributes(
951
+ &self,
952
+ attributes: &MetricAttributes,
953
+ ) -> Result<Box<dyn GaugeF64Base>, Box<dyn std::error::Error>> {
954
+ Ok(Box::new(InstrumentWithAttributes {
955
+ inner: self.clone(),
956
+ attributes: attributes.clone(),
957
+ }))
958
+ }
959
+ }
960
+ impl<I> CounterBase for InstrumentWithAttributes<BufferInstrument<I>>
814
961
  where
815
- I: BufferInstrumentRef + Send + Sync + Clone,
962
+ I: BufferInstrumentRef + Send + Sync + Clone + 'static,
816
963
  {
817
- fn add(&self, value: u64, attributes: &MetricAttributes) {
818
- self.send(MetricUpdateVal::Delta(value), attributes)
964
+ fn adds(&self, value: u64) {
965
+ self.inner
966
+ .send(MetricUpdateVal::Delta(value), &self.attributes)
819
967
  }
820
968
  }
821
- impl<I> Gauge for BufferInstrument<I>
969
+ impl<I> GaugeBase for InstrumentWithAttributes<BufferInstrument<I>>
822
970
  where
823
- I: BufferInstrumentRef + Send + Sync + Clone,
971
+ I: BufferInstrumentRef + Send + Sync + Clone + 'static,
824
972
  {
825
- fn record(&self, value: u64, attributes: &MetricAttributes) {
826
- self.send(MetricUpdateVal::Value(value), attributes)
973
+ fn records(&self, value: u64) {
974
+ self.inner
975
+ .send(MetricUpdateVal::Value(value), &self.attributes)
827
976
  }
828
977
  }
829
- impl<I> GaugeF64 for BufferInstrument<I>
978
+ impl<I> GaugeF64Base for InstrumentWithAttributes<BufferInstrument<I>>
830
979
  where
831
- I: BufferInstrumentRef + Send + Sync + Clone,
980
+ I: BufferInstrumentRef + Send + Sync + Clone + 'static,
832
981
  {
833
- fn record(&self, value: f64, attributes: &MetricAttributes) {
834
- self.send(MetricUpdateVal::ValueF64(value), attributes)
982
+ fn records(&self, value: f64) {
983
+ self.inner
984
+ .send(MetricUpdateVal::ValueF64(value), &self.attributes)
835
985
  }
836
986
  }
837
- impl<I> Histogram for BufferInstrument<I>
987
+ impl<I> HistogramBase for InstrumentWithAttributes<BufferInstrument<I>>
838
988
  where
839
- I: BufferInstrumentRef + Send + Sync + Clone,
989
+ I: BufferInstrumentRef + Send + Sync + Clone + 'static,
840
990
  {
841
- fn record(&self, value: u64, attributes: &MetricAttributes) {
842
- self.send(MetricUpdateVal::Value(value), attributes)
991
+ fn records(&self, value: u64) {
992
+ self.inner
993
+ .send(MetricUpdateVal::Value(value), &self.attributes)
843
994
  }
844
995
  }
845
- impl<I> HistogramF64 for BufferInstrument<I>
996
+ impl<I> HistogramF64Base for InstrumentWithAttributes<BufferInstrument<I>>
846
997
  where
847
- I: BufferInstrumentRef + Send + Sync + Clone,
998
+ I: BufferInstrumentRef + Send + Sync + Clone + 'static,
848
999
  {
849
- fn record(&self, value: f64, attributes: &MetricAttributes) {
850
- self.send(MetricUpdateVal::ValueF64(value), attributes)
1000
+ fn records(&self, value: f64) {
1001
+ self.inner
1002
+ .send(MetricUpdateVal::ValueF64(value), &self.attributes)
851
1003
  }
852
1004
  }
853
- impl<I> HistogramDuration for BufferInstrument<I>
1005
+ impl<I> HistogramDurationBase for InstrumentWithAttributes<BufferInstrument<I>>
854
1006
  where
855
- I: BufferInstrumentRef + Send + Sync + Clone,
1007
+ I: BufferInstrumentRef + Send + Sync + Clone + 'static,
856
1008
  {
857
- fn record(&self, value: Duration, attributes: &MetricAttributes) {
858
- self.send(MetricUpdateVal::Duration(value), attributes)
1009
+ fn records(&self, value: Duration) {
1010
+ self.inner
1011
+ .send(MetricUpdateVal::Duration(value), &self.attributes)
859
1012
  }
860
1013
  }
861
1014
 
@@ -877,32 +1030,32 @@ impl<CM: CoreMeter> CoreMeter for PrefixedMetricsMeter<CM> {
877
1030
  self.meter.extend_attributes(existing, attribs)
878
1031
  }
879
1032
 
880
- fn counter(&self, mut params: MetricParameters) -> Arc<dyn Counter> {
1033
+ fn counter(&self, mut params: MetricParameters) -> Counter {
881
1034
  params.name = (self.prefix.clone() + &*params.name).into();
882
1035
  self.meter.counter(params)
883
1036
  }
884
1037
 
885
- fn histogram(&self, mut params: MetricParameters) -> Arc<dyn Histogram> {
1038
+ fn histogram(&self, mut params: MetricParameters) -> Histogram {
886
1039
  params.name = (self.prefix.clone() + &*params.name).into();
887
1040
  self.meter.histogram(params)
888
1041
  }
889
1042
 
890
- fn histogram_f64(&self, mut params: MetricParameters) -> Arc<dyn HistogramF64> {
1043
+ fn histogram_f64(&self, mut params: MetricParameters) -> HistogramF64 {
891
1044
  params.name = (self.prefix.clone() + &*params.name).into();
892
1045
  self.meter.histogram_f64(params)
893
1046
  }
894
1047
 
895
- fn histogram_duration(&self, mut params: MetricParameters) -> Arc<dyn HistogramDuration> {
1048
+ fn histogram_duration(&self, mut params: MetricParameters) -> HistogramDuration {
896
1049
  params.name = (self.prefix.clone() + &*params.name).into();
897
1050
  self.meter.histogram_duration(params)
898
1051
  }
899
1052
 
900
- fn gauge(&self, mut params: MetricParameters) -> Arc<dyn Gauge> {
1053
+ fn gauge(&self, mut params: MetricParameters) -> Gauge {
901
1054
  params.name = (self.prefix.clone() + &*params.name).into();
902
1055
  self.meter.gauge(params)
903
1056
  }
904
1057
 
905
- fn gauge_f64(&self, mut params: MetricParameters) -> Arc<dyn GaugeF64> {
1058
+ fn gauge_f64(&self, mut params: MetricParameters) -> GaugeF64 {
906
1059
  params.name = (self.prefix.clone() + &*params.name).into();
907
1060
  self.meter.gauge_f64(params)
908
1061
  }
@@ -1003,6 +1156,7 @@ mod tests {
1003
1156
  => populate_into
1004
1157
  );
1005
1158
  a2.set(Arc::new(DummyCustomAttrs(2))).unwrap();
1159
+ dbg!(&events);
1006
1160
  assert_matches!(
1007
1161
  &events[1],
1008
1162
  MetricEvent::Update {