tracing_actions/
span_constructor.rs

1use std::sync::Mutex;
2
3use crate::ActionSpan;
4
5pub trait SpanConstructor {
6    fn new_span(&self) -> ActionSpan;
7    fn return_span(&self, span: ActionSpan);
8}
9
10pub struct AlwaysNewSpanConstructor;
11impl SpanConstructor for AlwaysNewSpanConstructor {
12    fn new_span(&self) -> ActionSpan {
13        ActionSpan::default()
14    }
15
16    fn return_span(&self, _span: ActionSpan) {
17        // Drops the span
18    }
19}
20
21/// Works with shared spans when it wins a race to grab a mutex.
22/// When it doesn't get a shared span, it simply allocates a new one.
23pub struct LazySpanCache {
24    span_cache_size: usize,
25    span_cache: Mutex<Vec<ActionSpan>>,
26}
27impl LazySpanCache {
28    pub fn new(span_cache_size: usize) -> Self {
29        Self {
30            span_cache_size,
31            span_cache: Vec::with_capacity(span_cache_size).into(),
32        }
33    }
34}
35impl Default for LazySpanCache {
36    fn default() -> Self {
37        Self::new(64)
38    }
39}
40impl SpanConstructor for LazySpanCache {
41    fn new_span(&self) -> ActionSpan {
42        match self.span_cache.try_lock() {
43            Ok(mut lazy_win) => lazy_win.pop(),
44            Err(_) => None,
45        }
46        .unwrap_or_default()
47    }
48
49    fn return_span(&self, span: ActionSpan) {
50        if let Ok(mut lazy_win) = self.span_cache.try_lock() {
51            if lazy_win.len() < self.span_cache_size {
52                lazy_win.push(span)
53            }
54        }
55    }
56}