Skip to content

Pool.ts

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.

Since v2.0.0



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.Effect<void, never, Scope.Scope>
<A, E>(self: Pool<A, E>, item: A): Effect.Effect<void, never, Scope.Scope>
}

Source

Since v2.0.0

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 const make: <A, E, R>(options: {
readonly acquire: Effect.Effect<A, E, R>
readonly size: number
readonly concurrency?: number | undefined
readonly targetUtilization?: number | undefined
}) => Effect.Effect<Pool<A, E>, never, R | Scope.Scope>

Source

Since v2.0.0

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 const makeWithStrategy: <A, E, R>(options: {
readonly acquire: Effect.Effect<A, E, R>
readonly min: number
readonly max: number
readonly concurrency?: number | undefined
readonly targetUtilization?: number | undefined
readonly strategy: Strategy<A, E>
}) => Effect.Effect<Pool<A, E>, never, Scope.Scope | R>

Source

Since v4.0.0

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

Example (Creating a connection pool)

import { Duration, Effect, Pool } from "effect"
interface Connection {
readonly execute: (sql: string) => Effect.Effect<ReadonlyArray<string>>
readonly close: Effect.Effect<void>
}
const acquireDBConnection = Effect.acquireRelease(
Effect.succeed({
execute: (sql) => Effect.succeed([`executed: ${sql}`]),
close: Effect.void
} satisfies Connection),
(connection) => connection.close
)
const program = Effect.scoped(
Effect.flatMap(
Pool.makeWithTTL({
acquire: acquireDBConnection,
min: 10,
max: 20,
timeToLive: Duration.seconds(60)
}),
(pool) => Effect.flatMap(Pool.get(pool), (connection) => connection.execute("select 1"))
)
)

Signature

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

Source

Since v2.0.0

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 const get: <A, E>(self: Pool<A, E>) => Effect.Effect<A, E, Scope.Scope>

Source

Since v2.0.0

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

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

Source

Since v4.0.0

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

export interface Pool<in out A, in out E = never> extends Pipeable {
readonly [TypeId]: typeof TypeId
readonly config: Config<A, E>
readonly state: State<A, E>
}

Source

Since v2.0.0

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

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

Source

Since v4.0.0

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

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

Source

Since v4.0.0

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

  • makeWithStrategy for constructing a pool from a custom Strategy

Signature

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

Source

Since v4.0.0

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 const isPool: (u: unknown) => u is Pool<unknown, unknown>

Source

Since v2.0.0