@@ -94,6 +94,11 @@ thread_local! {
9494/// ```
9595#[ derive( Clone , Default ) ]
9696pub struct Context {
97+ pub ( super ) inner : Option < Arc < InnerContext > > ,
98+ }
99+
100+ #[ derive( Clone , Default ) ]
101+ pub ( super ) struct InnerContext {
97102 #[ cfg( feature = "trace" ) ]
98103 pub ( crate ) span : Option < Arc < SynchronizedSpan > > ,
99104 entries : Option < Arc < EntryMap > > ,
@@ -198,7 +203,9 @@ impl Context {
198203 /// assert_eq!(cx.get::<MyUser>(), None);
199204 /// ```
200205 pub fn get < T : ' static > ( & self ) -> Option < & T > {
201- self . entries
206+ self . inner
207+ . as_ref ( ) ?
208+ . entries
202209 . as_ref ( ) ?
203210 . get ( & TypeId :: of :: < T > ( ) ) ?
204211 . downcast_ref ( )
@@ -232,20 +239,30 @@ impl Context {
232239 /// assert_eq!(cx_with_a_and_b.get::<ValueB>(), Some(&ValueB(42)));
233240 /// ```
234241 pub fn with_value < T : ' static + Send + Sync > ( & self , value : T ) -> Self {
235- let entries = if let Some ( current_entries) = & self . entries {
236- let mut inner_entries = ( * * current_entries) . clone ( ) ;
237- inner_entries. insert ( TypeId :: of :: < T > ( ) , Arc :: new ( value) ) ;
238- Some ( Arc :: new ( inner_entries) )
242+ if let Some ( inner) = & self . inner {
243+ let ( mut entries, suppress_telemetry) = if let Some ( entries) = & inner. entries {
244+ ( ( * * entries) . clone ( ) , inner. suppress_telemetry )
245+ } else {
246+ ( EntryMap :: default ( ) , inner. suppress_telemetry )
247+ } ;
248+ entries. insert ( TypeId :: of :: < T > ( ) , Arc :: new ( value) ) ;
249+ Context {
250+ inner : Some ( Arc :: new ( InnerContext {
251+ #[ cfg( feature = "trace" ) ]
252+ span : inner. span . clone ( ) ,
253+ entries : Some ( Arc :: new ( entries) ) ,
254+ suppress_telemetry,
255+ } ) ) ,
256+ }
239257 } else {
240258 let mut entries = EntryMap :: default ( ) ;
241259 entries. insert ( TypeId :: of :: < T > ( ) , Arc :: new ( value) ) ;
242- Some ( Arc :: new ( entries) )
243- } ;
244- Context {
245- entries,
246- #[ cfg( feature = "trace" ) ]
247- span : self . span . clone ( ) ,
248- suppress_telemetry : self . suppress_telemetry ,
260+ Context {
261+ inner : Some ( Arc :: new ( InnerContext {
262+ entries : Some ( Arc :: new ( entries) ) ,
263+ ..Default :: default ( )
264+ } ) ) ,
265+ }
249266 }
250267 }
251268
@@ -335,16 +352,35 @@ impl Context {
335352 /// Returns whether telemetry is suppressed in this context.
336353 #[ inline]
337354 pub fn is_telemetry_suppressed ( & self ) -> bool {
338- self . suppress_telemetry
355+ if let Some ( inner) = & self . inner {
356+ inner. suppress_telemetry
357+ } else {
358+ false
359+ }
339360 }
340361
341362 /// Returns a new context with telemetry suppression enabled.
342363 pub fn with_telemetry_suppressed ( & self ) -> Self {
343- Context {
344- entries : self . entries . clone ( ) ,
345- #[ cfg( feature = "trace" ) ]
346- span : self . span . clone ( ) ,
347- suppress_telemetry : true ,
364+ if self . is_telemetry_suppressed ( ) {
365+ return self . clone ( ) ;
366+ }
367+
368+ if let Some ( inner) = & self . inner {
369+ Context {
370+ inner : Some ( Arc :: new ( InnerContext {
371+ #[ cfg( feature = "trace" ) ]
372+ span : inner. span . clone ( ) ,
373+ entries : inner. entries . clone ( ) ,
374+ suppress_telemetry : true ,
375+ } ) ) ,
376+ }
377+ } else {
378+ Context {
379+ inner : Some ( Arc :: new ( InnerContext {
380+ suppress_telemetry : true ,
381+ ..Default :: default ( )
382+ } ) ) ,
383+ }
348384 }
349385 }
350386
@@ -410,43 +446,53 @@ impl Context {
410446
411447 #[ cfg( feature = "trace" ) ]
412448 pub ( crate ) fn current_with_synchronized_span ( value : SynchronizedSpan ) -> Self {
413- Self :: map_current ( |cx| Context {
414- span : Some ( Arc :: new ( value) ) ,
415- entries : cx. entries . clone ( ) ,
416- suppress_telemetry : cx. suppress_telemetry ,
417- } )
449+ Self :: map_current ( |cx| cx. with_synchronized_span ( value) )
418450 }
419451
420452 #[ cfg( feature = "trace" ) ]
421453 pub ( crate ) fn with_synchronized_span ( & self , value : SynchronizedSpan ) -> Self {
454+ let ( entries, suppress_telemetry) = if let Some ( inner) = & self . inner {
455+ ( inner. entries . clone ( ) , inner. suppress_telemetry )
456+ } else {
457+ ( None , false )
458+ } ;
422459 Context {
423- span : Some ( Arc :: new ( value) ) ,
424- entries : self . entries . clone ( ) ,
425- suppress_telemetry : self . suppress_telemetry ,
460+ inner : Some ( Arc :: new ( InnerContext {
461+ span : Some ( Arc :: new ( value) ) ,
462+ entries,
463+ suppress_telemetry,
464+ } ) ) ,
426465 }
427466 }
428467}
429468
430469impl fmt:: Debug for Context {
431470 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
432471 let mut dbg = f. debug_struct ( "Context" ) ;
472+ let mut entries = 0 ;
473+ let mut suppress_telemetry = false ;
433474
434- #[ cfg( feature = "trace" ) ]
435- let mut entries = self . entries . as_ref ( ) . map_or ( 0 , |e| e. len ( ) ) ;
436- #[ cfg( feature = "trace" ) ]
437- {
438- if let Some ( span) = & self . span {
439- dbg. field ( "span" , & span. span_context ( ) ) ;
440- entries += 1 ;
441- } else {
475+ if let Some ( inner) = & self . inner {
476+ entries = inner. entries . as_ref ( ) . map_or ( 0 , |e| e. len ( ) ) ;
477+ #[ cfg( feature = "trace" ) ]
478+ {
479+ if let Some ( span) = inner. span . as_ref ( ) {
480+ dbg. field ( "span" , & span. span_context ( ) ) ;
481+ entries += 1 ;
482+ } else {
483+ dbg. field ( "span" , & "None" ) ;
484+ }
485+ }
486+ suppress_telemetry = inner. suppress_telemetry ;
487+ } else {
488+ #[ cfg( feature = "trace" ) ]
489+ {
442490 dbg. field ( "span" , & "None" ) ;
443491 }
444492 }
445- #[ cfg( not( feature = "trace" ) ) ]
446- let entries = self . entries . as_ref ( ) . map_or ( 0 , |e| e. len ( ) ) ;
447493
448494 dbg. field ( "entries count" , & entries)
449- . field ( "suppress_telemetry" , & self . suppress_telemetry )
495+ . field ( "suppress_telemetry" , & suppress_telemetry)
450496 . finish ( )
451497 }
452498}
0 commit comments