@@ -92,6 +92,11 @@ thread_local! {
9292/// ```
9393#[ derive( Clone , Default ) ]
9494pub struct Context {
95+ pub ( super ) inner : Option < Arc < InnerContext > > ,
96+ }
97+
98+ #[ derive( Clone , Default ) ]
99+ pub ( super ) struct InnerContext {
95100 #[ cfg( feature = "trace" ) ]
96101 pub ( crate ) span : Option < Arc < SynchronizedSpan > > ,
97102 entries : Option < Arc < EntryMap > > ,
@@ -196,7 +201,9 @@ impl Context {
196201 /// assert_eq!(cx.get::<MyUser>(), None);
197202 /// ```
198203 pub fn get < T : ' static > ( & self ) -> Option < & T > {
199- self . entries
204+ self . inner
205+ . as_ref ( ) ?
206+ . entries
200207 . as_ref ( ) ?
201208 . get ( & TypeId :: of :: < T > ( ) ) ?
202209 . downcast_ref ( )
@@ -230,20 +237,28 @@ impl Context {
230237 /// assert_eq!(cx_with_a_and_b.get::<ValueB>(), Some(&ValueB(42)));
231238 /// ```
232239 pub fn with_value < T : ' static + Send + Sync > ( & self , value : T ) -> Self {
233- let entries = if let Some ( current_entries) = & self . entries {
234- let mut inner_entries = ( * * current_entries) . clone ( ) ;
235- inner_entries. insert ( TypeId :: of :: < T > ( ) , Arc :: new ( value) ) ;
236- Some ( Arc :: new ( inner_entries) )
240+ let ( span, mut entries, suppress_telemetry) = if let Some ( inner) = & self . inner {
241+ #[ cfg( feature = "trace" ) ]
242+ let span = inner. span . clone ( ) ;
243+ #[ cfg( not( feature = "trace" ) ) ]
244+ let span: Option < ( ) > = None ;
245+
246+ if let Some ( entries) = & inner. entries {
247+ ( span, ( * * entries) . clone ( ) , inner. suppress_telemetry )
248+ } else {
249+ ( span, EntryMap :: default ( ) , inner. suppress_telemetry )
250+ }
237251 } else {
238- let mut entries = EntryMap :: default ( ) ;
239- entries. insert ( TypeId :: of :: < T > ( ) , Arc :: new ( value) ) ;
240- Some ( Arc :: new ( entries) )
252+ ( None , EntryMap :: default ( ) , false )
241253 } ;
254+ entries. insert ( TypeId :: of :: < T > ( ) , Arc :: new ( value) ) ;
242255 Context {
243- entries,
244- #[ cfg( feature = "trace" ) ]
245- span : self . span . clone ( ) ,
246- suppress_telemetry : self . suppress_telemetry ,
256+ inner : Some ( Arc :: new ( InnerContext {
257+ #[ cfg( feature = "trace" ) ]
258+ span,
259+ entries : Some ( Arc :: new ( entries) ) ,
260+ suppress_telemetry,
261+ } ) ) ,
247262 }
248263 }
249264
@@ -333,16 +348,37 @@ impl Context {
333348 /// Returns whether telemetry is suppressed in this context.
334349 #[ inline]
335350 pub fn is_telemetry_suppressed ( & self ) -> bool {
336- self . suppress_telemetry
351+ if let Some ( inner) = & self . inner {
352+ inner. suppress_telemetry
353+ } else {
354+ false
355+ }
337356 }
338357
339358 /// Returns a new context with telemetry suppression enabled.
340359 pub fn with_telemetry_suppressed ( & self ) -> Self {
341- Context {
342- entries : self . entries . clone ( ) ,
360+ if self . is_telemetry_suppressed ( ) {
361+ return self . clone ( ) ;
362+ }
363+ let ( span, entries) = if let Some ( inner) = & self . inner {
343364 #[ cfg( feature = "trace" ) ]
344- span : self . span . clone ( ) ,
345- suppress_telemetry : true ,
365+ {
366+ ( inner. span . clone ( ) , inner. entries . clone ( ) )
367+ }
368+ #[ cfg( not( feature = "trace" ) ) ]
369+ {
370+ ( Option :: < ( ) > :: None , inner. entries . clone ( ) )
371+ }
372+ } else {
373+ ( None , None )
374+ } ;
375+ Context {
376+ inner : Some ( Arc :: new ( InnerContext {
377+ #[ cfg( feature = "trace" ) ]
378+ span,
379+ entries,
380+ suppress_telemetry : true ,
381+ } ) ) ,
346382 }
347383 }
348384
@@ -408,30 +444,38 @@ impl Context {
408444
409445 #[ cfg( feature = "trace" ) ]
410446 pub ( crate ) fn current_with_synchronized_span ( value : SynchronizedSpan ) -> Self {
411- Self :: map_current ( |cx| Context {
412- span : Some ( Arc :: new ( value) ) ,
413- entries : cx. entries . clone ( ) ,
414- suppress_telemetry : cx. suppress_telemetry ,
415- } )
447+ Self :: map_current ( |cx| cx. with_synchronized_span ( value) )
416448 }
417449
418450 #[ cfg( feature = "trace" ) ]
419451 pub ( crate ) fn with_synchronized_span ( & self , value : SynchronizedSpan ) -> Self {
452+ let ( entries, suppress_telemetry) = if let Some ( inner) = & self . inner {
453+ ( inner. entries . clone ( ) , inner. suppress_telemetry )
454+ } else {
455+ ( None , false )
456+ } ;
420457 Context {
421- span : Some ( Arc :: new ( value) ) ,
422- entries : self . entries . clone ( ) ,
423- suppress_telemetry : self . suppress_telemetry ,
458+ inner : Some ( Arc :: new ( InnerContext {
459+ span : Some ( Arc :: new ( value) ) ,
460+ entries,
461+ suppress_telemetry,
462+ } ) ) ,
424463 }
425464 }
426465}
427466
428467impl fmt:: Debug for Context {
429468 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
430469 let mut dbg = f. debug_struct ( "Context" ) ;
431- let mut entries = self . entries . as_ref ( ) . map_or ( 0 , |e| e. len ( ) ) ;
470+ let ( mut entries, suppress_telemetry) = self . inner . as_ref ( ) . map_or ( ( 0 , false ) , |inner| {
471+ (
472+ inner. entries . as_ref ( ) . map_or ( 0 , |e| e. len ( ) ) ,
473+ inner. suppress_telemetry ,
474+ )
475+ } ) ;
432476 #[ cfg( feature = "trace" ) ]
433477 {
434- if let Some ( span) = & self . span {
478+ if let Some ( span) = self . inner . as_ref ( ) . and_then ( |inner| inner . span . as_ref ( ) ) {
435479 dbg. field ( "span" , & span. span_context ( ) ) ;
436480 entries += 1 ;
437481 } else {
@@ -440,7 +484,7 @@ impl fmt::Debug for Context {
440484 }
441485
442486 dbg. field ( "entries count" , & entries)
443- . field ( "suppress_telemetry" , & self . suppress_telemetry )
487+ . field ( "suppress_telemetry" , & suppress_telemetry)
444488 . finish ( )
445489 }
446490}
0 commit comments