<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>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"))
)
)export const 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
>
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"))
)
)
makeWithTTL = <function (type parameter) A in <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>
A, function (type parameter) E in <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>
E, function (type parameter) R in <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>
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
}
options: {
readonly acquire: Effect.Effect<A, E, R>(property) acquire: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
acquire: import EffectEffect.interface Effect<out A, out E = never, out R = never>The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Effect<function (type parameter) A in <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>
A, function (type parameter) E in <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>
E, function (type parameter) R in <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>
R>
readonly min: numbermin: number
readonly max: numbermax: number
readonly concurrency?: number | undefinedconcurrency?: number | undefined
readonly targetUtilization?: number | undefinedtargetUtilization?: number | undefined
readonly timeToLive: Duration.InputtimeToLive: import DurationDuration.type Input =
| number
| bigint
| Duration.Duration
| readonly [seconds: number, nanos: number]
| `${number} nano`
| `${number} nanos`
| `${number} micro`
| `${number} micros`
| `${number} milli`
| `${number} millis`
| `${number} second`
| `${number} seconds`
| `${number} minute`
| `${number} minutes`
| `${number} hour`
| `${number} hours`
| `${number} day`
| `${number} days`
| `${number} week`
| `${number} weeks`
| "Infinity"
| "-Infinity"
| Duration.DurationObject
Valid input types that can be converted to a Duration.
When to use
Use when an API should accept any value that Effect can convert into a
Duration, including existing durations, millisecond numbers, nanosecond
bigints, high-resolution tuples, duration strings, infinity strings, or
duration objects.
Details
String inputs accept values like "10 seconds", "500 millis",
"Infinity", and "-Infinity". Finite fractional values that are
normalized to nanoseconds are rounded to the nearest nanosecond, with ties
away from zero.
Input
readonly timeToLiveStrategy?: "creation" | "usage" | undefinedtimeToLiveStrategy?: "creation" | "usage" | undefined
}): import EffectEffect.interface Effect<out A, out E = never, out R = never>The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Effect<interface Pool<in out A, in out E = never>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.
Pool<function (type parameter) A in <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>
A, function (type parameter) E in <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>
E>, never, function (type parameter) R in <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>
R | import ScopeScope.Scope> =>
import EffectEffect.const flatMap: {
<A, B, E1, R1>(
f: (a: A) => Effect<B, E1, R1>
): <E, R>(
self: Effect<A, E, R>
) => Effect<B, E1 | E, R1 | R>
<A, E, R, B, E1, R1>(
self: Effect<A, E, R>,
f: (a: A) => Effect<B, E1, R1>
): Effect<B, E | E1, R | R1>
}
flatMap(
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
}
options.timeToLiveStrategy?: "creation" | "usage" | undefinedtimeToLiveStrategy === "creation" ?
const strategyCreationTTL: <A, E>(
ttl: Duration.Input
) => Effect.Effect<Strategy<A, E>, never, never>
strategyCreationTTL<function (type parameter) A in <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>
A, function (type parameter) E in <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>
E>(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
}
options.timeToLive: Duration.InputtimeToLive) :
const strategyUsageTTL: <A, E>(
ttl: Duration.Input
) => Effect.Effect<Strategy<A, E>, never, never>
strategyUsageTTL<function (type parameter) A in <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>
A, function (type parameter) E in <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>
E>(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
}
options.timeToLive: Duration.InputtimeToLive),
(strategy: Strategy<A, E>(parameter) strategy: {
run: (pool: Pool<A, E>) => Effect.Effect<void>;
onAcquire: (item: PoolItem<A, E>) => Effect.Effect<void>;
reclaim: (pool: Pool<A, E>) => Effect.Effect<PoolItem<A, E> | undefined>;
}
strategy) => 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
>
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.
makeWithStrategy({ ...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
}
options, strategy: Strategy<A, E>(property) strategy: {
run: (pool: Pool<A, E>) => Effect.Effect<void>;
onAcquire: (item: PoolItem<A, E>) => Effect.Effect<void>;
reclaim: (pool: Pool<A, E>) => Effect.Effect<PoolItem<A, E> | undefined>;
}
strategy })
)