Skip to content

Pool

Shares scoped resources across fibers.

A Pool<A, E> acquires resource-backed values with a scoped effect, lets fibers borrow them with get, can invalidate broken values, and releases all acquired values when the pool scope closes. This module includes fixed-size pools, pools that resize with a time-to-live policy, custom strategy pools, per-item concurrency limits, and runtime state types used by pool strategies.

11 exports Added in v2.0.0 Source

Combinators

invalidate

Added in v2.0.0 Source

Invalidates the specified item so the pool can remove it and reallocate the item, lazily if needed.

When to use

Use to prevent a pooled item from being reused after it becomes unsuitable, such as a stale connection or a resource that failed a health check.

Gotchas

The item is matched with strict equality. Passing an equivalent but different object instance does nothing.

See

  • get for retrieving scoped items from the pool

Signature

declare const invalidate: {
  <A>(item: A): <E>(self: Pool<A, E>) => Effect<void, never, Scope>;
  <A, E>(self: Pool<A, E>, item: A): Effect<void, never, Scope>;
};

Constructors

make

Added in v2.0.0 Source

Makes a new pool of the specified fixed size.

When to use

Use when you need a fixed-size pool with no growth or shrinkage.

Details

The pool is returned in a Scope, which governs the lifetime of the pool. When the pool is shutdown because the Scope is closed, the individual items allocated by the pool will be released in some unspecified order.

By setting the concurrency parameter, you can control the level of concurrent access per pool item. By default, the number of permits is set to 1.

targetUtilization determines when to create new pool items. It is a value between 0 and 1, where 1 means only create new pool items when all the existing items are fully utilized.

A targetUtilization of 0.5 will create new pool items when the existing items are 50% utilized.

See

  • makeWithTTL for pools with min/max sizes and a TTL-based shrinking policy
  • makeWithStrategy for pools with a custom resizing and reclamation strategy

Signature

declare function make<A, E, R>(options: {
  readonly acquire: Effect<A, E, R>;
  readonly concurrency?: number;
  readonly size: number;
  readonly targetUtilization?: number;
}): Effect<Pool<A, E>, never, Scope | R>;

Creates a scoped pool using a custom resizing and reclamation strategy.

When to use

Use to build a pool whose item lifecycle is controlled by an explicit Strategy, such as custom background resizing, replacement, or reclamation.

Details

The returned pool requires Scope; closing the scope shuts down the pool and releases allocated items.

See

  • make for fixed-size pools without custom resizing or reclamation
  • makeWithTTL for min/max pools that shrink excess items with a TTL policy
  • Strategy for the custom strategy contract consumed by this constructor

Signature

declare function makeWithStrategy<A, E, R>(options: {
  readonly acquire: Effect<A, E, R>;
  readonly concurrency?: number;
  readonly max: number;
  readonly min: number;
  readonly strategy: Strategy<A, E>;
  readonly targetUtilization?: number;
}): Effect<Pool<A, E>, never, Scope | R>;

makeWithTTL

Added in v2.0.0 Source

Creates a scoped pool with minimum and maximum sizes and a time-to-live policy for shrinking unused excess items.

When to use

Use to create an elastic scoped pool that can grow up to a maximum size and later reclaim unused excess items.

Details

The returned pool requires Scope; when that scope is closed, allocated items are released in an unspecified order. concurrency controls how many fibers may use each pool item at once and defaults to 1.

targetUtilization controls when new items are created and is clamped by the pool implementation. A value of 1 waits until existing items are fully utilized before creating more items.

timeToLiveStrategy controls when excess items expire: "creation" measures from item creation, while "usage" measures from pool usage. The default is "usage".

Signature

declare function makeWithTTL<A, E, R>(options: {
  readonly acquire: Effect<A, E, R>;
  readonly concurrency?: number;
  readonly max: number;
  readonly min: number;
  readonly targetUtilization?: number;
  readonly timeToLive: Input;
  readonly timeToLiveStrategy?: "creation" | "usage";
}): Effect<Pool<A, E>, never, Scope | R>;

Getters

get

Added in v2.0.0 Source

Retrieves an item from the pool in a scoped effect.

When to use

Use to borrow a pooled resource for the lifetime of the current scope so it is automatically returned when that scope closes.

Details

The returned effect waits for an available item when the pool is at capacity. If acquiring a new item fails, the effect fails with the acquisition error.

Gotchas

Retrying a failed get can repeat the acquisition attempt.

