use crate::diagnostics::{Error, Result};
use super::ConcurrencyError;
use std::sync::Arc;
use tokio::sync::{Semaphore};
#[derive(Debug, Clone)]
pub struct SemaphoreSync {
inner: Arc<Semaphore>,
name: Option<String>,
}
impl SemaphoreSync {
pub fn new(permits: usize) -> Self {
Self {
inner: Arc::new(Semaphore::new(permits)),
name: None,
}
}
pub fn with_name(permits: usize, name: String) -> Self {
Self {
inner: Arc::new(Semaphore::new(permits)),
name: Some(name),
}
}
pub async fn acquire(&self) -> Result<SemaphorePermit<'_>> {
let permit = self.inner.acquire().await
.map_err(|_| ConcurrencyError::ChannelClosed)?;
Ok(SemaphorePermit { permit })
}
pub fn try_acquire(&self) -> Result<SemaphorePermit<'_>> {
let permit = self.inner.try_acquire()
.map_err(|_| Error::runtime_error("No permits available".to_string(), None))?;
Ok(SemaphorePermit { permit })
}
pub async fn acquire_many(&self, permits: u32) -> Result<SemaphorePermit<'_>> {
let permit = self.inner.acquire_many(permits).await
.map_err(|_| ConcurrencyError::ChannelClosed)?;
Ok(SemaphorePermit { permit })
}
pub fn available_permits(&self) -> usize {
self.inner.available_permits()
}
pub fn add_permits(&self, n: usize) {
self.inner.add_permits(n);
}
pub fn name(&self) -> Option<&str> {
self.name.as_deref()
}
}
pub struct SemaphorePermit<'a> {
permit: tokio::sync::SemaphorePermit<'a>,
}
impl<'a> Drop for SemaphorePermit<'a> {
fn drop(&mut self) {
}
}