Built-in Schedules
On this page
To demonstrate the functionality of different schedules, we will be working with the following helper:
ts
declare const log: <A, Out>(action: Effect.Effect<A>,schedule: Schedule.Schedule<Out, void>) => void
ts
declare const log: <A, Out>(action: Effect.Effect<A>,schedule: Schedule.Schedule<Out, void>) => void
Click to see the implementation
ts
import {Effect ,Schedule ,TestClock ,Fiber ,TestContext } from "effect"letstart = 0leti = 0export constlog = <A ,Out >(action :Effect .Effect <A >,schedule :Schedule .Schedule <Out , void>) => {Effect .gen (function* () {constfiber :Fiber .RuntimeFiber <[Out , number]> = yield*Effect .gen (function* () {yield*action constnow = yield*TestClock .currentTimeMillis console .log (i === 0? `delay: ${now -start }`:i === 10? "...": `#${i } delay: ${now -start }`)i ++start =now }).pipe (Effect .repeat (schedule .pipe (Schedule .intersect (Schedule .recurs (10)))),Effect .fork )yield*TestClock .adjust (Infinity )yield*Fiber .join (fiber )}).pipe (Effect .provide (TestContext .TestContext ),Effect .runPromise )}
ts
import {Effect ,Schedule ,TestClock ,Fiber ,TestContext } from "effect"letstart = 0leti = 0export constlog = <A ,Out >(action :Effect .Effect <A >,schedule :Schedule .Schedule <Out , void>) => {Effect .gen (function* () {constfiber :Fiber .RuntimeFiber <[Out , number]> = yield*Effect .gen (function* () {yield*action constnow = yield*TestClock .currentTimeMillis console .log (i === 0? `delay: ${now -start }`:i === 10? "...": `#${i } delay: ${now -start }`)i ++start =now }).pipe (Effect .repeat (schedule .pipe (Schedule .intersect (Schedule .recurs (10)))),Effect .fork )yield*TestClock .adjust (Infinity )yield*Fiber .join (fiber )}).pipe (Effect .provide (TestContext .TestContext ),Effect .runPromise )}
The log
helper logs the time delay between each execution. We will use this helper to showcase the behavior of various built-in schedules.
The log
helper accelerates time using TestClock,
which means it simulates the passing of time that would normally occur in a
real-world application.
forever
A schedule that always recurs and produces number of recurrence at each run.
ts
import {Schedule ,Effect } from "effect"import {log } from "./Delay"constschedule =Schedule .forever constaction =Effect .void log (action ,schedule )/*Output:delay: 0#1 delay: 0 < forever#2 delay: 0#3 delay: 0#4 delay: 0#5 delay: 0#6 delay: 0#7 delay: 0#8 delay: 0#9 delay: 0...*/
ts
import {Schedule ,Effect } from "effect"import {log } from "./Delay"constschedule =Schedule .forever constaction =Effect .void log (action ,schedule )/*Output:delay: 0#1 delay: 0 < forever#2 delay: 0#3 delay: 0#4 delay: 0#5 delay: 0#6 delay: 0#7 delay: 0#8 delay: 0#9 delay: 0...*/
once
A schedule that recurs one time.
ts
import {Schedule ,Effect } from "effect"import {log } from "./Delay"constschedule =Schedule .once constaction =Effect .void log (action ,schedule )/*Output:delay: 0#1 delay: 0 < once*/
ts
import {Schedule ,Effect } from "effect"import {log } from "./Delay"constschedule =Schedule .once constaction =Effect .void log (action ,schedule )/*Output:delay: 0#1 delay: 0 < once*/
recurs
A schedule that only recurs the specified number of times.
ts
import {Schedule ,Effect } from "effect"import {log } from "./Delay"constschedule =Schedule .recurs (5)constaction =Effect .void log (action ,schedule )/*Output:delay: 0#1 delay: 0 < recurs#2 delay: 0#3 delay: 0#4 delay: 0#5 delay: 0*/
ts
import {Schedule ,Effect } from "effect"import {log } from "./Delay"constschedule =Schedule .recurs (5)constaction =Effect .void log (action ,schedule )/*Output:delay: 0#1 delay: 0 < recurs#2 delay: 0#3 delay: 0#4 delay: 0#5 delay: 0*/
Recurring at specific intervals
In the context of scheduling, two commonly used schedules are spaced
and fixed
. While they both involve recurring at specific intervals, they have a fundamental difference in how they determine the timing of repetitions.
The spaced
schedule creates a recurring pattern where each repetition is spaced apart by a specified duration. This means that there is a delay between the completion of one repetition and the start of the next. The duration between repetitions remains constant, providing a consistent spacing pattern.
On the other hand, the fixed
schedule recurs on a fixed interval, regardless of the duration of the actions or the completion time of previous repetitions. It operates independently of the execution time, ensuring a regular recurrence at the specified interval.
spaced
A schedule that recurs continuously, each repetition spaced the specified duration from the last run.
ts
import {Schedule ,Effect } from "effect"import {log } from "./Delay"constschedule =Schedule .spaced ("200 millis")constaction =Effect .delay (Effect .void , "100 millis")log (action ,schedule )/*Output:delay: 100#1 delay: 300 < spaced#2 delay: 300#3 delay: 300#4 delay: 300#5 delay: 300#6 delay: 300#7 delay: 300#8 delay: 300#9 delay: 300...*/
ts
import {Schedule ,Effect } from "effect"import {log } from "./Delay"constschedule =Schedule .spaced ("200 millis")constaction =Effect .delay (Effect .void , "100 millis")log (action ,schedule )/*Output:delay: 100#1 delay: 300 < spaced#2 delay: 300#3 delay: 300#4 delay: 300#5 delay: 300#6 delay: 300#7 delay: 300#8 delay: 300#9 delay: 300...*/
The first delay is approximately 100 milliseconds, as the initial execution is not affected by the schedule. Subsequent delays are approximately 200 milliseconds apart, demonstrating the effect of the spaced
schedule.
fixed
A schedule that recurs on a fixed interval. Returns the number of repetitions of the schedule so far.
ts
import {Schedule ,Effect } from "effect"import {log } from "./Delay"constschedule =Schedule .fixed ("200 millis")constaction =Effect .delay (Effect .void , "100 millis")log (action ,schedule )/*Output:delay: 100#1 delay: 300 < fixed#2 delay: 200#3 delay: 200#4 delay: 200#5 delay: 200#6 delay: 200#7 delay: 200#8 delay: 200#9 delay: 200...*/
ts
import {Schedule ,Effect } from "effect"import {log } from "./Delay"constschedule =Schedule .fixed ("200 millis")constaction =Effect .delay (Effect .void , "100 millis")log (action ,schedule )/*Output:delay: 100#1 delay: 300 < fixed#2 delay: 200#3 delay: 200#4 delay: 200#5 delay: 200#6 delay: 200#7 delay: 200#8 delay: 200#9 delay: 200...*/
The first delay is approximately 100 milliseconds, as the initial execution is not affected by the schedule. Subsequent delays are consistently around 200 milliseconds apart, demonstrating the effect of the fixed
schedule.
exponential
A schedule that recurs using exponential backoff.
ts
import {Schedule ,Effect } from "effect"import {log } from "./Delay"constschedule =Schedule .exponential ("10 millis")constaction =Effect .void log (action ,schedule )/*Output:delay: 0#1 delay: 10 < exponential#2 delay: 20#3 delay: 40#4 delay: 80#5 delay: 160#6 delay: 320#7 delay: 640#8 delay: 1280#9 delay: 2560...*/
ts
import {Schedule ,Effect } from "effect"import {log } from "./Delay"constschedule =Schedule .exponential ("10 millis")constaction =Effect .void log (action ,schedule )/*Output:delay: 0#1 delay: 10 < exponential#2 delay: 20#3 delay: 40#4 delay: 80#5 delay: 160#6 delay: 320#7 delay: 640#8 delay: 1280#9 delay: 2560...*/
fibonacci
A schedule that always recurs, increasing delays by summing the preceding two delays (similar to the fibonacci sequence). Returns the current duration between recurrences.
ts
import {Schedule ,Effect } from "effect"import {log } from "./Delay"constschedule =Schedule .fibonacci ("10 millis")constaction =Effect .void log (action ,schedule )/*Output:delay: 0#1 delay: 10 < fibonacci#2 delay: 10#3 delay: 20#4 delay: 30#5 delay: 50#6 delay: 80#7 delay: 130#8 delay: 210#9 delay: 340...*/
ts
import {Schedule ,Effect } from "effect"import {log } from "./Delay"constschedule =Schedule .fibonacci ("10 millis")constaction =Effect .void log (action ,schedule )/*Output:delay: 0#1 delay: 10 < fibonacci#2 delay: 10#3 delay: 20#4 delay: 30#5 delay: 50#6 delay: 80#7 delay: 130#8 delay: 210#9 delay: 340...*/