@@ -9,6 +9,7 @@ use std::{
9
9
} ;
10
10
11
11
use opentelemetry:: {
12
+ global,
12
13
metrics:: { noop:: NoopMeterCore , Meter , MeterProvider , MetricsError , Result } ,
13
14
KeyValue ,
14
15
} ;
@@ -113,6 +114,13 @@ impl SdkMeterProvider {
113
114
}
114
115
}
115
116
117
+ impl Drop for SdkMeterProvider {
118
+ fn drop ( & mut self ) {
119
+ if let Err ( err) = self . shutdown ( ) {
120
+ global:: handle_error ( err) ;
121
+ }
122
+ }
123
+ }
116
124
impl MeterProvider for SdkMeterProvider {
117
125
fn versioned_meter (
118
126
& self ,
@@ -211,6 +219,7 @@ impl fmt::Debug for MeterProviderBuilder {
211
219
mod tests {
212
220
use crate :: testing:: metrics:: metric_reader:: TestMetricReader ;
213
221
use crate :: Resource ;
222
+ use opentelemetry:: global;
214
223
use opentelemetry:: Key ;
215
224
use opentelemetry:: KeyValue ;
216
225
use std:: env;
@@ -228,14 +237,14 @@ mod tests {
228
237
expect. map( |s| s. to_string( ) )
229
238
) ;
230
239
} ;
231
- let reader = TestMetricReader { } ;
240
+ let reader = TestMetricReader :: new ( ) ;
232
241
let default_meter_provider = super :: SdkMeterProvider :: builder ( )
233
242
. with_reader ( reader)
234
243
. build ( ) ;
235
244
assert_service_name ( default_meter_provider, Some ( "unknown_service" ) ) ;
236
245
237
246
// If user provided a resource, use that.
238
- let reader2 = TestMetricReader { } ;
247
+ let reader2 = TestMetricReader :: new ( ) ;
239
248
let custom_meter_provider = super :: SdkMeterProvider :: builder ( )
240
249
. with_reader ( reader2)
241
250
. with_resource ( Resource :: new ( vec ! [ KeyValue :: new(
@@ -250,7 +259,7 @@ mod tests {
250
259
Some ( "key1=value1, k2, k3=value2" ) ,
251
260
|| {
252
261
// If `OTEL_RESOURCE_ATTRIBUTES` is set, read them automatically
253
- let reader3 = TestMetricReader { } ;
262
+ let reader3 = TestMetricReader :: new ( ) ;
254
263
let env_resource_provider = super :: SdkMeterProvider :: builder ( )
255
264
. with_reader ( reader3)
256
265
. build ( ) ;
@@ -273,7 +282,7 @@ mod tests {
273
282
"OTEL_RESOURCE_ATTRIBUTES" ,
274
283
Some ( "my-custom-key=env-val,k2=value2" ) ,
275
284
|| {
276
- let reader4 = TestMetricReader { } ;
285
+ let reader4 = TestMetricReader :: new ( ) ;
277
286
let user_provided_resource_config_provider = super :: SdkMeterProvider :: builder ( )
278
287
. with_reader ( reader4)
279
288
. with_resource ( Resource :: default ( ) . merge ( & mut Resource :: new ( vec ! [
@@ -295,12 +304,37 @@ mod tests {
295
304
) ;
296
305
297
306
// If user provided a resource, it takes priority during collision.
298
- let reader5 = TestMetricReader { } ;
307
+ let reader5 = TestMetricReader :: new ( ) ;
299
308
let no_service_name = super :: SdkMeterProvider :: builder ( )
300
309
. with_reader ( reader5)
301
310
. with_resource ( Resource :: empty ( ) )
302
311
. build ( ) ;
303
312
304
313
assert_service_name ( no_service_name, None ) ;
305
314
}
315
+
316
+ #[ test]
317
+ fn test_meter_provider_shutdown ( ) {
318
+ let reader = TestMetricReader :: new ( ) ;
319
+ let provider = super :: SdkMeterProvider :: builder ( )
320
+ . with_reader ( reader. clone ( ) )
321
+ . build ( ) ;
322
+ global:: set_meter_provider ( provider. clone ( ) ) ;
323
+ assert ! ( !provider
324
+ . is_shutdown
325
+ . load( std:: sync:: atomic:: Ordering :: Relaxed ) ) ;
326
+ assert ! ( !reader. is_shutdown( ) ) ;
327
+ // create a meter and an instrument
328
+ let meter = global:: meter ( "test" ) ;
329
+ let counter = meter. u64_counter ( "test_counter" ) . init ( ) ;
330
+ // no need to drop a meter for meter_provider shutdown
331
+ global:: shutdown_meter_provider ( ) ;
332
+ assert ! ( provider
333
+ . is_shutdown
334
+ . load( std:: sync:: atomic:: Ordering :: Relaxed ) ) ;
335
+ assert ! ( reader. is_shutdown( ) ) ;
336
+ // TODO Fix: the instrument is still available, and can be used.
337
+ // While the reader is shutdown, and no collect is happening
338
+ counter. add ( 1 , & [ ] ) ;
339
+ }
306
340
}
0 commit comments