Skip to main content

xml_disassembler/utils/
async_queue.rs

1//! Async task queue with concurrency control.
2
3use std::future::Future;
4use std::sync::Arc;
5use tokio::sync::Semaphore;
6
7pub struct AsyncTaskQueue {
8    semaphore: Arc<Semaphore>,
9}
10
11impl AsyncTaskQueue {
12    pub fn new(concurrency: usize) -> Self {
13        Self {
14            semaphore: Arc::new(Semaphore::new(concurrency)),
15        }
16    }
17
18    pub async fn add<T, F>(&self, task: F) -> T
19    where
20        F: Future<Output = T> + Send,
21        T: Send,
22    {
23        let _permit = self.semaphore.acquire().await.unwrap();
24        task.await
25    }
26}
27
28#[cfg(test)]
29mod tests {
30    use super::*;
31
32    #[tokio::test]
33    async fn new_and_add_returns_task_result() {
34        let queue = AsyncTaskQueue::new(2);
35        let r: i32 = queue.add(async { 42 }).await;
36        assert_eq!(r, 42);
37    }
38
39    #[tokio::test]
40    async fn add_respects_concurrency() {
41        let queue = AsyncTaskQueue::new(1);
42        let a = queue.add(async { 1 });
43        let b = queue.add(async { 2 });
44        let (x, y) = tokio::join!(a, b);
45        assert_eq!((x, y), (1, 2));
46    }
47}