@@ -11,37 +11,45 @@ use std::{
11
11
sync:: { Arc , RwLock } ,
12
12
} ;
13
13
14
- use crate :: provider:: { GlobalTelemetryProvider , TelemetryProvider } ;
14
+ use crate :: {
15
+ error:: { ErrorKind , GlobalTelemetryProviderError } ,
16
+ provider:: { GlobalTelemetryProvider , TelemetryProvider } ,
17
+ ObservabilityError ,
18
+ } ;
15
19
16
20
// Statically store the global provider
17
21
static GLOBAL_TELEMETRY_PROVIDER : Lazy < RwLock < GlobalTelemetryProvider > > =
18
22
Lazy :: new ( || RwLock :: new ( GlobalTelemetryProvider :: new ( TelemetryProvider :: default ( ) ) ) ) ;
19
23
20
24
/// Set the current global [TelemetryProvider].
21
25
///
22
- /// This is meant to be run once at the beginning of an application. It will panic if two threads
23
- /// attempt to call it at the same time.
24
- pub fn set_telemetry_provider ( new_provider : TelemetryProvider ) {
25
- // TODO(smithyObservability): would probably be nicer to return a Result here, but the Guard held by the error from
26
- // .try_write is not Send so I struggled to build an ObservabilityError from it
27
- let mut old_provider = GLOBAL_TELEMETRY_PROVIDER
28
- . try_write ( )
29
- . expect ( "GLOBAL_TELEMETRY_PROVIDER RwLock Poisoned" ) ;
26
+ /// This is meant to be run once at the beginning of an application. Will return an [Err] if the
27
+ /// [RwLock] holding the global [TelemetryProvider] is locked or poisoned.
28
+ pub fn set_telemetry_provider ( new_provider : TelemetryProvider ) -> Result < ( ) , ObservabilityError > {
29
+ if let Ok ( mut old_provider) = GLOBAL_TELEMETRY_PROVIDER . try_write ( ) {
30
+ let new_global_provider = GlobalTelemetryProvider :: new ( new_provider) ;
30
31
31
- let new_global_provider = GlobalTelemetryProvider :: new ( new_provider ) ;
32
+ let _ = mem :: replace ( & mut * old_provider , new_global_provider ) ;
32
33
33
- let _ = mem:: replace ( & mut * old_provider, new_global_provider) ;
34
+ Ok ( ( ) )
35
+ } else {
36
+ Err ( ObservabilityError :: new (
37
+ ErrorKind :: GettingGlobalProvider ,
38
+ GlobalTelemetryProviderError ,
39
+ ) )
40
+ }
34
41
}
35
42
36
- /// Get an [Arc] reference to the current global [TelemetryProvider]. [None] is returned if the [RwLock] containing
37
- /// the global [TelemetryProvider] is poisoned or is currently locked by a writer.
38
- pub fn get_telemetry_provider ( ) -> Option < Arc < TelemetryProvider > > {
39
- // TODO(smithyObservability): would probably make more sense to return a Result rather than an Option here, but the Guard held by the error from
40
- // .try_read is not Send so I struggled to build an ObservabilityError from it
43
+ /// Get an [Arc] reference to the current global [TelemetryProvider]. Will return an [Err] if the
44
+ /// [RwLock] holding the global [TelemetryProvider] is locked or poisoned.
45
+ pub fn get_telemetry_provider ( ) -> Result < Arc < TelemetryProvider > , ObservabilityError > {
41
46
if let Ok ( tp) = GLOBAL_TELEMETRY_PROVIDER . try_read ( ) {
42
- Some ( tp. telemetry_provider ( ) . clone ( ) )
47
+ Ok ( tp. telemetry_provider ( ) . clone ( ) )
43
48
} else {
44
- None
49
+ Err ( ObservabilityError :: new (
50
+ ErrorKind :: GettingGlobalProvider ,
51
+ GlobalTelemetryProviderError ,
52
+ ) )
45
53
}
46
54
}
47
55
@@ -59,7 +67,7 @@ mod tests {
59
67
let my_provider = TelemetryProvider :: default ( ) ;
60
68
61
69
// Set the new counter and get a reference to the old one
62
- set_telemetry_provider ( my_provider) ;
70
+ set_telemetry_provider ( my_provider) . unwrap ( ) ;
63
71
}
64
72
65
73
#[ test]
0 commit comments