Skip to content

Commit

Permalink
core: don't clone Arcs for static dispatchers
Browse files Browse the repository at this point in the history
This backports more of the change from #1017 to `v0.1.x`. This change
makes cloning a `&'static` global dispatcher and a `None` dispatcher no
longer require an `Arc` clone. `None` dispatchers no longer allocate.

This undoes much of the performance regression from the previous commit:

```

     Running benches/baseline.rs (target/release/deps/baseline-9b70733ce49582d2)comparison/relaxed_load time:   [467.51 ps 468.35 ps 469.23 ps]
                        change: [-0.8492% -0.5683% -0.3377%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 3 outliers among 100 measurements (3.00%)
  3 (3.00%) high mild
comparison/acquire_load time:   [473.86 ps 476.62 ps 480.23 ps]
                        change: [+0.0428% +0.6687% +1.2841%] (p = 0.04 < 0.05)
                        Change within noise threshold.
Found 14 outliers among 100 measurements (14.00%)
  8 (8.00%) high mild
  6 (6.00%) high severe
comparison/log          time:   [235.40 ps 236.35 ps 237.77 ps]
                        change: [-0.3095% +0.3407% +1.2059%] (p = 0.50 > 0.05)
                        No change in performance detected.
Found 16 outliers among 100 measurements (16.00%)
  3 (3.00%) low severe
  6 (6.00%) low mild
  3 (3.00%) high mild
  4 (4.00%) high severe

     Running benches/dispatch_get_clone.rs (target/release/deps/dispatch_get_clone-d4d6ca1f9895e432)Dispatch::get_clone/none
                        time:   [8.3471 ns 8.3649 ns 8.3863 ns]
                        change: [-64.375% -64.301% -64.226%] (p = 0.00 < 0.05)
                        Performance has improved.
Dispatch::get_clone/scoped
                        time:   [17.054 ns 17.081 ns 17.108 ns]
                        change: [+53.653% +53.819% +53.991%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 7 outliers among 100 measurements (7.00%)
  2 (2.00%) high mild
  5 (5.00%) high severe
Dispatch::get_clone/global
                        time:   [8.4810 ns 8.4853 ns 8.4901 ns]
                        change: [-64.773% -64.741% -64.710%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 16 outliers among 100 measurements (16.00%)
  15 (15.00%) high mild
  1 (1.00%) high severe

     Running benches/dispatch_get_ref.rs (target/release/deps/dispatch_get_ref-6ce05749a0b1bf87)Dispatch::get_ref/none  time:   [1.8803 ns 1.8826 ns 1.8853 ns]
                        change: [-86.888% -86.856% -86.812%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 5 outliers among 100 measurements (5.00%)
  1 (1.00%) high mild
  4 (4.00%) high severe
Dispatch::get_ref/scoped
                        time:   [3.8294 ns 3.8422 ns 3.8529 ns]
                        change: [-1.5952% -1.3861% -1.1447%] (p = 0.00 < 0.05)
                        Performance has improved.
Dispatch::get_ref/global
                        time:   [1.8859 ns 1.8901 ns 1.8936 ns]
                        change: [-87.025% -86.963% -86.907%] (p = 0.00 < 0.05)
                        Performance has improved.

     Running benches/empty_span.rs (target/release/deps/empty_span-745c777d77b8b7ca)empty_span/none         time:   [234.18 ps 234.44 ps 234.68 ps]
                        change: [+1.4833% +1.6364% +1.7788%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 7 outliers among 100 measurements (7.00%)
  5 (5.00%) low mild
  1 (1.00%) high mild
  1 (1.00%) high severe
empty_span/scoped       time:   [235.19 ps 236.00 ps 236.71 ps]
                        change: [+0.5261% +0.8586% +1.1517%] (p = 0.00 < 0.05)
                        Change within noise threshold.
empty_span/global       time:   [235.04 ps 235.52 ps 236.15 ps]
                        change: [-0.0215% +0.7651% +2.1704%] (p = 0.17 > 0.05)
                        No change in performance detected.
Found 7 outliers among 100 measurements (7.00%)
  3 (3.00%) low mild
  1 (1.00%) high mild
  3 (3.00%) high severe
empty_span/baseline_struct
                        time:   [704.83 ps 705.28 ps 705.80 ps]
                        change: [+0.0246% +0.6522% +1.5423%] (p = 0.10 > 0.05)
                        No change in performance detected.
Found 4 outliers among 100 measurements (4.00%)
  2 (2.00%) high mild
  2 (2.00%) high severe

     Running benches/enter_span.rs (target/release/deps/enter_span-7fc1c2a69c076475)enter_span/none         time:   [0.0000 ps 0.0000 ps 0.0000 ps]
                        change: [-49.467% +1.5232% +101.49%] (p = 0.98 > 0.05)
                        No change in performance detected.
Found 13 outliers among 100 measurements (13.00%)
  5 (5.00%) high mild
  8 (8.00%) high severe
enter_span/scoped       time:   [3.7519 ns 3.7648 ns 3.7776 ns]
                        change: [+32.984% +33.297% +33.588%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 7 outliers among 100 measurements (7.00%)
  6 (6.00%) low mild
  1 (1.00%) high mild
enter_span/global       time:   [3.7399 ns 3.7532 ns 3.7687 ns]
                        change: [+33.878% +34.287% +34.719%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 19 outliers among 100 measurements (19.00%)
  14 (14.00%) low severe
  2 (2.00%) low mild
  1 (1.00%) high mild
  2 (2.00%) high severe

     Running benches/event.rs (target/release/deps/event-6742eef6ebe07aa4)event/none              time:   [234.52 ps 234.95 ps 235.48 ps]
                        change: [-0.2638% +0.2782% +0.7705%] (p = 0.34 > 0.05)
                        No change in performance detected.
Found 8 outliers among 100 measurements (8.00%)
  4 (4.00%) high mild
  4 (4.00%) high severe
event/scoped            time:   [8.8083 ns 8.8738 ns 8.9531 ns]
                        change: [-7.2455% -6.8819% -6.4900%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 3 outliers among 100 measurements (3.00%)
  1 (1.00%) high mild
  2 (2.00%) high severe
event/scoped_recording  time:   [32.472 ns 33.287 ns 34.363 ns]
                        change: [-9.3516% -0.4827% +9.1329%] (p = 0.89 > 0.05)
                        No change in performance detected.
Found 2 outliers among 100 measurements (2.00%)
  2 (2.00%) high severe
event/global            time:   [6.7528 ns 6.7610 ns 6.7701 ns]
                        change: [-70.199% -70.111% -70.013%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 11 outliers among 100 measurements (11.00%)
  1 (1.00%) low mild
  8 (8.00%) high mild
  2 (2.00%) high severe

     Running benches/shared.rs (target/release/deps/shared-9c2531bf46089869)

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

     Running benches/span_fields.rs (target/release/deps/span_fields-96dfd0a8a577dec6)span_fields/none        time:   [3.6797 ns 3.6839 ns 3.6888 ns]
                        change: [+12.223% +12.489% +12.735%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 4 outliers among 100 measurements (4.00%)
  1 (1.00%) low severe
  3 (3.00%) high mild
span_fields/scoped      time:   [32.995 ns 33.166 ns 33.349 ns]
                        change: [+13.805% +14.178% +14.526%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 4 outliers among 100 measurements (4.00%)
  1 (1.00%) high mild
  3 (3.00%) high severe
span_fields/scoped_recording
                        time:   [280.94 ns 283.54 ns 286.81 ns]
                        change: [+4.7144% +5.4942% +6.4857%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 7 outliers among 100 measurements (7.00%)
  2 (2.00%) high mild
  5 (5.00%) high severe
span_fields/global      time:   [29.370 ns 29.434 ns 29.505 ns]
                        change: [-27.391% -26.777% -26.346%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 1 outliers among 100 measurements (1.00%)
  1 (1.00%) low mild

     Running benches/span_no_fields.rs (target/release/deps/span_no_fields-f8c7d7a84f720442)span_no_fields/none     time:   [1.6604 ns 1.6663 ns 1.6725 ns]
                        change: [+18.306% +18.708% +19.155%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 6 outliers among 100 measurements (6.00%)
  2 (2.00%) low mild
  3 (3.00%) high mild
  1 (1.00%) high severe
span_no_fields/scoped   time:   [19.079 ns 19.107 ns 19.132 ns]
                        change: [+0.5306% +0.7813% +1.0349%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 2 outliers among 100 measurements (2.00%)
  2 (2.00%) high mild
span_no_fields/scoped_recording
                        time:   [32.628 ns 32.667 ns 32.707 ns]
                        change: [-0.3009% -0.1227% +0.0411%] (p = 0.18 > 0.05)
                        No change in performance detected.
span_no_fields/global   time:   [13.029 ns 13.042 ns 13.055 ns]
                        change: [-64.133% -64.076% -64.014%] (p = 0.00 < 0.05)
                        Performance has improved.

     Running benches/span_repeated.rs (target/release/deps/span_repeated-03bfaaf4ecd13d36)span_repeated/none      time:   [253.05 ns 256.87 ns 261.12 ns]
                        change: [-65.419% -65.179% -64.926%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 7 outliers among 100 measurements (7.00%)
  7 (7.00%) high severe
span_repeated/scoped    time:   [2.2869 µs 2.2926 µs 2.2986 µs]
                        change: [-8.5393% -8.3402% -8.1049%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 5 outliers among 100 measurements (5.00%)
  3 (3.00%) high mild
  2 (2.00%) high severe
span_repeated/scoped_recording
                        time:   [4.7143 µs 4.7286 µs 4.7451 µs]
                        change: [-5.0531% -4.7290% -4.3831%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 9 outliers among 100 measurements (9.00%)
  6 (6.00%) high mild
  3 (3.00%) high severe
span_repeated/global    time:   [2.1195 µs 2.1224 µs 2.1253 µs]
                        change: [-44.708% -44.624% -44.550%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 2 outliers among 100 measurements (2.00%)
  2 (2.00%) high mild
  ```
  • Loading branch information
