I am trying to create a simple queue for rate limiting by wrapping a tokio::sync::Semaphore
Essentially I need a queue to rate limit access with a certain number of slots and to know the length but I am struggling a bit with the life times required
My code is below
use tokio::sync::{Semaphore,OwnedSemaphorePermit};
use std::sync::{Arc,atomic::{AtomicU32, Ordering}};
pub struct QueuePermit<'a> {
permit:OwnedSemaphorePermit,
queue: & 'a Queue,
}
impl <'a> Drop for QueuePermit<'a> {
fn drop(&mut self) {
self.queue.size.fetch_sub(1, Ordering::Relaxed);
}
}
/// A basic queue implamentation that wraps a Tokio::Semaphore and keeps track of the searches and size
pub struct Queue {
lock: Arc<Semaphore>,
size: AtomicU32,
}
impl Queue {
pub fn new (search_slots:usize) -> Self {
Self{
lock: Arc::new(Semaphore::new(search_slots)),
size: AtomicU32::new(0u32),
}
}
pub async fn enqueue<'a>(&'a self) -> QueuePermit<'a> {
// Increment size and try to acquire a permit
self.size.fetch_add(1, Ordering::Relaxed);
// Acquire a permit from the underlying semaphore
let permit = self.lock.acquire_owned().await;
QueuePermit {
permit:permit,
queue:&self
}
}
}
Now obviously the permit must live as long as the queue but I can quite figure out how to communicate that.
A link to the code in the playground is here Rust Playground Also if there is a better way to go about this any input is greatly appreciated