Semaphore
Limits how many effects can use a shared resource at the same time.
A Semaphore owns a number of permits. Work can run only after acquiring the permits it needs, and those permits are returned when the work finishes. This module includes constructors, automatic wrappers that acquire and release permits around an effect, manual permit operations, a non-waiting variant for work that should only run immediately, and resizing support for an existing semaphore.
Combinators
Signature
declare const release: {
(permits: number): (self: Semaphore) => Effect<number>;
(self: Semaphore, permits: number): Effect<number>;
};releaseAll
Releases all permits held by this semaphore and returns the resulting available permits.
When to use
Use to return every currently taken permit to a semaphore at once, typically during cleanup of manual take / release protocols.
See
releasefor releasing a known permit countwithPermitsfor automatic acquire and release around an effect
Signature
declare function releaseAll(self: Semaphore): Effect<number>;Sets the total number of permits managed by the semaphore.
When to use
Use to change the concurrency limit of an existing semaphore while keeping current acquisitions in place.
Details
Existing acquisitions remain taken after resizing. If the new total is less than the currently taken permit count, new acquisitions wait until enough permits are released.
See
Signature
declare const resize: {
(permits: number): (self: Semaphore) => Effect<void>;
(self: Semaphore, permits: number): Effect<void>;
};Acquires the specified number of permits and returns the acquired permit count.
When to use
Use when you need manual permit acquisition for a lower-level protocol with explicit acquisition and release control.
Details
The effect waits until enough permits are available.
See
withPermitfor automatically acquiring and releasing one permit around an effectwithPermitsfor automatically acquiring and releasing multiple permits around an effecttakeIfAvailablefor manually acquiring permits without waitingreleasefor returning manually acquired permits
Signature
declare const take: {
(permits: number): (self: Semaphore) => Effect<number>;
(self: Semaphore, permits: number): Effect<number>;
};takeIfAvailable
Acquires the specified number of permits only if they are immediately available.
When to use
Use when you need fail-fast manual permit acquisition for a lower-level protocol with explicit acquisition and release control.
Details
If enough permits are available, they are acquired and the effect returns true. Otherwise, the effect returns false immediately without acquiring any permits.
See
takefor the variant that waits until permits are availablereleasefor returning manually acquired permitswithPermitsIfAvailablefor automatic acquisition and release around an effect
Signature
declare const takeIfAvailable: {
(permits: number): (self: Semaphore) => Effect<boolean>;
(self: Semaphore, permits: number): Effect<boolean>;
};withPermit
Runs an effect with a single permit and releases the permit when the effect completes.
When to use
Use to guard an effect with exactly one semaphore permit while automatically releasing that permit when the effect exits.
See
withPermitsfor acquiring more than one permitwithPermitsIfAvailablefor running only when permits are immediately availabletakefor manually acquiring permitsreleasefor manually returning permits
Signature
declare const withPermit: {
(self: Semaphore): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
<A, E, R>(self: Semaphore, effect: Effect<A, E, R>): Effect<A, E, R>;
};withPermits
Runs an effect with the given number of permits and releases the permits when the effect completes.
When to use
Use to run an effect while holding a specified number of semaphore permits for the duration of that effect.
Details
The effect waits until enough permits are available. Acquired permits are released when the wrapped effect exits.
See
withPermitfor acquiring exactly one permitwithPermitsIfAvailablefor running only when permits are immediately availabletakefor manually acquiring permitsreleasefor manually returning permits
Signature
declare const withPermits: {
(self: Semaphore, permits: number): <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
<A, E, R>(self: Semaphore, permits: number, effect: Effect<A, E, R>): Effect<A, E, R>;
};withPermitsIfAvailable
Runs an effect only if the specified number of permits are immediately available.
When to use
Use when guarded work should run only if the requested permits are immediately available.
Details
When the permits are unavailable, the effect is not run and the result is Option.none. When permits are available, the effect is run, its result is wrapped in Option.some, and the acquired permits are released when the effect exits.
See
withPermitsfor the variant that waits until permits are available
Signature
declare const withPermitsIfAvailable: {
(self: Semaphore, permits: number): <A, E, R>(effect: Effect<A, E, R>) => Effect<Option<A>, E, R>;
<A, E, R>(self: Semaphore, permits: number, effect: Effect<A, E, R>): Effect<Option<A>, E, R>;
};Constructors
Creates a Semaphore initialized with the specified total number of permits.
When to use
Use to create a semaphore inside Effect code for bounding concurrency with automatic or manual permit management.
Signature
declare function make(permits: number): Effect<Semaphore>;makeUnsafe
Creates a Semaphore synchronously with the specified total number of permits.
When to use
Use to construct a semaphore synchronously when an immediate value is required outside an Effect workflow.
Signature
declare function makeUnsafe(permits: number): Semaphore;Models
A counting semaphore that coordinates concurrent access with permits.
When to use
Use to coordinate concurrent effects that need bounded access to a shared resource.
Details
Effects can acquire permits, wait until enough permits are available, release permits, or run with permits that are automatically released when the effect exits.
See
makefor creating a semaphore inside Effect codemakeUnsafefor creating a semaphore synchronously
Signature
interface Semaphore {
readonly releaseAll: Effect<number>;
release(this: Semaphore, permits: number): Effect<number>;
resize(this: Semaphore, permits: number): Effect<void>;
take(this: Semaphore, permits: number): Effect<number>;
takeIfAvailable(this: Semaphore, permits: number): Effect<boolean>;
withPermit<A, E, R>(self: Effect<A, E, R>): Effect<A, E, R>;
withPermits(
this: Semaphore,
permits: number,
): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>;
withPermitsIfAvailable(
this: Semaphore,
permits: number,
): <A, E, R>(self: Effect<A, E, R>) => Effect<Option<A>, E, R>;
}
Releases the specified number of permits and returns the resulting available permits.
When to use
Use when you need to return permits acquired with
takein a lower-level permit protocol with explicit release control.Details
Running the effect releases the requested permits, wakes waiting acquirers when permits become available, and returns the current available permit count.
Gotchas
Manual
take/releaseusage must keep permit counts balanced. PreferwithPermitorwithPermitswhen the acquisition can be scoped to one effect.See
takefor manually acquiring permitsreleaseAllfor returning every currently taken permitwithPermitsfor automatic acquire and release around an effect