Skip to main content

oxidite_queue/
stats.rs

1use std::sync::Arc;
2use tokio::sync::RwLock;
3use serde::{Deserialize, Serialize};
4
5/// Job queue statistics
6#[derive(Debug, Clone, Serialize, Deserialize, Default)]
7pub struct QueueStats {
8    /// Total number of jobs enqueued
9    pub total_enqueued: u64,
10    /// Total number of jobs processed
11    pub total_processed: u64,
12    /// Total number of jobs failed
13    pub total_failed: u64,
14    /// Total number of jobs retried
15    pub total_retried: u64,
16    /// Current number of pending jobs
17    pub pending_count: u64,
18    /// Current number of running jobs
19    pub running_count: u64,
20    /// Current number of dead letter jobs
21    pub dead_letter_count: u64,
22}
23
24/// Thread-safe statistics tracker
25#[derive(Clone)]
26pub struct StatsTracker {
27    stats: Arc<RwLock<QueueStats>>,
28}
29
30impl StatsTracker {
31    /// Create a new stats tracker
32    pub fn new() -> Self {
33        Self {
34            stats: Arc::new(RwLock::new(QueueStats::default())),
35        }
36    }
37
38    /// Increment the enqueued counter
39    pub async fn increment_enqueued(&self) {
40        let mut stats = self.stats.write().await;
41        stats.total_enqueued += 1;
42        stats.pending_count += 1;
43    }
44
45    /// Increment the processed counter
46    pub async fn increment_processed(&self) {
47        let mut stats = self.stats.write().await;
48        stats.total_processed += 1;
49        if stats.running_count > 0 {
50            stats.running_count -= 1;
51        }
52    }
53
54    /// Increment the failed counter
55    pub async fn increment_failed(&self) {
56        let mut stats = self.stats.write().await;
57        stats.total_failed += 1;
58        if stats.running_count > 0 {
59            stats.running_count -= 1;
60        }
61    }
62
63    /// Increment the retried counter
64    pub async fn increment_retried(&self) {
65        let mut stats = self.stats.write().await;
66        stats.total_retried += 1;
67    }
68
69    /// Increment the dead letter counter
70    pub async fn increment_dead_letter(&self) {
71        let mut stats = self.stats.write().await;
72        stats.dead_letter_count += 1;
73    }
74
75    /// Mark a job as running
76    pub async fn mark_running(&self) {
77        let mut stats = self.stats.write().await;
78        if stats.pending_count > 0 {
79            stats.pending_count -= 1;
80        }
81        stats.running_count += 1;
82    }
83
84    /// Get a snapshot of the current stats
85    pub async fn get_stats(&self) -> QueueStats {
86        self.stats.read().await.clone()
87    }
88
89    /// Reset all statistics to zero
90    pub async fn reset(&self) {
91        let mut stats = self.stats.write().await;
92        *stats = QueueStats::default();
93    }
94}
95
96impl Default for StatsTracker {
97    fn default() -> Self {
98        Self::new()
99    }
100}