| /** | |
| * 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. | |
| * | |
| * @since 4.0.0 | |
| */ | |
| import type * as Effect from "./Effect.ts" | |
| import type { Fiber } from "./Fiber.ts" | |
| import { dual } from "./Function.ts" | |
| import * as core from "./internal/core.ts" | |
| import * as internal from "./internal/effect.ts" | |
| import type * as Option from "./Option.ts" | |
| /** | |
| * 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. | |
| * | |
| * **Example** (Controlling concurrent access) | |
| * | |
| * ```ts | |
| * import { Effect, Semaphore } from "effect" | |
| * | |
| * // Create and use a semaphore for controlling concurrent access | |
| * const program = Effect.gen(function*() { | |
| * const semaphore = yield* Semaphore.make(2) | |
| * | |
| * return yield* semaphore.withPermits(1)( | |
| * Effect.succeed("Resource accessed") | |
| * ) | |
| * }) | |
| * ``` | |
| * | |
| * @see {@link make} for creating a semaphore inside Effect code | |
| * @see {@link makeUnsafe} for creating a semaphore synchronously | |
| * | |
| * @category models | |
| * @since 4.0.0 | |
| */ | |
| export interface Semaphore { | |
| /** | |
| * Adjusts the number of permits available in the semaphore. | |
| * | |
| * **When to use** | |
| * | |
| * Use to change the total permit count of an existing semaphore. | |
| */ | |
| resize(this: Semaphore, permits: number): Effect.Effect<void> | |
| /** | |
| * 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. | |
| * | |
| * **Details** | |
| * | |
| * This function acquires the specified number of permits before executing | |
| * the provided effect. Once the effect finishes, the permits are released. | |
| * If insufficient permits are available, the function will wait until they | |
| * are released by other tasks. | |
| */ | |
| withPermits(this: Semaphore, permits: number): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R> | |
| /** | |
| * 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 exactly one semaphore permit. | |
| * | |
| * **Details** | |
| * | |
| * This function acquires the specified number of permits before executing | |
| * the provided effect. Once the effect finishes, the permits are released. | |
| * If insufficient permits are available, the function will wait until they | |
| * are released by other tasks. | |
| */ | |
| withPermit<A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> | |
| /** | |
| * 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** | |
| * | |
| * This function attempts to acquire the specified number of permits. If they | |
| * are available, it runs the effect and releases the permits after the effect | |
| * completes. If permits are not available, the effect does not execute, and | |
| * the result is `Option.none`. | |
| */ | |
| withPermitsIfAvailable( | |
| this: Semaphore, | |
| permits: number | |
| ): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<Option.Option<A>, E, R> | |
| /** | |
| * Acquires the specified number of permits and returns the resulting | |
| * available permits, suspending the task if they are not yet available. | |
| * Concurrent pending `take` calls are processed in a first-in, first-out manner. | |
| * | |
| * **When to use** | |
| * | |
| * Use to manually acquire permits for lower-level coordination protocols. | |
| */ | |
| take(this: Semaphore, permits: number): Effect.Effect<number> | |
| /** | |
| * Releases the specified number of permits and returns the resulting | |
| * available permits. | |
| * | |
| * **When to use** | |
| * | |
| * Use to manually return permits acquired by a lower-level coordination | |
| * protocol. | |
| */ | |
| release(this: Semaphore, permits: number): Effect.Effect<number> | |
| /** | |
| * Releases all permits held by this semaphore and returns the resulting available permits. | |
| * | |
| * **When to use** | |
| * | |
| * Use to return every currently taken permit to the semaphore at once. | |
| */ | |
| readonly releaseAll: Effect.Effect<number> | |
| } | |
| /** | |
| * 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. | |
| * | |
| * **Example** (Creating an unsafe semaphore) | |
| * | |
| * ```ts | |
| * import { Effect, Semaphore } from "effect" | |
| * | |
| * const semaphore = Semaphore.makeUnsafe(3) | |
| * | |
| * const task = (id: number) => | |
| * semaphore.withPermits(1)( | |
| * Effect.gen(function*() { | |
| * yield* Effect.log(`Task ${id} started`) | |
| * yield* Effect.sleep("1 second") | |
| * yield* Effect.log(`Task ${id} completed`) | |
| * }) | |
| * ) | |
| * | |
| * // Only 3 tasks can run concurrently | |
| * const program = Effect.all([ | |
| * task(1), | |
| * task(2), | |
| * task(3), | |
| * task(4), | |
| * task(5) | |
| * ], { concurrency: "unbounded" }) | |
| * ``` | |
| * | |
| * @category constructors | |
| * @since 4.0.0 | |
| */ | |
| export const makeUnsafe = (permits: number): Semaphore => new SemaphoreImpl(permits) | |
| class SemaphoreImpl implements Semaphore { | |
| public waiters = new Set<() => void>() | |
| public taken = 0 | |
| public permits: number | |
| constructor(permits: number) { | |
| this.permits = permits | |
| } | |
| get free() { | |
| return this.permits - this.taken | |
| } | |
| take(n: number): Effect.Effect<number> { | |
| const take: Effect.Effect<number> = internal.suspend(() => { | |
| if (this.free < n) { | |
| return internal.callback((resume) => { | |
| if (this.free >= n) return resume(take) | |
| const observer = () => { | |
| if (this.free < n) return | |
| this.waiters.delete(observer) | |
| resume(take) | |
| } | |
| this.waiters.add(observer) | |
| return internal.sync(() => { | |
| this.waiters.delete(observer) | |
| }) | |
| }) | |
| } | |
| this.taken += n | |
| return internal.succeed(n) | |
| }) | |
| return take | |
| } | |
| updateTakenUnsafe(fiber: Fiber<any, any>, f: (n: number) => number): number { | |
| this.taken = f(this.taken) | |
| if (this.waiters.size > 0) { | |
| fiber.currentDispatcher.scheduleTask(() => { | |
| const iter = this.waiters.values() | |
| let item = iter.next() | |
| while (item.done === false && this.free > 0) { | |
| item.value() | |
| item = iter.next() | |
| } | |
| }, 0) | |
| } | |
| return this.free | |
| } | |
| updateTaken(f: (n: number) => number): Effect.Effect<number> { | |
| return core.withFiber((fiber) => internal.succeed(this.updateTakenUnsafe(fiber, f))) | |
| } | |
| resize(permits: number) { | |
| return core.withFiber((fiber) => { | |
| this.permits = permits | |
| if (this.free < 0) return internal.void | |
| this.updateTakenUnsafe(fiber, (taken) => taken) | |
| return internal.void | |
| }) | |
| } | |
| release(n: number): Effect.Effect<number> { | |
| return this.updateTaken((taken) => taken - n) | |
| } | |
| get releaseAll(): Effect.Effect<number> { | |
| return this.updateTaken((_) => 0) | |
| } | |
| withPermits(n: number) { | |
| return <A, E, R>(self: Effect.Effect<A, E, R>) => | |
| internal.uninterruptibleMask((restore) => | |
| internal.flatMap( | |
| restore(this.take(n)), | |
| (permits) => | |
| internal.onExitPrimitive( | |
| restore(self), | |
| () => { | |
| this.updateTakenUnsafe(internal.getCurrentFiber()!, (taken) => taken - permits) | |
| return undefined | |
| }, | |
| true | |
| ) | |
| ) | |
| ) | |
| } | |
| readonly withPermit = this.withPermits(1) | |
| withPermitsIfAvailable(n: number) { | |
| return <A, E, R>(self: Effect.Effect<A, E, R>) => | |
| internal.uninterruptibleMask((restore) => { | |
| if (this.free < n) return internal.succeedNone | |
| this.taken += n | |
| return internal.onExitPrimitive(restore(internal.asSome(self)), () => { | |
| this.updateTakenUnsafe(internal.getCurrentFiber()!, (taken) => taken - n) | |
| return undefined | |
| }, true) | |
| }) | |
| } | |
| } | |
| /** | |
| * 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. | |
| * | |
| * **Example** (Creating a semaphore) | |
| * | |
| * ```ts | |
| * import { Effect, Semaphore } from "effect" | |
| * | |
| * const program = Effect.gen(function*() { | |
| * const semaphore = yield* Semaphore.make(2) | |
| * | |
| * const task = (id: number) => | |
| * semaphore.withPermits(1)( | |
| * Effect.gen(function*() { | |
| * yield* Effect.log(`Task ${id} acquired permit`) | |
| * yield* Effect.sleep("1 second") | |
| * yield* Effect.log(`Task ${id} releasing permit`) | |
| * }) | |
| * ) | |
| * | |
| * // Run 4 tasks, but only 2 can run concurrently | |
| * yield* Effect.all([task(1), task(2), task(3), task(4)]) | |
| * }) | |
| * ``` | |
| * | |
| * @category constructors | |
| * @since 4.0.0 | |
| */ | |
| export const make = (permits: number): Effect.Effect<Semaphore> => internal.sync(() => new SemaphoreImpl(permits)) | |
| /** | |
| * 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 {@link make} for creating a semaphore with an initial permit count | |
| * @see {@link release} for returning permits without changing semaphore capacity | |
| * | |
| * @category combinators | |
| * @since 4.0.0 | |
| */ | |
| export const resize: { | |
| /** | |
| * 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 {@link make} for creating a semaphore with an initial permit count | |
| * @see {@link release} for returning permits without changing semaphore capacity | |
| * | |
| * @category combinators | |
| * @since 4.0.0 | |
| */ | |
| (permits: number): (self: Semaphore) => Effect.Effect<void> | |
| /** | |
| * 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 {@link make} for creating a semaphore with an initial permit count | |
| * @see {@link release} for returning permits without changing semaphore capacity | |
| * | |
| * @category combinators | |
| * @since 4.0.0 | |
| */ | |
| (self: Semaphore, permits: number): Effect.Effect<void> | |
| } = dual(2, (self: Semaphore, permits: number) => self.resize(permits)) | |
| /** | |
| * 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 {@link withPermit} for acquiring exactly one permit | |
| * @see {@link withPermitsIfAvailable} for running only when permits are immediately available | |
| * @see {@link take} for manually acquiring permits | |
| * @see {@link release} for manually returning permits | |
| * | |
| * @category combinators | |
| * @since 4.0.0 | |
| */ | |
| export const 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 {@link withPermit} for acquiring exactly one permit | |
| * @see {@link withPermitsIfAvailable} for running only when permits are immediately available | |
| * @see {@link take} for manually acquiring permits | |
| * @see {@link release} for manually returning permits | |
| * | |
| * @category combinators | |
| * @since 4.0.0 | |
| */ | |
| (self: Semaphore, permits: number): <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R> | |
| /** | |
| * 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 {@link withPermit} for acquiring exactly one permit | |
| * @see {@link withPermitsIfAvailable} for running only when permits are immediately available | |
| * @see {@link take} for manually acquiring permits | |
| * @see {@link release} for manually returning permits | |
| * | |
| * @category combinators | |
| * @since 4.0.0 | |
| */ | |
| <A, E, R>(self: Semaphore, permits: number, effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> | |
| } = ((self: Semaphore, permits: number, effect?: Effect.Effect<any, any, any>) => { | |
| const withPermits = self.withPermits(permits) | |
| return effect ? withPermits(effect) : withPermits | |
| }) as any | |
| /** | |
| * 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 {@link withPermits} for acquiring more than one permit | |
| * @see {@link withPermitsIfAvailable} for running only when permits are immediately available | |
| * @see {@link take} for manually acquiring permits | |
| * @see {@link release} for manually returning permits | |
| * | |
| * @category combinators | |
| * @since 4.0.0 | |
| */ | |
| export const 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 {@link withPermits} for acquiring more than one permit | |
| * @see {@link withPermitsIfAvailable} for running only when permits are immediately available | |
| * @see {@link take} for manually acquiring permits | |
| * @see {@link release} for manually returning permits | |
| * | |
| * @category combinators | |
| * @since 4.0.0 | |
| */ | |
| (self: Semaphore): <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R> | |
| /** | |
| * 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 {@link withPermits} for acquiring more than one permit | |
| * @see {@link withPermitsIfAvailable} for running only when permits are immediately available | |
| * @see {@link take} for manually acquiring permits | |
| * @see {@link release} for manually returning permits | |
| * | |
| * @category combinators | |
| * @since 4.0.0 | |
| */ | |
| <A, E, R>(self: Semaphore, effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> | |
| } = ((self: Semaphore, effect?: Effect.Effect<any, any, any>) => { | |
| if (!effect) return self.withPermit | |
| return self.withPermit(effect) | |
| }) as any | |
| /** | |
| * 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 {@link withPermits} for the variant that waits until permits are available | |
| * | |
| * @category combinators | |
| * @since 4.0.0 | |
| */ | |
| export const 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 {@link withPermits} for the variant that waits until permits are available | |
| * | |
| * @category combinators | |
| * @since 4.0.0 | |
| */ | |
| (self: Semaphore, permits: number): <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<Option.Option<A>, E, R> | |
| /** | |
| * 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 {@link withPermits} for the variant that waits until permits are available | |
| * | |
| * @category combinators | |
| * @since 4.0.0 | |
| */ | |
| <A, E, R>(self: Semaphore, permits: number, effect: Effect.Effect<A, E, R>): Effect.Effect<Option.Option<A>, E, R> | |
| } = ((self: Semaphore, permits: number, effect?: Effect.Effect<any, any, any>) => { | |
| const withPermits = self.withPermitsIfAvailable(permits) | |
| return effect ? withPermits(effect) : withPermits | |
| }) as any | |
| /** | |
| * 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 {@link withPermit} for automatically acquiring and releasing one permit around an effect | |
| * @see {@link withPermits} for automatically acquiring and releasing multiple permits around an effect | |
| * @see {@link release} for returning manually acquired permits | |
| * | |
| * @category combinators | |
| * @since 4.0.0 | |
| */ | |
| export const take: { | |
| /** | |
| * 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 {@link withPermit} for automatically acquiring and releasing one permit around an effect | |
| * @see {@link withPermits} for automatically acquiring and releasing multiple permits around an effect | |
| * @see {@link release} for returning manually acquired permits | |
| * | |
| * @category combinators | |
| * @since 4.0.0 | |
| */ | |
| (permits: number): (self: Semaphore) => Effect.Effect<number> | |
| /** | |
| * 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 {@link withPermit} for automatically acquiring and releasing one permit around an effect | |
| * @see {@link withPermits} for automatically acquiring and releasing multiple permits around an effect | |
| * @see {@link release} for returning manually acquired permits | |
| * | |
| * @category combinators | |
| * @since 4.0.0 | |
| */ | |
| (self: Semaphore, permits: number): Effect.Effect<number> | |
| } = dual(2, (self: Semaphore, permits: number) => self.take(permits)) | |
| /** | |
| * Releases the specified number of permits and returns the resulting available | |
| * permits. | |
| * | |
| * **When to use** | |
| * | |
| * Use when you need to return permits acquired with `take` in 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` / `release` usage must keep permit counts balanced. Prefer | |
| * `withPermit` or `withPermits` when the acquisition can be scoped to one | |
| * effect. | |
| * | |
| * @see {@link take} for manually acquiring permits | |
| * @see {@link releaseAll} for returning every currently taken permit | |
| * @see {@link withPermits} for automatic acquire and release around an effect | |
| * | |
| * @category combinators | |
| * @since 4.0.0 | |
| */ | |
| export const release: { | |
| /** | |
| * Releases the specified number of permits and returns the resulting available | |
| * permits. | |
| * | |
| * **When to use** | |
| * | |
| * Use when you need to return permits acquired with `take` in 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` / `release` usage must keep permit counts balanced. Prefer | |
| * `withPermit` or `withPermits` when the acquisition can be scoped to one | |
| * effect. | |
| * | |
| * @see {@link take} for manually acquiring permits | |
| * @see {@link releaseAll} for returning every currently taken permit | |
| * @see {@link withPermits} for automatic acquire and release around an effect | |
| * | |
| * @category combinators | |
| * @since 4.0.0 | |
| */ | |
| (permits: number): (self: Semaphore) => Effect.Effect<number> | |
| /** | |
| * Releases the specified number of permits and returns the resulting available | |
| * permits. | |
| * | |
| * **When to use** | |
| * | |
| * Use when you need to return permits acquired with `take` in 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` / `release` usage must keep permit counts balanced. Prefer | |
| * `withPermit` or `withPermits` when the acquisition can be scoped to one | |
| * effect. | |
| * | |
| * @see {@link take} for manually acquiring permits | |
| * @see {@link releaseAll} for returning every currently taken permit | |
| * @see {@link withPermits} for automatic acquire and release around an effect | |
| * | |
| * @category combinators | |
| * @since 4.0.0 | |
| */ | |
| (self: Semaphore, permits: number): Effect.Effect<number> | |
| } = dual(2, (self: Semaphore, permits: number) => self.release(permits)) | |
| /** | |
| * 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 {@link release} for releasing a known permit count | |
| * @see {@link withPermits} for automatic acquire and release around an effect | |
| * | |
| * @category combinators | |
| * @since 4.0.0 | |
| */ | |
| export const releaseAll = (self: Semaphore): Effect.Effect<number> => self.releaseAll | |
Xet Storage Details
- Size:
- 24.7 kB
- Xet hash:
- 17bb7cafeb88f411e16fa438494f64a9a93bf4478d1f6fd9c89602513338cc5b
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.