Skip to main content

kojin_core/
queue_weight.rs

1use serde::{Deserialize, Serialize};
2
3/// Queue priority weight for weighted queue selection.
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
5pub enum QueueWeight {
6    High,
7    Medium,
8    Low,
9}
10
11impl QueueWeight {
12    /// Numeric weight for weighted selection.
13    pub fn weight(&self) -> u32 {
14        match self {
15            QueueWeight::High => 6,
16            QueueWeight::Medium => 3,
17            QueueWeight::Low => 1,
18        }
19    }
20}
21
22/// A queue with an associated weight.
23#[derive(Debug, Clone)]
24pub struct WeightedQueue {
25    pub name: String,
26    pub weight: QueueWeight,
27}
28
29impl WeightedQueue {
30    pub fn new(name: impl Into<String>, weight: QueueWeight) -> Self {
31        Self {
32            name: name.into(),
33            weight,
34        }
35    }
36}
37
38/// Build a weighted queue ordering: higher-weight queues appear more often.
39/// Returns queue names in the order they should be polled.
40pub fn build_weighted_order(queues: &[WeightedQueue]) -> Vec<String> {
41    let mut order = Vec::new();
42    for wq in queues {
43        for _ in 0..wq.weight.weight() {
44            order.push(wq.name.clone());
45        }
46    }
47    order
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    #[test]
55    fn weighted_order() {
56        let queues = vec![
57            WeightedQueue::new("high", QueueWeight::High),
58            WeightedQueue::new("low", QueueWeight::Low),
59        ];
60        let order = build_weighted_order(&queues);
61        let high_count = order.iter().filter(|q| *q == "high").count();
62        let low_count = order.iter().filter(|q| *q == "low").count();
63        assert_eq!(high_count, 6);
64        assert_eq!(low_count, 1);
65    }
66}