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
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
- capacity for the fixed total permit capacity
- release for returning permits to the shared pool
- withPermitsIfAvailable for running only when permits are immediately available
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
- take for manual acquisition
- withPermits for automatic acquire and release around an effect
- available for 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
- release for manually returning permits to the shared pool
- withPermits for automatic acquire and release around an effect
- withPermit for 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
- withPermits for acquiring a weighted number of permits
- withPermitsIfAvailable for running only when permits are immediately available
- take for manual acquisition
- release for 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
- withPermit for the single-permit variant
- withPermitsIfAvailable for running only when permits are immediately available
- take for manual acquisition
- release for 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
- withPermits for 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
- makeUnsafe for 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
- make for creating a partitioned semaphore inside
Effect
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
- available for the current number of free permits
Signature
declare function capacity<K>(self: PartitionedSemaphore<K>): numberModels
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: PartitionedTypeIdPartitionedTypeId 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"