Pool.ts
Pool.ts overview
Section titled “Pool.ts overview”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
Exports Grouped by Category
Section titled “Exports Grouped by Category”combinators
Section titled “combinators”invalidate
Section titled “invalidate”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
getfor 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>}Since v2.0.0
constructors
Section titled “constructors”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
makeWithTTLfor pools with min/max sizes and a TTL-based shrinking policymakeWithStrategyfor 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>Since v2.0.0
makeWithStrategy
Section titled “makeWithStrategy”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
makefor fixed-size pools without custom resizing or reclamationmakeWithTTLfor min/max pools that shrink excess items with a TTL policyStrategyfor 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>Since v4.0.0
makeWithTTL
Section titled “makeWithTTL”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>Since v2.0.0
getters
Section titled “getters”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
invalidatefor removing an unhealthy item from future reuse
Signature
declare const get: <A, E>(self: Pool<A, E>) => Effect.Effect<A, E, Scope.Scope>Since v2.0.0
models
Section titled “models”Config (interface)
Section titled “Config (interface)”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
Poolfor the value exposing this configurationStatefor mutable runtime state instead of static configurationStrategyfor 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}Since v4.0.0
Pool (interface)
Section titled “Pool (interface)”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
makefor creating a pool with size boundsmakeWithTTLfor creating a pool with idle item expirationmakeWithStrategyfor creating a pool with a custom strategygetfor acquiring an item from a poolinvalidatefor 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>}Since v2.0.0
PoolItem (interface)
Section titled “PoolItem (interface)”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
Strategyfor the custom strategy callbacks that receive and return pool itemsStatefor 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}Since v4.0.0
State (interface)
Section titled “State (interface)”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
Poolfor the pool value exposing this statePoolItemfor the entries stored in the runtime item setsgetfor acquiring items through the high-level APIinvalidatefor 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}Since v4.0.0
Strategy (interface)
Section titled “Strategy (interface)”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
makeWithStrategyfor constructing a pool from a customStrategy
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>}Since v4.0.0
refinements
Section titled “refinements”isPool
Section titled “isPool”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>Since v2.0.0