Skip to main content

ContextSnapshot

Struct ContextSnapshot 

Source
pub struct ContextSnapshot { /* private fields */ }
Available on crate feature std only.
Expand description

An owned, immutable copy of a set of context fields.

Send + Sync and cheap to clone, so it can be moved into threads, tasks, and closures. Install it on the current thread with ContextSnapshot::attach, ContextSnapshot::scope or ContextSnapshot::wrap. An attached snapshot behaves like a group of with_field entries: fields pushed later shadow it, and it shadows fields pushed earlier.

Implementations§

Source§

impl ContextSnapshot

Source

pub fn from_fields(fields: &[Field<'_>]) -> Self

Build a snapshot from explicit fields, without touching the thread’s context. Later fields shadow earlier ones with the same key.

§Examples
use log_io::context::ContextSnapshot;
use log_io::Field;

let snap = ContextSnapshot::from_fields(&[Field::new("tenant", "acme")]);
assert_eq!(snap.len(), 1);
Source

pub fn len(&self) -> usize

Number of fields in the snapshot.

Source

pub fn is_empty(&self) -> bool

true if the snapshot has no fields.

Source

pub fn iter(&self) -> impl Iterator<Item = Field<'_>>

Iterate over the snapshot’s fields in insertion order.

Source

pub fn attach(&self) -> ContextGuard

Install the snapshot on the current thread until the returned guard is dropped. Does not allocate.

Source

pub fn scope<R>(&self, f: impl FnOnce() -> R) -> R

Run f with the snapshot installed on the current thread.

Source

pub fn wrap<F: Future>(&self, future: F) -> WithContext<F> ⓘ

Wrap a future so the snapshot is installed around every poll.

Works with any executor, including work-stealing ones: whichever thread polls the future sees the snapshot for exactly the duration of the poll.

Context the future itself pushes and holds across an .await (a ContextGuard alive in the future’s state) is taken off the thread when the poll returns Pending and put back at the start of the next poll, so other futures polled on the same thread do not see it. Such a future is !Send, so it always resumes on the thread that created the guard.

The future is boxed once (one allocation per wrapped future) so the wrapper can be Unpin without unsafe code; holding context across an .await allocates once more, on first use.

§Examples
use std::future::Future;
use std::pin::pin;
use std::task::{Context, Poll, Waker};
use log_io::context::{self, ContextSnapshot};

/// Returns `Pending` once, like an `.await` on I/O.
struct YieldOnce(bool);
impl Future for YieldOnce {
    type Output = ();
    fn poll(mut self: std::pin::Pin<&mut Self>, _: &mut Context<'_>) -> Poll<()> {
        if self.0 { Poll::Ready(()) } else { self.0 = true; Poll::Pending }
    }
}

let mut task = pin!(ContextSnapshot::default().wrap(async {
    let _tenant = context::with_field("tenant", "a");
    YieldOnce(false).await;
    assert_eq!(context::len(), 1); // back while this future runs
}));
let mut cx = Context::from_waker(Waker::noop());
assert!(task.as_mut().poll(&mut cx).is_pending());
assert_eq!(context::len(), 0); // not visible to anything else
assert!(task.as_mut().poll(&mut cx).is_ready());

Trait Implementations§

Source§

impl Clone for ContextSnapshot

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ContextSnapshot

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for ContextSnapshot

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.