prometheus_utils/
guards.rs1use crate::{IntCounterWithLabels, Labels};
2use prometheus::core::{Atomic, AtomicF64, AtomicI64, GenericCounter, GenericGauge, Number};
3
4pub type IntGaugeGuard = GenericGaugeGuard<AtomicI64>;
8
9pub type GaugeGuard = GenericGaugeGuard<AtomicF64>;
13
14pub struct GenericGaugeGuard<P: Atomic + 'static> {
19 value: P::T,
20 gauge: &'static GenericGauge<P>,
21}
22
23impl<P: Atomic + 'static> Drop for GenericGaugeGuard<P> {
25 fn drop(&mut self) {
26 self.gauge.sub(self.value);
27 }
28}
29
30pub trait GuardedGauge<P: Atomic + 'static> {
32 #[must_use]
34 fn guarded_inc(&'static self) -> GenericGaugeGuard<P>;
35
36 #[must_use]
38 fn guarded_add(&'static self, v: P::T) -> GenericGaugeGuard<P>;
39}
40
41impl<P: Atomic + 'static> GuardedGauge<P> for GenericGauge<P> {
42 fn guarded_inc(&'static self) -> GenericGaugeGuard<P> {
43 self.inc();
44 GenericGaugeGuard {
45 value: <P::T as Number>::from_i64(1),
46 gauge: self,
47 }
48 }
49
50 fn guarded_add(&'static self, v: P::T) -> GenericGaugeGuard<P> {
51 self.add(v);
52 GenericGaugeGuard {
53 value: v,
54 gauge: self,
55 }
56 }
57}
58
59pub struct DeferredAddWithLabels<'a, L: Labels> {
63 value: Option<u64>,
64 metric: &'a IntCounterWithLabels<L>,
65 labels: L,
66}
67
68impl<'a, L: Labels> Drop for DeferredAddWithLabels<'a, L> {
70 fn drop(&mut self) {
71 if let Some(value) = self.value {
72 self.metric.add(value, &self.labels)
73 }
74 }
75}
76
77impl<'a, L: Labels> DeferredAddWithLabels<'a, L> {
78 pub(crate) fn new(metric: &'a IntCounterWithLabels<L>, value: u64, labels: L) -> Self {
83 Self {
84 value: Some(value),
85 metric,
86 labels,
87 }
88 }
89
90 pub fn with_labels(mut self, new_labels: L) -> DeferredAddWithLabels<'a, L> {
92 self.labels = new_labels;
93 self
94 }
95
96 pub fn labels(&self) -> &L {
98 &self.labels
99 }
100
101 pub fn labels_mut(&mut self) -> &mut L {
103 &mut self.labels
104 }
105
106 pub fn complete_add(self) {
108 drop(self)
109 }
110
111 pub fn cancel(&mut self) {
113 self.value = None;
114 }
115}
116
117pub struct DeferredAdd<'a, P: Atomic> {
121 value: Option<P::T>,
122 metric: &'a GenericCounter<P>,
123}
124
125impl<'a, P: Atomic> DeferredAdd<'a, P> {
126 pub fn complete_add(self) {
128 drop(self)
129 }
130
131 pub fn cancel(&mut self) {
133 self.value = None;
134 }
135}
136
137impl<'a, P: Atomic> Drop for DeferredAdd<'a, P> {
139 fn drop(&mut self) {
140 if let Some(value) = self.value {
141 self.metric.inc_by(value);
142 }
143 }
144}
145
146pub trait DeferredCounter<P: Atomic + 'static> {
149 #[must_use]
151 fn deferred_inc(&'static self) -> DeferredAdd<P> {
152 self.deferred_add(<P::T as Number>::from_i64(1))
153 }
154
155 #[must_use]
157 fn deferred_add(&'static self, v: P::T) -> DeferredAdd<P>;
158}
159
160impl<P: Atomic + 'static> DeferredCounter<P> for GenericCounter<P> {
161 fn deferred_add(&'static self, v: P::T) -> DeferredAdd<P> {
162 DeferredAdd {
163 value: Some(v),
164 metric: self,
165 }
166 }
167}