PartitionedSemaphore
The PartitionedSemaphore module provides a semaphore for limiting concurrency across a shared permit pool while keeping waiters grouped by partition key. A PartitionedSemaphore<K> is useful when many independent groups of work compete for the same bounded resource and each group should make progress without one busy group monopolizing released permits.
Combinators
Signature
declare function available<K>(self: PartitionedSemaphore<K>): Effect<number>;Returns an effect that releases permits back to the shared pool and returns the current available permit count.
When to use
Use when you need to return permits acquired with take in a lower-level partitioned permit protocol with explicit release control.
Details
Released permits are first assigned to waiting partitions in round-robin order. Only permits not needed by waiters increase the available count, which is capped at the semaphore capacity.
See
takefor manual acquisitionwithPermitsfor automatic acquire and release around an effectavailablefor reading the permit count without releasing
Signature
declare const release: {
(permits: number): <K>(self: PartitionedSemaphore<K>) => Effect<number>;
<K>(self: PartitionedSemaphore<K>, permits: number): Effect<number>;
};Returns an effect that acquires the requested number of permits for the given partition key.
When to use
Use when you need manual permit acquisition for a partition and want to control acquisition and release as separate effects.
Details
If enough permits are available, the effect completes immediately. Otherwise it waits until released permits are assigned to this partition.
Gotchas
Requests for more permits than the semaphore capacity never complete. Requests for zero or a negative number of permits complete without acquiring anything.
See
releasefor manually returning permits to the shared poolwithPermitsfor automatic acquire and release around an effectwithPermitfor acquiring exactly one permit around an effect
Signature
declare const take: {
<K>(key: K, permits: number): (self: PartitionedSemaphore<K>) => Effect<void>;
<K>(self: PartitionedSemaphore<K>, key: K, permits: number): Effect<void>;
};withPermit
Runs an effect after acquiring one permit for a partition, then releases the permit when the effect exits.
When to use
Use to guard partitioned work with exactly one permit and automatic release when the effect exits.
Details
This is the single-permit variant of withPermits. The permit is released even if the wrapped effect fails or is interrupted.
See
withPermitsfor acquiring a weighted number of permitswithPermitsIfAvailablefor running only when permits are immediately availabletakefor manual acquisitionreleasefor manual release
Signature
declare const withPermit: {
<K>(self: PartitionedSemaphore<K>, key: K): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
<K, A, E, R>(self: PartitionedSemaphore<K>, key: K, effect: Effect<A, E, R>): Effect<A, E, R>;
};withPermits
Runs an effect after acquiring permits for a partition, then releases those permits when the effect exits.
When to use
Use to guard weighted partitioned work with automatic permit acquisition and release around an effect.
Details
Permit acquisition may wait according to take semantics. Once acquired, the permits are released even if the wrapped effect fails or is interrupted.
Gotchas
Requests for more permits than the semaphore capacity never complete. Requests for zero or a negative number of permits run the effect without acquiring anything.
See
withPermitfor the single-permit variantwithPermitsIfAvailablefor running only when permits are immediately availabletakefor manual acquisitionreleasefor manual release
Signature
declare const withPermits: {
<K>(
self: PartitionedSemaphore<K>,
key: K,
permits: number,
): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
<K, A, E, R>(
self: PartitionedSemaphore<K>,
key: K,
permits: number,
effect: Effect<A, E, R>,
): Effect<A, E, R>;
};withPermitsIfAvailable
Runs an effect only when the requested permits can be acquired immediately, returning the result in Some.
When to use
Use when guarded work should run only if the shared permit pool can provide the requested permits immediately.
Details
If the permits are not available, the effect is not run and the result is None. When permits are acquired, they are released after the wrapped effect completes, fails, or is interrupted. Requests for zero or a negative number of permits run the effect and return Some.
See
withPermitsfor the keyed variant that waits until permits are available for a partition
Signature
declare const withPermitsIfAvailable: {
<K>(
self: PartitionedSemaphore<K>,
permits: number,
): <A, E, R>(effect: Effect<A, E, R>) => Effect<Option<A>, E, R>;
<K, A, E, R>(
self: PartitionedSemaphore<K>,
permits: number,
effect: Effect<A, E, R>,
): Effect<Option<A>, E, R>;
};Constructors
Creates a PartitionedSemaphore inside an Effect.
When to use
Use when semaphore construction should stay inside an Effect workflow.
Details
The permits option sets the shared permit capacity. The resulting semaphore tracks waiters by partition key and distributes released permits across waiting partitions in round-robin order.
Gotchas
Negative permit counts are clamped to 0. Non-finite permit counts create an unbounded semaphore.
See
makeUnsafefor synchronous construction
Signature
declare function make<K = unknown>(options: {
readonly permits: number;
}): Effect<PartitionedSemaphore<K>>;makeUnsafe
Constructs a PartitionedSemaphore synchronously, outside of Effect.
When to use
Use when you need to construct a partitioned semaphore synchronously outside an Effect workflow.
Details
Negative permit counts are clamped to 0. Non-finite permit counts create an unbounded semaphore whose acquire and release operations complete immediately.
See
makefor creating a partitioned semaphore insideEffect
Signature
declare function makeUnsafe<K = unknown>(options: {
readonly permits: number;
}): PartitionedSemaphore<K>;Getters
Gets the total capacity.
When to use
Use to inspect the fixed number of permits configured for the semaphore.
Details
Capacity is stored when the semaphore is created and does not change as permits are acquired or released.
See
availablefor the current number of free permits
Signature
declare function capacity<K>(self: PartitionedSemaphore<K>): number;Models
Partitioned interface
Alias interface for a PartitionedSemaphore keyed by values of type K.
When to use
Use as an alternate exported name for a partitioned permit pool keyed by K.
Details
This interface does not add members beyond PartitionedSemaphore; it provides an alternate exported name for APIs that refer to a partitioned permit pool.
Signature
interface Partitioned<in K> extends PartitionedSemaphore<K> {}PartitionedSemaphore interface
A PartitionedSemaphore controls access to a shared permit pool while tracking waiters by partition key.
When to use
Use to coordinate shared permits across partition keys so waiting groups make progress without one group monopolizing the pool.
Details
Waiting permits are distributed across partitions in round-robin order.
Signature
interface PartitionedSemaphore<in K> {
readonly "~effect/PartitionedSemaphore": "~effect/PartitionedSemaphore";
readonly available: Effect<number>;
readonly capacity: number;
readonly release: (permits: number) => Effect<number>;
readonly take: (key: K, permits: number) => Effect<void>;
readonly withPermit: (key: K) => <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
readonly withPermits: (
key: K,
permits: number,
) => <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
readonly withPermitsIfAvailable: (
permits: number,
) => <A, E, R>(effect: Effect<A, E, R>) => Effect<Option<A>, E, R>;
}Type IDs
PartitionedTypeId
Runtime type identifier used to mark values that implement PartitionedSemaphore.
Details
This marker is part of the runtime representation of partitioned semaphore values.
Signature
declare const PartitionedTypeId: PartitionedTypeId;PartitionedTypeId type
Literal type of the PartitionedSemaphore runtime type identifier.
When to use
Use to type fields that store the exact PartitionedSemaphore runtime marker.
Details
Use this type when declaring fields that must contain the exact PartitionedTypeId marker value.
Signature
type PartitionedTypeId = "~effect/PartitionedSemaphore";
Gets the current number of available permits.
When to use
Use to inspect a snapshot of how many permits are currently free.
Details
Running the returned effect reads the semaphore's current availability. Taking permits decreases availability, and releasing permits can increase it up to the semaphore capacity.
Gotchas
Reading availability does not reserve permits.
See
capacityfor the fixed total permit capacityreleasefor returning permits to the shared poolwithPermitsIfAvailablefor running only when permits are immediately available