Skip to content

Commit

Permalink
docs and cleanup the type parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
guswynn committed Jun 9, 2022
1 parent 51a0b8c commit 87fd6d2
Showing 1 changed file with 49 additions and 35 deletions.
84 changes: 49 additions & 35 deletions tracing-subscriber/src/reload.rs
@@ -1,15 +1,25 @@
//! Wrapper for a `Collect` or `Subscribe` to allow it to be dynamically reloaded.
//!
//! This module provides a type implementing [`Subscribe`] which wraps another type implementing
//! the [`Subscribe`] trait, allowing the wrapped type to be replaced with another
//! This module provides a type implementing [`Subscribe`] and [`Filter`]
//! which wraps another type implementing the corresponding trait. This
//! allows the wrapped type to be replaced with another
//! instance of that type at runtime.
//!
//! This can be used in cases where a subset of `Collect` functionality
//! This can be used in cases where a subset of `Collect` or `Filter` functionality
//! should be dynamically reconfigured, such as when filtering directives may
//! change at runtime. Note that this subscriber introduces a (relatively small)
//! amount of overhead, and should thus only be used as needed.
//!
//! ## Note
//! The [`Subscriber`] implementation is unable to implement downcasting functionality,
//! so you may find certain `Subscriber`s fail to function properly if wrapped in a
//! `reload::Subscriber`.
//!
//! If you only want to be able to dynamically change the
//! `Filter` on your layer, prefer wrapping that `Filter` in the `reload::Subscriber`.
//!
//! [`Subscribe`]: crate::Subscribe
//! [`Filter`]: crate::subscribe::Filter
use crate::subscribe;
use crate::sync::RwLock;

Expand Down Expand Up @@ -119,25 +129,6 @@ where
}
}

impl<S> Subscriber<S> {
/// Wraps the given `Subscribe`, returning a subscriber and a `Handle` that allows
/// the inner type to be modified at runtime.
pub fn new(inner: S) -> (Self, Handle<S>) {
let this = Self {
inner: Arc::new(RwLock::new(inner)),
};
let handle = this.handle();
(this, handle)
}

/// Returns a `Handle` that can be used to reload the wrapped `Subscribe`.
pub fn handle(&self) -> Handle<S> {
Handle {
inner: Arc::downgrade(&self.inner),
}
}
}

#[cfg(all(feature = "registry", feature = "std"))]
#[cfg_attr(docsrs, doc(cfg(all(feature = "registry", feature = "std"))))]
impl<S, C> crate::subscribe::Filter<C> for Subscriber<S>
Expand Down Expand Up @@ -191,24 +182,47 @@ where
}
}

impl<O> Subscriber<O> {
/// Wraps the given `Subscribe` or `Filter`,
/// returning a subscriber or filter and a `Handle` that allows
/// the inner type to be modified at runtime.
pub fn new(inner: O) -> (Self, Handle<O>) {
let this = Self {
inner: Arc::new(RwLock::new(inner)),
};
let handle = this.handle();
(this, handle)
}

/// Returns a `Handle` that can be used to reload the wrapped `Subscribe`.
pub fn handle(&self) -> Handle<O> {
Handle {
inner: Arc::downgrade(&self.inner),
}
}
}

// ===== impl Handle =====

impl<S> Handle<S> {
/// Replace the current subscriber with the provided `new_subscriber`.
impl<O> Handle<O> {
/// Replace the current subscriber or filter with the provided `new_object`.
///
/// **Warning:** The [`Filtered`](crate::filter::Filtered) type currently can't be changed
/// **Warning:** If this `Handle` is being used with the [`Filtered`](crate::filter::Filtered)
/// subscriber, it currently can't be changed
/// at runtime via the [`Handle::reload`] method.
/// Use the [`Handle::modify`] method to change the filter instead.
/// (see <https://github.com/tokio-rs/tracing/issues/1629>)
pub fn reload(&self, new_subscriber: impl Into<S>) -> Result<(), Error> {
self.modify(|subscriber| {
*subscriber = new_subscriber.into();
/// (see <https://github.com/tokio-rs/tracing/issues/1629>) However, if you only want to change
/// the underlying [`Filter`](crate::subscribe::Filter), then use the `reload::Subscriber` to
/// wrap the `Filter` itself.
pub fn reload(&self, new_object: impl Into<O>) -> Result<(), Error> {
self.modify(|object| {
*object = new_object.into();
})
}

/// Invokes a closure with a mutable reference to the current subscriber,
/// allowing it to be modified in place.
pub fn modify(&self, f: impl FnOnce(&mut S)) -> Result<(), Error> {
pub fn modify(&self, f: impl FnOnce(&mut O)) -> Result<(), Error> {
let inner = self.inner.upgrade().ok_or(Error {
kind: ErrorKind::CollectorGone,
})?;
Expand All @@ -235,16 +249,16 @@ impl<S> Handle<S> {

/// Returns a clone of the subscriber's current value if it still exists.
/// Otherwise, if the collector has been dropped, returns `None`.
pub fn clone_current(&self) -> Option<S>
pub fn clone_current(&self) -> Option<O>
where
S: Clone,
O: Clone,
{
self.with_current(S::clone).ok()
self.with_current(O::clone).ok()
}

/// Invokes a closure with a borrowed reference to the current subscriber,
/// returning the result (or an error if the collector no longer exists).
pub fn with_current<T>(&self, f: impl FnOnce(&S) -> T) -> Result<T, Error> {
pub fn with_current<T>(&self, f: impl FnOnce(&O) -> T) -> Result<T, Error> {
let inner = self.inner.upgrade().ok_or(Error {
kind: ErrorKind::CollectorGone,
})?;
Expand All @@ -253,7 +267,7 @@ impl<S> Handle<S> {
}
}

impl<S> Clone for Handle<S> {
impl<O> Clone for Handle<O> {
fn clone(&self) -> Self {
Handle {
inner: self.inner.clone(),
Expand Down

0 comments on commit 87fd6d2

Please sign in to comment.