1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
use std::sync::Arc;
use tokio::sync::OwnedSemaphorePermit as OwnedSemaphoreBasePermit;
use tokio::sync::Semaphore as SemaphoreBase;
use tokio::sync::SemaphorePermit as SemaphoreBasePermit;
/// Represents a permit to a [Semaphore].
pub struct SemaphorePermit<'a> {
_permit: SemaphoreBasePermit<'a>,
}
/// Represents an owned permit to a [Semaphore].
pub struct OwnedSemaphorePermit {
_permit: OwnedSemaphoreBasePermit,
}
/// Error when there are no permits available.
#[derive(Debug)]
pub struct NoPermits;
/// A semaphore maintains a set of permits. Permits are used to synchronize access to a shared resource.
/// A semaphore differs from a mutex in that it can allow more than one concurrent caller to access the shared resource at a time.
#[repr(transparent)]
pub struct Semaphore {
inner: SemaphoreBase,
}
/// An owned semaphore is identical to a [Semaphore] except it can be owned by an actor and it's permits can still be shared externally.
#[repr(transparent)]
pub struct OwnedSemaphore {
inner: Arc<SemaphoreBase>,
}
impl Semaphore {
/// Creates a new instance of [Semaphore] with the given `permits` count.
///
/// This is typically used to create a static semaphore:
/// ```
/// use hydra::Semaphore;
///
/// static RATE_LIMIT: Semaphore = Semaphore::new(100);
/// ```
pub const fn new(permits: usize) -> Self {
Self {
inner: SemaphoreBase::const_new(permits),
}
}
/// Acquires one permit asynchronously waiting for one to become available.
#[must_use]
pub async fn acquire(&self) -> SemaphorePermit {
let permit = self.inner.acquire().await.unwrap();
SemaphorePermit { _permit: permit }
}
/// Acquires many permits asynchronously waiting for them to become available.
#[must_use]
pub async fn acquire_many(&self, count: u32) -> SemaphorePermit {
let permit = self.inner.acquire_many(count).await.unwrap();
SemaphorePermit { _permit: permit }
}
/// Attempts to acquire a permit, returning an error if there are none available.
pub fn try_acquire(&self) -> Result<SemaphorePermit, NoPermits> {
let permit = self.inner.try_acquire().map_err(|_| NoPermits)?;
Ok(SemaphorePermit { _permit: permit })
}
}
impl OwnedSemaphore {
/// Creates a new instance of [OwnedSemaphore] with the given `permits` count that can be used with owned permits.
///
/// This can be used to create a owned semaphore that lives in a state:
/// ```
/// use hydra::OwnedSemaphore;
///
/// struct MyServer {
/// rate_limit: OwnedSemaphore,
/// }
///
/// impl MyServer {
/// pub fn new() -> Self {
/// Self {
/// rate_limit: OwnedSemaphore::new(100),
/// }
/// }
/// }
/// ```
pub fn new(permits: usize) -> Self {
Self {
inner: Arc::new(SemaphoreBase::new(permits)),
}
}
/// Acquires one permit asynchronously waiting for one to become available.
#[must_use]
pub async fn acquire(&self) -> SemaphorePermit {
let permit = self.inner.acquire().await.unwrap();
SemaphorePermit { _permit: permit }
}
/// Acquires one permit asynchronously waiting for one to become available.
#[must_use]
pub async fn acquire_owned(&self) -> OwnedSemaphorePermit {
let permit = self.inner.clone().acquire_owned().await.unwrap();
OwnedSemaphorePermit { _permit: permit }
}
/// Acquires many permits asynchronously waiting for them to become available.
#[must_use]
pub async fn acquire_many(&self, count: u32) -> SemaphorePermit {
let permit = self.inner.acquire_many(count).await.unwrap();
SemaphorePermit { _permit: permit }
}
/// Acquires many permits asynchronously waiting for them to become available.
#[must_use]
pub async fn acquire_many_owned(&self, count: u32) -> OwnedSemaphorePermit {
let permit = self.inner.clone().acquire_many_owned(count).await.unwrap();
OwnedSemaphorePermit { _permit: permit }
}
/// Attempts to acquire a permit, returning an error if there are none available.
pub fn try_acquire(&self) -> Result<SemaphorePermit, NoPermits> {
let permit = self.inner.try_acquire().map_err(|_| NoPermits)?;
Ok(SemaphorePermit { _permit: permit })
}
/// Attempts to acquire a permit, returning an error if there are none available.
pub fn try_acquire_owned(&self) -> Result<OwnedSemaphorePermit, NoPermits> {
let permit = self
.inner
.clone()
.try_acquire_owned()
.map_err(|_| NoPermits)?;
Ok(OwnedSemaphorePermit { _permit: permit })
}
}