use std::{sync::Arc, time::Duration};
use thiserror::Error;
use tokio::sync::{AcquireError, OwnedSemaphorePermit, Semaphore};
use tracing::Span;
#[derive(Debug)]
pub struct ProverPermit {
#[allow(dead_code)]
permit: OwnedSemaphorePermit,
span: Span,
time: tokio::time::Instant,
}
impl ProverPermit {
#[must_use]
pub fn release(self) -> Duration {
self.time.elapsed()
}
}
impl Drop for ProverPermit {
fn drop(&mut self) {
let duration = self.time.elapsed();
tracing::debug!(parent: &self.span, "permit acquired for {:?} ", duration);
}
}
#[derive(Debug, Clone)]
pub struct ProverSemaphore {
sem: Arc<Semaphore>,
}
impl ProverSemaphore {
#[must_use]
#[inline]
pub fn new(max_permits: usize) -> Self {
Self { sem: Arc::new(Semaphore::new(max_permits)) }
}
#[inline]
pub async fn acquire(self) -> Result<ProverPermit, ProverAcquireError> {
let span = tracing::Span::current();
let permit = self.sem.acquire_owned().await?;
let time = tokio::time::Instant::now();
Ok(ProverPermit { permit, span, time })
}
#[inline]
pub async fn acquire_many(self, n: u32) -> Result<ProverPermit, ProverAcquireError> {
let span = tracing::Span::current();
let permit = self.sem.acquire_many_owned(n).await?;
let time = tokio::time::Instant::now();
Ok(ProverPermit { permit, span, time })
}
}
#[derive(Debug, Error)]
#[error("failed to acquire permit")]
pub struct ProverAcquireError(#[from] AcquireError);