@@ -48,27 +48,52 @@ pub(crate) struct TracerProviderInner {
4848 is_shutdown : AtomicBool ,
4949}
5050
51- impl Drop for TracerProviderInner {
52- fn drop ( & mut self ) {
51+ impl TracerProviderInner {
52+ /// Crate-private shutdown method to be called both from explicit shutdown
53+ /// and from Drop when the last reference is released.
54+ pub ( crate ) fn shutdown ( & self ) -> TraceResult < ( ) > {
5355 if self
5456 . is_shutdown
5557 . compare_exchange ( false , true , Ordering :: SeqCst , Ordering :: SeqCst )
5658 . is_ok ( )
5759 {
60+ // propagate the shutdown signal to processors
61+ // it's up to the processor to properly block new spans after shutdown
62+ let mut errs = vec ! [ ] ;
5863 for processor in & self . processors {
5964 if let Err ( err) = processor. shutdown ( ) {
60- global :: handle_error ( err) ;
65+ errs . push ( err) ;
6166 }
6267 }
68+
69+ if errs. is_empty ( ) {
70+ Ok ( ( ) )
71+ } else {
72+ Err ( TraceError :: Other ( format ! ( "{errs:?}" ) . into ( ) ) )
73+ }
74+ } else {
75+ Err ( TraceError :: Other (
76+ "tracer provider already shut down" . into ( ) ,
77+ ) )
78+ }
79+ }
80+ }
81+
82+ impl Drop for TracerProviderInner {
83+ fn drop ( & mut self ) {
84+ if let Err ( err) = self . shutdown ( ) {
85+ global:: handle_error ( err) ;
6386 }
6487 }
6588}
6689
6790/// Creator and registry of named [`Tracer`] instances.
6891///
69- /// `TracerProvider` is lightweight container holding pointers to `SpanProcessor` and other components.
70- /// Cloning and dropping them will not stop the span processing. To stop span processing, users
71- /// must either call `shutdown` method explicitly, or drop every clone of `TracerProvider`.
92+ /// `TracerProvider` is a lightweight container holding pointers to `SpanProcessor` and other components.
93+ /// Cloning a `TracerProvider` instance will not stop span processing. To stop span processing, users
94+ /// must either call the `shutdown` method explicitly or allow the last reference to the `TracerProvider`
95+ /// to be dropped. When the last reference is dropped, the shutdown process will be automatically triggered
96+ /// to ensure proper cleanup.
7297#[ derive( Clone , Debug ) ]
7398pub struct TracerProvider {
7499 inner : Arc < TracerProviderInner > ,
@@ -157,31 +182,7 @@ impl TracerProvider {
157182 ///
158183 /// Note that shut down doesn't means the TracerProvider has dropped
159184 pub fn shutdown ( & self ) -> TraceResult < ( ) > {
160- if self
161- . inner
162- . is_shutdown
163- . compare_exchange ( false , true , Ordering :: SeqCst , Ordering :: SeqCst )
164- . is_ok ( )
165- {
166- // propagate the shutdown signal to processors
167- // it's up to the processor to properly block new spans after shutdown
168- let mut errs = vec ! [ ] ;
169- for processor in & self . inner . processors {
170- if let Err ( err) = processor. shutdown ( ) {
171- errs. push ( err) ;
172- }
173- }
174-
175- if errs. is_empty ( ) {
176- Ok ( ( ) )
177- } else {
178- Err ( TraceError :: Other ( format ! ( "{errs:?}" ) . into ( ) ) )
179- }
180- } else {
181- Err ( TraceError :: Other (
182- "tracer provider already shut down" . into ( ) ,
183- ) )
184- }
185+ self . inner . shutdown ( )
185186 }
186187}
187188
0 commit comments