See

  • invalidate for removing an unhealthy item from future reuse

Signature

declare function get<A, E>(self: Pool<A, E>): Effect<A, E, Scope>;

Guards

isPool

Added in v2.0.0 Source

Returns true if the specified value is a Pool, false otherwise.

When to use

Use to validate unknown values at runtime boundaries before treating them as Pool values.

Details

This predicate narrows the input to Pool<unknown, unknown>.

Signature

declare function isPool(u: unknown): u is Pool<unknown, unknown>;

Models

Config interface

Added in v4.0.0 Source

Normalized configuration used by a Pool.

When to use

Use as the normalized, read-only description of how a pool acquires, sizes, shares, and resizes its items after construction.

Details

The config stores the acquire effect, size bounds, per-item concurrency, target utilization, and resizing strategy used by the pool implementation.

See

  • Pool for the value exposing this configuration
  • State for mutable runtime state instead of static configuration
  • Strategy for the resizing and reclamation contract stored on the config

Signature

interface Config<A, E> {
  readonly acquire: Effect<A, E, Scope>;
  readonly concurrency: number;
  readonly maxSize: number;
  readonly minSize: number;
  readonly strategy: Strategy<A, E>;
  readonly targetUtilization: number;
}

Pool interface

Added in v2.0.0 Source

A Pool<A, E> is a pool of items of type A, each of which may be associated with the acquisition and release of resources. An attempt to get an item A from a pool may fail with an error of type E.

When to use

Use when you need to share a bounded set of scoped resources across fibers while the pool manages acquisition, reuse, and release.

See

  • make for creating a pool with size bounds
  • makeWithTTL for creating a pool with idle item expiration
  • makeWithStrategy for creating a pool with a custom strategy
  • get for acquiring an item from a pool
  • invalidate for removing a broken item from the pool

Signature

interface Pool<in out A, in out E = never> extends Pipeable {
  readonly "~effect/Pool": "~effect/Pool";
  readonly config: Config<A, E>;
  readonly state: State<A, E>;
}

PoolItem interface

Added in v4.0.0 Source

Internal record for a value managed by a Pool.

When to use

Use when implementing a custom pool Strategy that needs to inspect acquired items, track reference counts, or return reclaimable items to the pool.

Details

Each item stores the acquisition Exit, its finalizer, the current reference count, and whether automatic reclaiming has been disabled because the item was invalidated.

See

  • Strategy for the custom strategy callbacks that receive and return pool items
  • State for the runtime sets that store active, available, and invalidated pool items

Signature

interface PoolItem<A, E> {
  disableReclaim: boolean;
  readonly exit: Exit<A, E>;
  finalizer: Effect<void>;
  refCount: number;
}

State interface

Added in v4.0.0 Source

Mutable runtime state maintained by a Pool.

When to use

Use when you need to inspect or support the runtime state backing a Pool, including its scope, item sets, semaphores, waiters, invalidation tracking, and shutdown flag.

Details

This state tracks the pool scope, active and available items, invalidated items, semaphores, waiters, and shutdown status. It is exposed for inspection and implementation support; user code should prefer the high-level pool operations.

See

  • Pool for the pool value exposing this state
  • PoolItem for the entries stored in the runtime item sets
  • get for acquiring items through the high-level API
  • invalidate for invalidating items through the high-level API

Signature

interface State<A, E> {
  readonly available: Set<PoolItem<A, E>>;
  readonly availableLatch: Latch;
  readonly invalidated: Set<PoolItem<A, E>>;
  isShuttingDown: boolean;
  readonly items: Set<PoolItem<A, E>>;
  readonly resizeSemaphore: Semaphore;
  readonly scope: Scope;
  readonly semaphore: Semaphore;
  waiters: number;
}

Strategy interface

Added in v4.0.0 Source

Strategy used by a Pool to manage background resizing and item reclamation.

When to use

Use when defining a custom pool lifecycle policy that needs to run background work, observe acquired items, or choose items for reclamation.

Details

run starts any strategy-specific background work, onAcquire is invoked when an item is acquired, and reclaim selects an item that can be removed or replaced.

See

Signature

interface Strategy<A, E> {
  readonly onAcquire: (item: PoolItem<A, E>) => Effect<void>;
  readonly reclaim: (pool: Pool<A, E>) => Effect<PoolItem<A, E> | undefined>;
  readonly run: (pool: Pool<A, E>) => Effect<void>;
}