Skip to content

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.

13 exports Added in v3.19.4 Source

Combinators

available

Added in v4.0.0 Source

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

Signature

declare function available<K>(self: PartitionedSemaphore<K>): Effect<number>;

release

Added in v4.0.0 Source

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>;
};

take

Added in v4.0.0 Source

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

Added in v4.0.0 Source

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

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

Added in v4.0.0 Source

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

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>;
};

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

make

Added in v3.19.4 Source

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

Signature

declare function make<K = unknown>(options: {
  readonly permits: number;
}): Effect<PartitionedSemaphore<K>>;

makeUnsafe

Added in v3.19.4 Source

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

capacity

Added in v4.0.0 Source

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>): number;

Models

Partitioned interface

Added in v4.0.0 Source

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

Added in v3.19.4 Source

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

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

Added in v4.0.0 Source

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";