@@ -226,10 +226,10 @@ impl Span {
226226 ///
227227 /// [`LocalSpan`]: crate::local::LocalSpan
228228 /// [`LocalSpan::enter_with_local_parent()`]: crate::local::LocalSpan::enter_with_local_parent
229- pub fn set_local_parent ( & self ) -> Option < impl Drop > {
229+ pub fn set_local_parent ( & self ) -> LocalParentGuard {
230230 #[ cfg( not( feature = "enable" ) ) ]
231231 {
232- None :: < Span >
232+ LocalParentGuard :: noop ( )
233233 }
234234
235235 #[ cfg( feature = "enable" ) ]
@@ -388,10 +388,11 @@ impl Span {
388388 pub ( crate ) fn attach_into_stack (
389389 & self ,
390390 stack : & Rc < RefCell < LocalSpanStack > > ,
391- ) -> Option < impl Drop > {
391+ ) -> LocalParentGuard {
392392 self . inner
393393 . as_ref ( )
394394 . map ( move |inner| inner. capture_local_spans ( stack. clone ( ) ) )
395+ . unwrap_or_else ( LocalParentGuard :: noop)
395396 }
396397}
397398
@@ -409,19 +410,11 @@ impl SpanInner {
409410 }
410411
411412 #[ inline]
412- fn capture_local_spans ( & self , stack : Rc < RefCell < LocalSpanStack > > ) -> impl Drop {
413+ fn capture_local_spans ( & self , stack : Rc < RefCell < LocalSpanStack > > ) -> LocalParentGuard {
413414 let token = self . issue_collect_token ( ) . collect ( ) ;
414415 let collector = LocalCollector :: new ( Some ( token) , stack) ;
415- let collect = self . collect . clone ( ) ;
416- defer:: defer ( move || {
417- let ( spans, token) = collector. collect_spans_and_token ( ) ;
418- debug_assert ! ( token. is_some( ) ) ;
419- let token = token. unwrap_or_else ( || [ ] . iter ( ) . collect ( ) ) ;
420416
421- if !spans. spans . is_empty ( ) {
422- collect. submit_spans ( SpanSet :: LocalSpansInner ( spans) , token) ;
423- }
424- } )
417+ LocalParentGuard :: new ( collector, self . collect . clone ( ) )
425418 }
426419
427420 #[ inline]
@@ -473,6 +466,51 @@ impl Drop for Span {
473466 }
474467}
475468
469+ /// A guard created by [`Span::set_local_parent()`].
470+ #[ derive( Default ) ]
471+ pub struct LocalParentGuard {
472+ #[ cfg( feature = "enable" ) ]
473+ inner : Option < LocalParentGuardInner > ,
474+ }
475+
476+ struct LocalParentGuardInner {
477+ collector : LocalCollector ,
478+ collect : GlobalCollect ,
479+ }
480+
481+ impl LocalParentGuard {
482+ pub ( crate ) fn noop ( ) -> LocalParentGuard {
483+ LocalParentGuard {
484+ #[ cfg( feature = "enable" ) ]
485+ inner : None ,
486+ }
487+ }
488+
489+ pub ( crate ) fn new ( collector : LocalCollector , collect : GlobalCollect ) -> LocalParentGuard {
490+ LocalParentGuard {
491+ #[ cfg( feature = "enable" ) ]
492+ inner : Some ( LocalParentGuardInner { collector, collect } ) ,
493+ }
494+ }
495+ }
496+
497+ impl Drop for LocalParentGuard {
498+ fn drop ( & mut self ) {
499+ #[ cfg( feature = "enable" ) ]
500+ if let Some ( inner) = self . inner . take ( ) {
501+ let ( spans, token) = inner. collector . collect_spans_and_token ( ) ;
502+ debug_assert ! ( token. is_some( ) ) ;
503+ if let Some ( token) = token {
504+ if !spans. spans . is_empty ( ) {
505+ inner
506+ . collect
507+ . submit_spans ( SpanSet :: LocalSpansInner ( spans) , token) ;
508+ }
509+ }
510+ }
511+ }
512+ }
513+
476514#[ cfg( test) ]
477515mod tests {
478516 use std:: sync:: atomic:: AtomicUsize ;
@@ -495,7 +533,7 @@ mod tests {
495533 fn noop_basic ( ) {
496534 let span = Span :: noop ( ) ;
497535 let stack = Rc :: new ( RefCell :: new ( LocalSpanStack :: with_capacity ( 16 ) ) ) ;
498- assert ! ( span. attach_into_stack( & stack) . is_none( ) ) ;
536+ assert ! ( span. attach_into_stack( & stack) . inner . is_none( ) ) ;
499537 assert ! ( stack. borrow_mut( ) . enter_span( "span1" ) . is_none( ) ) ;
500538 }
501539
@@ -809,11 +847,11 @@ parent5 []
809847 {
810848 let parent_ctx = SpanContext :: random ( ) ;
811849 let root = Span :: root ( "root" , parent_ctx, collect. clone ( ) ) ;
812- let _g = root. attach_into_stack ( & stack) . unwrap ( ) ;
850+ let _g = root. attach_into_stack ( & stack) ;
813851 let child =
814852 Span :: enter_with_stack ( "child" , & mut stack. borrow_mut ( ) , collect. clone ( ) ) ;
815853 {
816- let _g = child. attach_into_stack ( & stack) . unwrap ( ) ;
854+ let _g = child. attach_into_stack ( & stack) ;
817855 let _s = Span :: enter_with_stack ( "grandchild" , & mut stack. borrow_mut ( ) , collect) ;
818856 }
819857 let _s = LocalSpan :: enter_with_stack ( "local" , stack) ;
0 commit comments