use core::str;
use std::collections::HashMap;
use std::sync::Arc;
use std::sync::atomic::AtomicU64;
use parking_lot::RwLock;
use crate::instrumentation::metrics::QUEUE_PENDING_MESSAGES;
use near_o11y::metrics::prometheus;
pub struct InstrumentedQueue {
pending: RwLock<HashMap<String, AtomicU64>>,
pending_messages_gauge: prometheus::core::GenericGauge<prometheus::core::AtomicI64>,
}
impl InstrumentedQueue {
pub fn new(queue_name: &str) -> Arc<Self> {
let queue = Arc::new(Self {
pending: RwLock::new(HashMap::new()),
pending_messages_gauge: QUEUE_PENDING_MESSAGES.with_label_values(&[queue_name]),
});
queue
}
pub fn enqueue(&self, message_type: &str) {
{
let pending = self.pending.read();
if let Some(counter) = pending.get(message_type) {
counter.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
self.pending_messages_gauge.inc();
return;
}
}
let mut pending = self.pending.write();
let counter = pending.entry(message_type.to_string()).or_insert_with(|| AtomicU64::new(0));
counter.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
self.pending_messages_gauge.inc();
}
pub fn dequeue(&self, message_type: &str) {
let pending = self.pending.read();
if let Some(counter) = pending.get(message_type) {
counter.fetch_sub(1, std::sync::atomic::Ordering::Relaxed);
self.pending_messages_gauge.dec();
}
}
pub fn get_pending_events(&self) -> HashMap<String, u64> {
let pending = self.pending.read();
pending
.iter()
.map(|(k, v)| (k.clone(), v.load(std::sync::atomic::Ordering::Relaxed)))
.collect()
}
}