(times: number): Schedule<number>Returns a Schedule which can only be stepped the specified number of
times before it terminates.
When to use
Use when you need a counter schedule with no additional delay.
Gotchas
recurs(n) counts schedule recurrences, not the first evaluation of the
effect being repeated or retried. For retrying, this means one initial
attempt plus at most n retries.
Example (Limiting recurrences)
import { Console, Data, Effect, Schedule } from "effect"
class RetryAttemptError extends Data.TaggedError("RetryAttemptError")<{ readonly message: string }> {}
// Basic recurs - retry at most 3 times
const maxThreeAttempts = Schedule.recurs(3)
// Retry a failing operation at most 5 times
const program = Effect.gen(function*() {
let attempt = 0
const result = yield* Effect.retry(
Effect.gen(function*() {
attempt++
yield* Console.log(`Attempt ${attempt}`)
if (attempt < 4) {
return yield* Effect.fail(new RetryAttemptError({ message: `Attempt ${attempt} failed` }))
}
return `Success on attempt ${attempt}`
}),
Schedule.recurs(5) // Will retry up to 5 times
)
yield* Console.log(`Final result: ${result}`)
})
// Combining recurs with other schedules for sophisticated retry logic
const complexRetry = Schedule.max([
Schedule.exponential("100 millis"),
Schedule.recurs(3) // At most 3 retries
])
// Allow ten recurrences after the initial run
const tenRecurrences = Effect.gen(function*() {
yield* Console.log("Executing task...")
return "completed"
}).pipe(
Effect.repeat(Schedule.recurs(10))
)
// The schedule outputs the current recurrence count (0-based)
const countingSchedule = Schedule.recurs(3).pipe(
Schedule.tap(({ output: count }) => Console.log(`Execution #${count + 1}`))
)export const const recurs: (
times: number
) => Schedule<number>
Returns a Schedule which can only be stepped the specified number of
times before it terminates.
When to use
Use when you need a counter schedule with no additional delay.
Gotchas
recurs(n) counts schedule recurrences, not the first evaluation of the
effect being repeated or retried. For retrying, this means one initial
attempt plus at most n retries.
Example (Limiting recurrences)
import { Console, Data, Effect, Schedule } from "effect"
class RetryAttemptError extends Data.TaggedError("RetryAttemptError")<{ readonly message: string }> {}
// Basic recurs - retry at most 3 times
const maxThreeAttempts = Schedule.recurs(3)
// Retry a failing operation at most 5 times
const program = Effect.gen(function*() {
let attempt = 0
const result = yield* Effect.retry(
Effect.gen(function*() {
attempt++
yield* Console.log(`Attempt ${attempt}`)
if (attempt < 4) {
return yield* Effect.fail(new RetryAttemptError({ message: `Attempt ${attempt} failed` }))
}
return `Success on attempt ${attempt}`
}),
Schedule.recurs(5) // Will retry up to 5 times
)
yield* Console.log(`Final result: ${result}`)
})
// Combining recurs with other schedules for sophisticated retry logic
const complexRetry = Schedule.max([
Schedule.exponential("100 millis"),
Schedule.recurs(3) // At most 3 retries
])
// Allow ten recurrences after the initial run
const tenRecurrences = Effect.gen(function*() {
yield* Console.log("Executing task...")
return "completed"
}).pipe(
Effect.repeat(Schedule.recurs(10))
)
// The schedule outputs the current recurrence count (0-based)
const countingSchedule = Schedule.recurs(3).pipe(
Schedule.tap(({ output: count }) => Console.log(`Execution #${count + 1}`))
)
recurs = (times: numbertimes: number): 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<number> =>
const while_: {
<Input, Output, Error2 = never, Env2 = never>(
predicate: (
metadata: Metadata<Output, Input>
) => boolean | Effect<boolean, Error2, Env2>
): <Error, Env>(
self: Schedule<Output, Input, Error, Env>
) => Schedule<
Output,
Input,
Error | Error2,
Env | Env2
>
<
Output,
Input,
Error,
Env,
Error2 = never,
Env2 = never
>(
self: Schedule<Output, Input, Error, Env>,
predicate: (
metadata: Metadata<Output, Input>
) => boolean | Effect<boolean, Error2, Env2>
): Schedule<
Output,
Input,
Error | Error2,
Env | Env2
>
}
while_(const forever: Schedule<number>const forever: {
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; <…;
}
Returns a new Schedule that will recur forever.
Details
The output of the schedule is the current count of its repetitions thus far
(i.e. 0, 1, 2, ...).
Example (Repeating forever)
import { Console, Effect, Schedule } from "effect"
// A schedule that runs forever with no delay
const infiniteSchedule = Schedule.forever
const program = Effect.gen(function*() {
yield* Effect.repeat(
Effect.gen(function*() {
yield* Console.log("Running forever...")
return "continuous-task"
}),
infiniteSchedule.pipe(Schedule.upTo({ times: 5 })) // Limit for demo
)
})
forever, ({ attempt: numberattempt }) => import effecteffect.const succeed: <A>(
value: A
) => Effect.Effect<A>
succeed(attempt: numberattempt <= times: numbertimes))