hawkw committed May 11, 2023
1 parent d1849cb commit 50c70c2
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 46 deletions.
141 changes: 95 additions & 46 deletions tracing-core/src/dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ use core::ops::Deref;
/// `Dispatch` trace data to a [`Subscriber`].
#[derive(Clone)]
pub struct Dispatch {
subscriber: Arc<dyn Subscriber + Send + Sync>,
subscriber: Kind<Arc<dyn Subscriber + Send + Sync>>,
}

/// `WeakDispatch` is a version of [`Dispatch`] that holds a non-owning reference
Expand All @@ -176,13 +176,12 @@ pub struct Dispatch {
/// [here]: Subscriber#avoiding-memory-leaks
#[derive(Clone)]
pub struct WeakDispatch {
subscriber: Weak<dyn Subscriber + Send + Sync>,
subscriber: Kind<Weak<dyn Subscriber + Send + Sync>>,
}

#[cfg(feature = "alloc")]
#[derive(Clone)]
enum Kind<T> {
Global(&'static (dyn Collect + Send + Sync)),
Global(&'static (dyn Subscriber + Send + Sync)),
Scoped(T),
}

Expand All @@ -204,7 +203,13 @@ const UNINITIALIZED: usize = 0;
const INITIALIZING: usize = 1;
const INITIALIZED: usize = 2;

static mut GLOBAL_DISPATCH: Option<Dispatch> = None;
static mut GLOBAL_DISPATCH: Dispatch = Dispatch {
subscriber: Kind::Global(&NO_SUBSCRIBER),
};
static NONE: Dispatch = Dispatch {
subscriber: Kind::Global(&NO_SUBSCRIBER),
};
static NO_SUBSCRIBER: NoSubscriber = NoSubscriber::new();

/// The dispatch state of a thread.
#[cfg(feature = "std")]
Expand Down Expand Up @@ -308,8 +313,20 @@ pub fn set_global_default(dispatcher: Dispatch) -> Result<(), SetGlobalDefaultEr
)
.is_ok()
{
let subscriber = {
let subscriber = match dispatcher.subscriber {
Kind::Global(s) => s,
Kind::Scoped(s) => unsafe {
// safety: this leaks the subscriber onto the heap. the
// reference count will always be at least 1, because the
// global default will never be dropped.
&*Arc::into_raw(s)
},
};
Kind::Global(subscriber)
};
unsafe {
GLOBAL_DISPATCH = Some(dispatcher);
GLOBAL_DISPATCH = Dispatch { subscriber };
}
GLOBAL_INIT.store(INITIALIZED, Ordering::SeqCst);
EXISTS.store(true, Ordering::Release);
Expand Down Expand Up @@ -371,7 +388,7 @@ where
if SCOPED_COUNT.load(Ordering::Acquire) == 0 {
// fast path if no scoped dispatcher has been set; just use the global
// default.
return f(get_global().unwrap_or(&Dispatch::none()));
return f(get_global());
}

CURRENT_STATE
Expand Down Expand Up @@ -399,7 +416,7 @@ pub fn get_current<T>(f: impl FnOnce(&Dispatch) -> T) -> Option<T> {
if SCOPED_COUNT.load(Ordering::Acquire) == 0 {
// fast path if no scoped dispatcher has been set; just use the global
// default.
return Some(f(get_global()?));
return Some(f(get_global()));
}

CURRENT_STATE
Expand Down Expand Up @@ -435,28 +452,27 @@ where
}
}

fn get_global() -> Option<&'static Dispatch> {
#[inline]
fn get_global() -> &'static Dispatch {
if GLOBAL_INIT.load(Ordering::SeqCst) != INITIALIZED {
return None;
return &NONE;
}
unsafe {
// This is safe given the invariant that setting the global dispatcher
// also sets `GLOBAL_INIT` to `INITIALIZED`.
Some(GLOBAL_DISPATCH.as_ref().expect(
"invariant violated: GLOBAL_DISPATCH must be initialized before GLOBAL_INIT is set",
))
&GLOBAL_DISPATCH
}
}

#[cfg(feature = "std")]
pub(crate) struct Registrar(Weak<dyn Subscriber + Send + Sync>);
pub(crate) struct Registrar(Kind<Weak<dyn Subscriber + Send + Sync>>);

impl Dispatch {
/// Returns a new `Dispatch` that discards events and spans.
#[inline]
pub fn none() -> Self {
Dispatch {
subscriber: Arc::new(NoSubscriber::default()),
subscriber: Kind::Global(&NO_SUBSCRIBER),
}
}

Expand All @@ -468,15 +484,15 @@ impl Dispatch {
S: Subscriber + Send + Sync + 'static,
{
let me = Dispatch {
subscriber: Arc::new(subscriber),
subscriber: Kind::Scoped(Arc::new(subscriber)),
};
callsite::register_dispatch(&me);
me
}

#[cfg(feature = "std")]
pub(crate) fn registrar(&self) -> Registrar {
Registrar(Arc::downgrade(&self.subscriber))
Registrar(self.subscriber.downgrade())
}

/// Creates a [`WeakDispatch`] from this `Dispatch`.
Expand All @@ -495,14 +511,16 @@ impl Dispatch {
/// [here]: Subscriber#avoiding-memory-leaks
pub fn downgrade(&self) -> WeakDispatch {
WeakDispatch {
subscriber: Arc::downgrade(&self.subscriber),
subscriber: self.subscriber.downgrade(),
}
}

#[inline(always)]
#[cfg(not(feature = "alloc"))]
pub(crate) fn subscriber(&self) -> &(dyn Subscriber + Send + Sync) {
&self.subscriber
match self.subscriber {
Kind::Global(s) => s,
Kind::Scoped(ref s) => s.as_ref(),
}
}

/// Registers a new callsite with this collector, returning whether or not
Expand All @@ -515,7 +533,7 @@ impl Dispatch {
/// [`register_callsite`]: super::subscriber::Subscriber::register_callsite
#[inline]
pub fn register_callsite(&self, metadata: &'static Metadata<'static>) -> subscriber::Interest {
self.subscriber.register_callsite(metadata)
self.subscriber().register_callsite(metadata)
}

/// Returns the highest [verbosity level][level] that this [`Subscriber`] will
Expand All @@ -531,7 +549,7 @@ impl Dispatch {
// TODO(eliza): consider making this a public API?
#[inline]
pub(crate) fn max_level_hint(&self) -> Option<LevelFilter> {
self.subscriber.max_level_hint()
self.subscriber().max_level_hint()
}

/// Record the construction of a new span, returning a new [ID] for the
Expand All @@ -545,7 +563,7 @@ impl Dispatch {
/// [`new_span`]: super::subscriber::Subscriber::new_span
#[inline]
pub fn new_span(&self, span: &span::Attributes<'_>) -> span::Id {
self.subscriber.new_span(span)
self.subscriber().new_span(span)
}

/// Record a set of values on a span.
Expand All @@ -557,7 +575,7 @@ impl Dispatch {
/// [`record`]: super::subscriber::Subscriber::record
#[inline]
pub fn record(&self, span: &span::Id, values: &span::Record<'_>) {
self.subscriber.record(span, values)
self.subscriber().record(span, values)
}

/// Adds an indication that `span` follows from the span with the id
Expand All @@ -570,7 +588,7 @@ impl Dispatch {
/// [`record_follows_from`]: super::subscriber::Subscriber::record_follows_from
#[inline]
pub fn record_follows_from(&self, span: &span::Id, follows: &span::Id) {
self.subscriber.record_follows_from(span, follows)
self.subscriber().record_follows_from(span, follows)
}

/// Returns true if a span with the specified [metadata] would be
Expand All @@ -584,7 +602,7 @@ impl Dispatch {
/// [`enabled`]: super::subscriber::Subscriber::enabled
#[inline]
pub fn enabled(&self, metadata: &Metadata<'_>) -> bool {
self.subscriber.enabled(metadata)
self.subscriber().enabled(metadata)
}

/// Records that an [`Event`] has occurred.
Expand All @@ -597,8 +615,9 @@ impl Dispatch {
/// [`event`]: super::subscriber::Subscriber::event
#[inline]
pub fn event(&self, event: &Event<'_>) {
if self.subscriber.event_enabled(event) {
self.subscriber.event(event);
let subscriber = self.subscriber();
if subscriber.event_enabled(event) {
subscriber.event(event);
}
}

Expand All @@ -610,7 +629,7 @@ impl Dispatch {
/// [`Subscriber`]: super::subscriber::Subscriber
/// [`enter`]: super::subscriber::Subscriber::enter
pub fn enter(&self, span: &span::Id) {
self.subscriber.enter(span);
self.subscriber().enter(span);
}

/// Records that a span has been exited.
Expand All @@ -621,7 +640,7 @@ impl Dispatch {
/// [`Subscriber`]: super::subscriber::Subscriber
/// [`exit`]: super::subscriber::Subscriber::exit
pub fn exit(&self, span: &span::Id) {
self.subscriber.exit(span);
self.subscriber().exit(span);
}

/// Notifies the subscriber that a [span ID] has been cloned.
Expand All @@ -640,7 +659,7 @@ impl Dispatch {
/// [`new_span`]: super::subscriber::Subscriber::new_span
#[inline]
pub fn clone_span(&self, id: &span::Id) -> span::Id {
self.subscriber.clone_span(id)
self.subscriber().clone_span(id)
}

/// Notifies the subscriber that a [span ID] has been dropped.
Expand Down Expand Up @@ -669,7 +688,7 @@ impl Dispatch {
#[deprecated(since = "0.1.2", note = "use `Dispatch::try_close` instead")]
pub fn drop_span(&self, id: span::Id) {
#[allow(deprecated)]
self.subscriber.drop_span(id);
self.subscriber().drop_span(id);
}

/// Notifies the subscriber that a [span ID] has been dropped, and returns
Expand All @@ -688,7 +707,7 @@ impl Dispatch {
/// [`try_close`]: super::subscriber::Subscriber::try_close
/// [`new_span`]: super::subscriber::Subscriber::new_span
pub fn try_close(&self, id: span::Id) -> bool {
self.subscriber.try_close(id)
self.subscriber().try_close(id)
}

/// Returns a type representing this subscriber's view of the current span.
Expand All @@ -699,21 +718,21 @@ impl Dispatch {
/// [`current`]: super::subscriber::Subscriber::current_span
#[inline]
pub fn current_span(&self) -> span::Current {
self.subscriber.current_span()
self.subscriber().current_span()
}

/// Returns `true` if this `Dispatch` forwards to a `Subscriber` of type
/// `T`.
#[inline]
pub fn is<T: Any>(&self) -> bool {
<dyn Subscriber>::is::<T>(&self.subscriber)
<dyn Subscriber>::is::<T>(self.subscriber())
}

/// Returns some reference to the `Subscriber` this `Dispatch` forwards to
/// if it is of type `T`, or `None` if it isn't.
#[inline]
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
<dyn Subscriber>::downcast_ref(&self.subscriber)
<dyn Subscriber>::downcast_ref(self.subscriber())
}
}

Expand All @@ -726,9 +745,15 @@ impl Default for Dispatch {

impl fmt::Debug for Dispatch {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("Dispatch")
.field(&format_args!("{:p}", self.subscriber))
.finish()
match self.subscriber {
Kind::Scoped(ref s) => f.debug_tuple("Dispatch::Scoped")
.field(&format_args!("{:p}", s))
.finish(),
Kind::Global(s) => f.debug_tuple("Dispatch::Global")
.field(&format_args!("{:p}", s))
.finish(),
}

}
}

Expand Down Expand Up @@ -772,12 +797,14 @@ impl WeakDispatch {

impl fmt::Debug for WeakDispatch {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut tuple = f.debug_tuple("WeakDispatch");
match self.subscriber.upgrade() {
Some(subscriber) => tuple.field(&format_args!("Some({:p})", subscriber)),
None => tuple.field(&format_args!("None")),
};
tuple.finish()
match self.subscriber {
Kind::Scoped(ref s) => f.debug_tuple("WeakDispatch::Scoped")
.field(&format_args!("{:p}", s))
.finish(),
Kind::Global(s) => f.debug_tuple("WeakDispatch::Global")
.field(&format_args!("{:p}", s))
.finish(),
}
}
}

Expand All @@ -788,6 +815,28 @@ impl Registrar {
}
}


// ===== impl State =====

impl Kind<Arc<dyn Subscriber + Send + Sync>> {
fn downgrade(&self) -> Kind<Weak<dyn Subscriber + Send + Sync>> {
match self {
Kind::Global(s) => Kind::Global(*s),
Kind::Scoped(ref s) => Kind::Scoped(Arc::downgrade(s)),
}
}
}

impl Kind<Weak<dyn Subscriber + Send + Sync>> {
fn upgrade(&self) -> Option<Kind<Arc<dyn Subscriber + Send + Sync>>> {
match self {
Kind::Global(s) => Some(Kind::Global(*s)),
Kind::Scoped(ref s) => Some(Kind::Scoped(s.upgrade()?)),
}
}
}


// ===== impl State =====

#[cfg(feature = "std")]
Expand Down Expand Up @@ -829,7 +878,7 @@ impl<'a> Entered<'a> {
fn current(&self) -> RefMut<'a, Dispatch> {
let default = self.0.default.borrow_mut();
RefMut::map(default, |default| {
default.get_or_insert_with(|| get_global().cloned().unwrap_or_else(Dispatch::none))
default.get_or_insert_with(|| get_global().clone())
})
}
}
Expand Down
8 changes: 8 additions & 0 deletions tracing-core/src/subscriber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,14 @@ impl Subscriber for NoSubscriber {
fn exit(&self, _span: &span::Id) {}
}

impl NoSubscriber {
/// Returns a new `NoSubscriber`.
#[must_use]
pub const fn new() -> Self {
Self(())
}
}

impl<S> Subscriber for Box<S>
where
S: Subscriber + ?Sized,
Expand Down

0 comments on commit 50c70c2

Please sign in to comment.