<Output, Input, X, Error2, Env2>(
f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>
): <Error, Env>(
self: Schedule<Output, Input, Error, Env>
) => Schedule<Output, Input, Error | Error2, Env | Env2>
<Output, Input, Error, Env, X, Error2, Env2>(
self: Schedule<Output, Input, Error, Env>,
f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>
): Schedule<Output, Input, Error | Error2, Env | Env2>Returns a new Schedule that allows execution of an effectful function for
every decision of the schedule, but does not alter the inputs and outputs of
the schedule.
Details
The callback receives the full schedule metadata, including the input, output, computed delay duration, current attempt, and elapsed timing information.
Example (Tapping schedule metadata)
import { Console, Effect, Schedule } from "effect"
const monitoredSchedule = Schedule.exponential("100 millis").pipe(
Schedule.upTo({ times: 5 }),
Schedule.tap((metadata) =>
Console.log(
`Attempt ${metadata.attempt} produced ${metadata.output} ` +
`after ${metadata.elapsed}ms; next delay is ${metadata.duration}`
)
)
)
const program = Effect.retry(
Effect.fail("transient error"),
monitoredSchedule
)export const const tap: {
<Output, Input, X, Error2, Env2>(
f: (
metadata: Metadata<Output, Input>
) => Effect<X, Error2, Env2>
): <Error, Env>(
self: Schedule<Output, Input, Error, Env>
) => Schedule<
Output,
Input,
Error | Error2,
Env | Env2
>
<Output, Input, Error, Env, X, Error2, Env2>(
self: Schedule<Output, Input, Error, Env>,
f: (
metadata: Metadata<Output, Input>
) => Effect<X, Error2, Env2>
): Schedule<
Output,
Input,
Error | Error2,
Env | Env2
>
}
Returns a new Schedule that allows execution of an effectful function for
every decision of the schedule, but does not alter the inputs and outputs of
the schedule.
Details
The callback receives the full schedule metadata, including the input, output,
computed delay duration, current attempt, and elapsed timing information.
Example (Tapping schedule metadata)
import { Console, Effect, Schedule } from "effect"
const monitoredSchedule = Schedule.exponential("100 millis").pipe(
Schedule.upTo({ times: 5 }),
Schedule.tap((metadata) =>
Console.log(
`Attempt ${metadata.attempt} produced ${metadata.output} ` +
`after ${metadata.elapsed}ms; next delay is ${metadata.duration}`
)
)
)
const program = Effect.retry(
Effect.fail("transient error"),
monitoredSchedule
)
tap: {
<function (type parameter) Output in <Output, Input, X, Error2, Env2>(f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): <Error, Env>(self: Schedule<Output, Input, Error, Env>) => Schedule<Output, Input, Error | Error2, Env | Env2>Output, function (type parameter) Input in <Output, Input, X, Error2, Env2>(f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): <Error, Env>(self: Schedule<Output, Input, Error, Env>) => Schedule<Output, Input, Error | Error2, Env | Env2>Input, function (type parameter) X in <Output, Input, X, Error2, Env2>(f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): <Error, Env>(self: Schedule<Output, Input, Error, Env>) => Schedule<Output, Input, Error | Error2, Env | Env2>X, function (type parameter) Error2 in <Output, Input, X, Error2, Env2>(f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): <Error, Env>(self: Schedule<Output, Input, Error, Env>) => Schedule<Output, Input, Error | Error2, Env | Env2>Error2, function (type parameter) Env2 in <Output, Input, X, Error2, Env2>(f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): <Error, Env>(self: Schedule<Output, Input, Error, Env>) => Schedule<Output, Input, Error | Error2, Env | Env2>Env2>(
f: (
metadata: Metadata<Output, Input>
) => Effect<X, Error2, Env2>
f: (metadata: Metadata<Output, Input>(parameter) metadata: {
output: Output;
duration: Duration.Duration;
input: Input;
attempt: number;
start: number;
now: number;
elapsed: number;
elapsedSincePrevious: number;
}
metadata: interface Metadata<Output = unknown, Input = unknown>Extended metadata that includes both input metadata and the output value from the schedule.
Metadata<function (type parameter) Output in <Output, Input, X, Error2, Env2>(f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): <Error, Env>(self: Schedule<Output, Input, Error, Env>) => Schedule<Output, Input, Error | Error2, Env | Env2>Output, function (type parameter) Input in <Output, Input, X, Error2, Env2>(f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): <Error, Env>(self: Schedule<Output, Input, Error, Env>) => Schedule<Output, Input, Error | Error2, Env | Env2>Input>) => 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) X in <Output, Input, X, Error2, Env2>(f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): <Error, Env>(self: Schedule<Output, Input, Error, Env>) => Schedule<Output, Input, Error | Error2, Env | Env2>X, function (type parameter) Error2 in <Output, Input, X, Error2, Env2>(f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): <Error, Env>(self: Schedule<Output, Input, Error, Env>) => Schedule<Output, Input, Error | Error2, Env | Env2>Error2, function (type parameter) Env2 in <Output, Input, X, Error2, Env2>(f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): <Error, Env>(self: Schedule<Output, Input, Error, Env>) => Schedule<Output, Input, Error | Error2, Env | Env2>Env2>
): <function (type parameter) Error in <Error, Env>(self: Schedule<Output, Input, Error, Env>): Schedule<Output, Input, Error | Error2, Env | Env2>Error, function (type parameter) Env in <Error, Env>(self: Schedule<Output, Input, Error, Env>): Schedule<Output, Input, Error | Error2, Env | Env2>Env>(
self: Schedule<Output, Input, Error, Env>(parameter) self: {
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; <…;
}
self: interface Schedule<out Output, in Input = unknown, out Error = never, out Env = never>A Schedule defines a strategy for repeating or retrying effects based on some policy.
Example (Defining retry and repeat schedules)
import { Console, Data, Effect, Schedule } from "effect"
class NetworkError extends Data.TaggedError("NetworkError")<{
readonly attempt: number
}> {}
// Basic retry schedule - retry up to 3 times with exponential backoff
const retrySchedule = Schedule.max([
Schedule.exponential("100 millis"),
Schedule.recurs(3)
])
// Basic repeat schedule - repeat every 30 seconds forever
const repeatSchedule: Schedule.Schedule<number, unknown, never> = Schedule
.spaced("30 seconds")
const program = Effect.gen(function*() {
let attempts = 0
const result1 = yield* Effect.retry(
Effect.gen(function*() {
attempts++
if (attempts < 3) {
return yield* Effect.fail(new NetworkError({ attempt: attempts }))
}
return "Success"
}),
retrySchedule
)
console.log(result1) // "Success"
yield* Console.log("heartbeat").pipe(
Effect.repeat(repeatSchedule.pipe(Schedule.upTo({ times: 5 })))
)
})
The Schedule namespace contains types and utilities for working with schedules.
Schedule<function (type parameter) Output in <Output, Input, X, Error2, Env2>(f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): <Error, Env>(self: Schedule<Output, Input, Error, Env>) => Schedule<Output, Input, Error | Error2, Env | Env2>Output, function (type parameter) Input in <Output, Input, X, Error2, Env2>(f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): <Error, Env>(self: Schedule<Output, Input, Error, Env>) => Schedule<Output, Input, Error | Error2, Env | Env2>Input, function (type parameter) Error in <Error, Env>(self: Schedule<Output, Input, Error, Env>): Schedule<Output, Input, Error | Error2, Env | Env2>Error, function (type parameter) Env in <Error, Env>(self: Schedule<Output, Input, Error, Env>): Schedule<Output, Input, Error | Error2, Env | Env2>Env>
) => interface Schedule<out Output, in Input = unknown, out Error = never, out Env = never>A Schedule defines a strategy for repeating or retrying effects based on some policy.
Example (Defining retry and repeat schedules)
import { Console, Data, Effect, Schedule } from "effect"
class NetworkError extends Data.TaggedError("NetworkError")<{
readonly attempt: number
}> {}
// Basic retry schedule - retry up to 3 times with exponential backoff
const retrySchedule = Schedule.max([
Schedule.exponential("100 millis"),
Schedule.recurs(3)
])
// Basic repeat schedule - repeat every 30 seconds forever
const repeatSchedule: Schedule.Schedule<number, unknown, never> = Schedule
.spaced("30 seconds")
const program = Effect.gen(function*() {
let attempts = 0
const result1 = yield* Effect.retry(
Effect.gen(function*() {
attempts++
if (attempts < 3) {
return yield* Effect.fail(new NetworkError({ attempt: attempts }))
}
return "Success"
}),
retrySchedule
)
console.log(result1) // "Success"
yield* Console.log("heartbeat").pipe(
Effect.repeat(repeatSchedule.pipe(Schedule.upTo({ times: 5 })))
)
})
The Schedule namespace contains types and utilities for working with schedules.
Schedule<function (type parameter) Output in <Output, Input, X, Error2, Env2>(f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): <Error, Env>(self: Schedule<Output, Input, Error, Env>) => Schedule<Output, Input, Error | Error2, Env | Env2>Output, function (type parameter) Input in <Output, Input, X, Error2, Env2>(f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): <Error, Env>(self: Schedule<Output, Input, Error, Env>) => Schedule<Output, Input, Error | Error2, Env | Env2>Input, function (type parameter) Error in <Error, Env>(self: Schedule<Output, Input, Error, Env>): Schedule<Output, Input, Error | Error2, Env | Env2>Error | function (type parameter) Error2 in <Output, Input, X, Error2, Env2>(f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): <Error, Env>(self: Schedule<Output, Input, Error, Env>) => Schedule<Output, Input, Error | Error2, Env | Env2>Error2, function (type parameter) Env in <Error, Env>(self: Schedule<Output, Input, Error, Env>): Schedule<Output, Input, Error | Error2, Env | Env2>Env | function (type parameter) Env2 in <Output, Input, X, Error2, Env2>(f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): <Error, Env>(self: Schedule<Output, Input, Error, Env>) => Schedule<Output, Input, Error | Error2, Env | Env2>Env2>
<function (type parameter) Output in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Output, function (type parameter) Input in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Input, function (type parameter) Error in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Error, function (type parameter) Env in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Env, function (type parameter) X in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>X, function (type parameter) Error2 in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Error2, function (type parameter) Env2 in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Env2>(
self: Schedule<Output, Input, Error, Env>(parameter) self: {
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; <…;
}
self: interface Schedule<out Output, in Input = unknown, out Error = never, out Env = never>A Schedule defines a strategy for repeating or retrying effects based on some policy.
Example (Defining retry and repeat schedules)
import { Console, Data, Effect, Schedule } from "effect"
class NetworkError extends Data.TaggedError("NetworkError")<{
readonly attempt: number
}> {}
// Basic retry schedule - retry up to 3 times with exponential backoff
const retrySchedule = Schedule.max([
Schedule.exponential("100 millis"),
Schedule.recurs(3)
])
// Basic repeat schedule - repeat every 30 seconds forever
const repeatSchedule: Schedule.Schedule<number, unknown, never> = Schedule
.spaced("30 seconds")
const program = Effect.gen(function*() {
let attempts = 0
const result1 = yield* Effect.retry(
Effect.gen(function*() {
attempts++
if (attempts < 3) {
return yield* Effect.fail(new NetworkError({ attempt: attempts }))
}
return "Success"
}),
retrySchedule
)
console.log(result1) // "Success"
yield* Console.log("heartbeat").pipe(
Effect.repeat(repeatSchedule.pipe(Schedule.upTo({ times: 5 })))
)
})
The Schedule namespace contains types and utilities for working with schedules.
Schedule<function (type parameter) Output in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Output, function (type parameter) Input in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Input, function (type parameter) Error in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Error, function (type parameter) Env in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Env>,
f: (
metadata: Metadata<Output, Input>
) => Effect<X, Error2, Env2>
f: (metadata: Metadata<Output, Input>(parameter) metadata: {
output: Output;
duration: Duration.Duration;
input: Input;
attempt: number;
start: number;
now: number;
elapsed: number;
elapsedSincePrevious: number;
}
metadata: interface Metadata<Output = unknown, Input = unknown>Extended metadata that includes both input metadata and the output value from the schedule.
Metadata<function (type parameter) Output in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Output, function (type parameter) Input in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Input>) => 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) X in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>X, function (type parameter) Error2 in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Error2, function (type parameter) Env2 in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Env2>
): interface Schedule<out Output, in Input = unknown, out Error = never, out Env = never>A Schedule defines a strategy for repeating or retrying effects based on some policy.
Example (Defining retry and repeat schedules)
import { Console, Data, Effect, Schedule } from "effect"
class NetworkError extends Data.TaggedError("NetworkError")<{
readonly attempt: number
}> {}
// Basic retry schedule - retry up to 3 times with exponential backoff
const retrySchedule = Schedule.max([
Schedule.exponential("100 millis"),
Schedule.recurs(3)
])
// Basic repeat schedule - repeat every 30 seconds forever
const repeatSchedule: Schedule.Schedule<number, unknown, never> = Schedule
.spaced("30 seconds")
const program = Effect.gen(function*() {
let attempts = 0
const result1 = yield* Effect.retry(
Effect.gen(function*() {
attempts++
if (attempts < 3) {
return yield* Effect.fail(new NetworkError({ attempt: attempts }))
}
return "Success"
}),
retrySchedule
)
console.log(result1) // "Success"
yield* Console.log("heartbeat").pipe(
Effect.repeat(repeatSchedule.pipe(Schedule.upTo({ times: 5 })))
)
})
The Schedule namespace contains types and utilities for working with schedules.
Schedule<function (type parameter) Output in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Output, function (type parameter) Input in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Input, function (type parameter) Error in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Error | function (type parameter) Error2 in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Error2, function (type parameter) Env in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Env | function (type parameter) Env2 in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Env2>
} = dual<(...args: Array<any>) => any, <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>) => Schedule<Output, Input, Error | Error2, Env | Env2>>(arity: 2, body: <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>) => Schedule<Output, Input, Error | Error2, Env | Env2>): ((...args: Array<any>) => any) & (<Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>) => Schedule<Output, Input, Error | Error2, Env | Env2>) (+1 overload)Creates a function that can be called in data-first style or data-last
(pipe-friendly) style.
When to use
Use to expose one implementation through both direct and pipe-friendly
call styles.
Details
Pass either the arity of the uncurried function or a predicate that decides
whether the current call is data-first. Arity is the common case. Use a
predicate when optional arguments make arity ambiguous.
Example (Selecting data-first or data-last style by arity)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(2, (self, that) => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Defining overloads with call signatures)
import { Function, pipe } from "effect"
const sum: {
(that: number): (self: number) => number
(self: number, that: number): number
} = Function.dual(2, (self: number, that: number): number => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Selecting data-first or data-last style with a predicate)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(
(args) => args.length === 2,
(self, that) => self + that
)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
dual(2, <function (type parameter) Output in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Output, function (type parameter) Input in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Input, function (type parameter) Error in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Error, function (type parameter) Env in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Env, function (type parameter) X in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>X, function (type parameter) Error2 in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Error2, function (type parameter) Env2 in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Env2>(
self: Schedule<Output, Input, Error, Env>(parameter) self: {
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; <…;
}
self: interface Schedule<out Output, in Input = unknown, out Error = never, out Env = never>A Schedule defines a strategy for repeating or retrying effects based on some policy.
Example (Defining retry and repeat schedules)
import { Console, Data, Effect, Schedule } from "effect"
class NetworkError extends Data.TaggedError("NetworkError")<{
readonly attempt: number
}> {}
// Basic retry schedule - retry up to 3 times with exponential backoff
const retrySchedule = Schedule.max([
Schedule.exponential("100 millis"),
Schedule.recurs(3)
])
// Basic repeat schedule - repeat every 30 seconds forever
const repeatSchedule: Schedule.Schedule<number, unknown, never> = Schedule
.spaced("30 seconds")
const program = Effect.gen(function*() {
let attempts = 0
const result1 = yield* Effect.retry(
Effect.gen(function*() {
attempts++
if (attempts < 3) {
return yield* Effect.fail(new NetworkError({ attempt: attempts }))
}
return "Success"
}),
retrySchedule
)
console.log(result1) // "Success"
yield* Console.log("heartbeat").pipe(
Effect.repeat(repeatSchedule.pipe(Schedule.upTo({ times: 5 })))
)
})
The Schedule namespace contains types and utilities for working with schedules.
Schedule<function (type parameter) Output in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Output, function (type parameter) Input in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Input, function (type parameter) Error in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Error, function (type parameter) Env in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Env>,
f: (
metadata: Metadata<Output, Input>
) => Effect<X, Error2, Env2>
f: (metadata: Metadata<Output, Input>(parameter) metadata: {
output: Output;
duration: Duration.Duration;
input: Input;
attempt: number;
start: number;
now: number;
elapsed: number;
elapsedSincePrevious: number;
}
metadata: interface Metadata<Output = unknown, Input = unknown>Extended metadata that includes both input metadata and the output value from the schedule.
Metadata<function (type parameter) Output in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Output, function (type parameter) Input in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Input>) => 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) X in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>X, function (type parameter) Error2 in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Error2, function (type parameter) Env2 in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Env2>
): interface Schedule<out Output, in Input = unknown, out Error = never, out Env = never>A Schedule defines a strategy for repeating or retrying effects based on some policy.
Example (Defining retry and repeat schedules)
import { Console, Data, Effect, Schedule } from "effect"
class NetworkError extends Data.TaggedError("NetworkError")<{
readonly attempt: number
}> {}
// Basic retry schedule - retry up to 3 times with exponential backoff
const retrySchedule = Schedule.max([
Schedule.exponential("100 millis"),
Schedule.recurs(3)
])
// Basic repeat schedule - repeat every 30 seconds forever
const repeatSchedule: Schedule.Schedule<number, unknown, never> = Schedule
.spaced("30 seconds")
const program = Effect.gen(function*() {
let attempts = 0
const result1 = yield* Effect.retry(
Effect.gen(function*() {
attempts++
if (attempts < 3) {
return yield* Effect.fail(new NetworkError({ attempt: attempts }))
}
return "Success"
}),
retrySchedule
)
console.log(result1) // "Success"
yield* Console.log("heartbeat").pipe(
Effect.repeat(repeatSchedule.pipe(Schedule.upTo({ times: 5 })))
)
})
The Schedule namespace contains types and utilities for working with schedules.
Schedule<function (type parameter) Output in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Output, function (type parameter) Input in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Input, function (type parameter) Error in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Error | function (type parameter) Error2 in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Error2, function (type parameter) Env in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Env | function (type parameter) Env2 in <Output, Input, Error, Env, X, Error2, Env2>(self: Schedule<Output, Input, Error, Env>, f: (metadata: Metadata<Output, Input>) => Effect<X, Error2, Env2>): Schedule<Output, Input, Error | Error2, Env | Env2>Env2> =>
const fromStep: <
Input,
Output,
EnvX,
Error,
ErrorX,
Env
>(
step: Effect<
(
now: number,
input: Input
) => Pull.Pull<
[Output, Duration.Duration],
ErrorX,
Output,
EnvX
>,
Error,
Env
>
) => Schedule<
Output,
Input,
Error | Pull.ExcludeDone<ErrorX>,
Env | EnvX
>
Creates a Schedule from a step function that returns a Pull.
Example (Creating a custom schedule from a step function)
import { Cause, Duration, Effect, Schedule } from "effect"
const schedule = Schedule.fromStep(Effect.sync(() => {
let count = 0
return (_now: number, _input: string) => {
if (count >= 3) {
return Cause.done(count)
}
return Effect.succeed([count++, Duration.millis(100)] as [number, Duration.Duration])
}
}))
fromStep(import effecteffect.const map: {
<A, B>(f: (a: A) => B): <E, R>(
self: Effect.Effect<A, E, R>
) => Effect.Effect<B, E, R>
<A, E, R, B>(
self: Effect.Effect<A, E, R>,
f: (a: A) => B
): Effect.Effect<B, E, R>
}
map(const toStep: <Output, Input, Error, Env>(
schedule: Schedule<Output, Input, Error, Env>
) => Effect<
(
now: number,
input: Input
) => Pull.Pull<
[Output, Duration.Duration],
Error,
Output,
Env
>,
never,
Env
>
Extracts the step function from a Schedule.
Example (Extracting a schedule step function)
import { Effect, Schedule } from "effect"
// Extract step function from an existing schedule
const schedule = Schedule.exponential("100 millis").pipe(Schedule.upTo({ times: 3 }))
const program = Effect.gen(function*() {
const stepFn = yield* Schedule.toStep(schedule)
// Use the step function directly for custom logic. The timestamp is
// supplied by the caller, so tests can pass a deterministic value.
const now = 0
const result = yield* stepFn(now, "input")
console.log(`Step result: ${result}`)
})
toStep(self: Schedule<Output, Input, Error, Env>(parameter) self: {
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; <…;
}
self), (step: (
now: number,
input: Input
) => Pull.Pull<
[Output, Duration.Duration],
Error,
Output,
Env
>
step) => {
const const meta: <In>(
now: number,
input: In
) => InputMetadata<In>
meta = const metadataFn: () => <In>(
now: number,
input: In
) => InputMetadata<In>
metadataFn()
return (now: numbernow, input: Inputinput) =>
import effecteffect.const tap: {
<A, B, E2, R2>(
f: (a: NoInfer<A>) => Effect.Effect<B, E2, R2>
): <E, R>(
self: Effect.Effect<A, E, R>
) => Effect.Effect<A, E | E2, R | R2>
<B, E2, R2>(f: Effect.Effect<B, E2, R2>): <
A,
E,
R
>(
self: Effect.Effect<A, E, R>
) => Effect.Effect<A, E | E2, R | R2>
<A, E, R, B, E2, R2>(
self: Effect.Effect<A, E, R>,
f: (a: NoInfer<A>) => Effect.Effect<B, E2, R2>
): Effect.Effect<A, E | E2, R | R2>
<A, E, R, B, E2, R2>(
self: Effect.Effect<A, E, R>,
f: Effect.Effect<B, E2, R2>
): Effect.Effect<A, E | E2, R | R2>
}
tap(step: (
now: number,
input: Input
) => Pull.Pull<
[Output, Duration.Duration],
Error,
Output,
Env
>
step(now: numbernow, input: Inputinput), ([output: Outputoutput, duration: Duration.Duration(parameter) duration: {
value: DurationValue;
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;
}
duration]) => f: (
metadata: Metadata<Output, Input>
) => Effect<X, Error2, Env2>
f({ ...const meta: <In>(
now: number,
input: In
) => InputMetadata<In>
meta(now: numbernow, input: Inputinput), Metadata<Output, Input>.output: Outputoutput, Metadata<Output = unknown, Input = unknown>.duration: Duration.Duration(property) Metadata<Output = unknown, Input = unknown>.duration: {
value: DurationValue;
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;
}
duration }))
})))