Skip to content

Commit

Permalink
add dimension guard breadcrumbs
Browse files Browse the repository at this point in the history
A breadcrumb is useful for remembering how far you got into a workflow.
It's particularly useful when your async function might be dropped
and you want to know where it happened.
  • Loading branch information
kvc0 committed Mar 11, 2024
1 parent 8e06957 commit 542656b
Showing 1 changed file with 20 additions and 27 deletions.
47 changes: 20 additions & 27 deletions lib/src/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ use std::{
collections::HashMap,
fmt::Display,
hash::BuildHasher,
sync::{atomic::AtomicUsize, Arc},
sync::{atomic::AtomicUsize, Arc, Mutex},
time::Instant,
};

use futures::channel::oneshot;

use crate::{
allocator::Hasher,
types::{Dimension, Distribution, Measurement, Name, Observation},
Expand Down Expand Up @@ -53,49 +51,44 @@ pub struct Metrics<TBuildHasher = Hasher> {

#[derive(Debug)]
pub struct DimensionGuard {
override_sender: oneshot::Sender<Dimension>,
value: Arc<Mutex<Dimension>>,
}
impl DimensionGuard {
fn new(name: Name, default: Dimension) -> (Self, OverrideDimension) {
let (override_sender, override_receiver) = oneshot::channel();
let value = Arc::new(Mutex::new(default));
(
Self { override_sender },
OverrideDimension {
name,
default,
override_receiver,
Self {
value: value.clone(),
},
OverrideDimension { name, value },
)
}

/// Track how far you got without a final result
pub fn breadcrumb(&mut self, dimension: impl Into<Dimension>) {
*self.value.lock().expect("local mutex") = dimension.into()
}

/// Set the final result of the dimension
pub fn set(self, dimension: impl Into<Dimension>) {
match self.override_sender.send(dimension.into()) {
Ok(_) => (),
Err(e) => log::debug!("dimension arrived too late: {e:?}"),
}
*self.value.lock().expect("local mutex") = dimension.into()
}
}

#[derive(Debug)]
pub struct OverrideDimension {
name: Name,
default: Dimension,
override_receiver: oneshot::Receiver<Dimension>,
value: Arc<Mutex<Dimension>>,
}

impl OverrideDimension {
/// Consume the dimension. If it hasn't been set by now, you get the default value.
pub fn redeem(mut self) -> (Name, Dimension) {
(
self.name,
match self.override_receiver.try_recv() {
Ok(option) => match option {
Some(overriden) => overriden,
None => self.default,
},
Err(_) => self.default,
},
)
pub fn redeem(self) -> (Name, Dimension) {
let dimension = std::mem::replace(
&mut *self.value.lock().expect("local mutex"),
"__none__".into(),
);
(self.name, dimension)
}
}

Expand Down

0 comments on commit 542656b

Please sign in to comment.