#[cfg(feature = "runtime")]
pub(crate) struct Timer {
#[cfg(any(feature = "metrics", feature = "tracing"))]
start: std::time::Instant,
}
#[cfg(feature = "runtime")]
impl Timer {
#[inline]
pub(crate) fn start() -> Self {
Self {
#[cfg(any(feature = "metrics", feature = "tracing"))]
start: std::time::Instant::now(),
}
}
#[cfg(any(feature = "metrics", feature = "tracing"))]
#[inline]
fn secs(&self) -> f64 {
self.start.elapsed().as_secs_f64()
}
}
#[cfg(feature = "runtime")]
#[inline]
pub(crate) fn acquired(limiter: &'static str) {
#[cfg(feature = "metrics")]
::metrics::counter!("throttle_acquired_total", "limiter" => limiter).increment(1);
#[cfg(not(feature = "metrics"))]
let _ = limiter;
}
#[cfg(feature = "runtime")]
#[inline]
pub(crate) fn wait(limiter: &'static str, timer: &Timer) {
#[cfg(feature = "metrics")]
::metrics::histogram!("throttle_wait_duration", "limiter" => limiter).record(timer.secs());
#[cfg(not(feature = "metrics"))]
let _ = (limiter, timer);
}
#[cfg(feature = "runtime")]
#[inline]
pub(crate) fn trace_acquire(limiter: &'static str, cost: u32, granted: bool, timer: &Timer) {
#[cfg(feature = "tracing")]
::tracing::debug!(
target: "throttle_net",
limiter,
cost,
granted,
wait_secs = timer.secs(),
"acquire",
);
#[cfg(not(feature = "tracing"))]
let _ = (limiter, cost, granted, timer);
}
#[cfg(feature = "runtime")]
#[inline]
pub(crate) fn queue_depth(depth: usize) {
#[cfg(feature = "metrics")]
#[allow(clippy::cast_precision_loss)]
::metrics::gauge!("throttle_queue_depth").set(depth as f64);
#[cfg(not(feature = "metrics"))]
let _ = depth;
}
#[cfg(feature = "runtime")]
#[inline]
pub(crate) fn queue_overflow(policy: &'static str) {
#[cfg(feature = "tracing")]
::tracing::warn!(target: "throttle_net", policy, "queue overflow");
#[cfg(not(feature = "tracing"))]
let _ = policy;
}
#[cfg(feature = "runtime")]
#[inline]
pub(crate) fn deadline_exceeded() {
#[cfg(feature = "tracing")]
::tracing::warn!(target: "throttle_net", "queue waiter deadline exceeded");
}
#[cfg(feature = "circuit-breaker")]
#[inline]
pub(crate) fn circuit_transition(from: &'static str, to: &'static str, state: u8) {
#[cfg(feature = "metrics")]
::metrics::gauge!("throttle_circuit_state").set(f64::from(state));
#[cfg(feature = "tracing")]
::tracing::info!(target: "throttle_net", from, to, "circuit breaker transition");
#[cfg(not(any(feature = "metrics", feature = "tracing")))]
let _ = (from, to, state);
#[cfg(all(feature = "metrics", not(feature = "tracing")))]
let _ = (from, to);
#[cfg(all(feature = "tracing", not(feature = "metrics")))]
let _ = state;
}
#[cfg(feature = "adaptive")]
#[inline]
pub(crate) fn rate_change(old: u32, new: u32) {
#[cfg(feature = "metrics")]
::metrics::gauge!("throttle_rate_current").set(f64::from(new));
#[cfg(feature = "tracing")]
::tracing::debug!(target: "throttle_net", old, new, "adaptive limit changed");
#[cfg(not(any(feature = "metrics", feature = "tracing")))]
let _ = (old, new);
#[cfg(all(feature = "metrics", not(feature = "tracing")))]
let _ = old;
}
#[cfg(all(
test,
feature = "runtime",
not(any(feature = "metrics", feature = "tracing"))
))]
mod tests {
use super::Timer;
#[test]
fn test_timer_is_zero_sized_when_observability_is_off() {
assert_eq!(core::mem::size_of::<Timer>(), 0);
}
}