ScheduleModule
Schedule
A Schedule<'env, 'input, 'output> decides, after each run of a flow, whether to run it again and how long to wait
first. It holds no state, so one schedule value can drive any number of independent runs.
Build one from recurs, spaced,
exponential, or fixedRate, then shape it: cap it with
union or upTo, bound it with
intersect or recursAtMost, filter by the retried
error with whileInput, sequence two with andThen, and
restart the count after a healthy run with resetAfter.
Drive it with Flow.retry after typed failures,
Flow.repeat after successes, or
FlowStream.fromSchedule as a stream of its outputs.
Delays are measured on the runtime's time, not the application clock. Read the
Scheduling and retries guide.
Summary
| Name | Signature | Synopsis |
|---|---|---|
| Operations | ||
| recurs | Schedule.recurs n | Creates a schedule that recurs a fixed number of times. |
| spaced | Schedule.spaced delay | Creates a schedule that recurs with a fixed delay between attempts. |
| exponential | Schedule.exponential baseDelay | Creates a schedule that recurs with exponential backoff. |
| jitteredWith | Schedule.jitteredWith sample (Schedule op) | Adds jitter to a schedule's delay using a caller-supplied sample source. |
| union | Schedule.union other schedule | Continues while either schedule continues, waiting for the shorter of their delays. |
| intersect | Schedule.intersect other schedule | Continues while both schedules continue, waiting for the longer of their delays. |
| fixedRate | Schedule.fixedRate period | Recurs at a fixed rate aligned to when the first run began, emitting the recurrence count. |
| whileInput | Schedule.whileInput predicate (Schedule op) | Continues only while the input satisfies a predicate. |
| untilInput | Schedule.untilInput predicate schedule | Continues until the input satisfies a predicate. |
| recursAtMost | Schedule.recursAtMost n (Schedule op) | Stops a schedule after at most n recurrences, keeping its output and delays. |
| map | Schedule.map mapper (Schedule op) | Transforms a schedule's output, keeping its decisions and delays. |
| elapsed | Schedule.elapsed | Recurs forever without waiting, emitting the time elapsed since the first run began. |
| whileOutput | Schedule.whileOutput predicate (Schedule op) | Continues only while the schedule's output satisfies a predicate. |
| untilOutput | Schedule.untilOutput predicate schedule | Continues until the schedule's output satisfies a predicate. |
| upTo | Schedule.upTo budget (Schedule op) | Stops a schedule once budget has passed since the first run began. |
| andThen | Schedule.andThen next schedule | Runs schedule until it stops, then continues with next. |
| resetAfter | Schedule.resetAfter healthy (Schedule op) | Starts a schedule's count again after a run that lasted at least healthy. |
Operations
kind:member
Creates a schedule that recurs a fixed number of times.
Parameters
| Name | Type | Description |
|---|---|---|
| n | int | The maximum number of additional times to recur, on top of the source flow's one free initial attempt. |
Returns
Schedule<'env, 'input, int>
Verification Examples
let retryThreeTimes () = Schedule.recurs 3
// Flow.retry runs the source flow once for free, then consults the schedule at
// attempts 0, 1, 2 (three retries) before giving up: 4 executions in total.kind:member
Creates a schedule that recurs with a fixed delay between attempts.
Parameters
| Name | Type | Description |
|---|---|---|
| delay | TimeSpan | The fixed time span to wait between each attempt. |
Returns
Schedule<'env, 'input, int>
Verification Examples
let everySecond () = Schedule.spaced (TimeSpan.FromSeconds 1.0)kind:member
Creates a schedule that recurs with exponential backoff.
Parameters
| Name | Type | Description |
|---|---|---|
| baseDelay | TimeSpan | The initial delay for the first retry. |
Returns
Schedule<'env, 'input, TimeSpan>
Verification Examples
let backoff () = Schedule.exponential (TimeSpan.FromMilliseconds 100.0)
// Delays: 100ms, 200ms, 400ms, 800ms...kind:member
Adds jitter to a schedule's delay using a caller-supplied sample source.
Parameters
| Name | Type | Description |
|---|---|---|
| sample | unit -> float | A function returning a value in [0.0, 1.0), sampled once per attempt. Supply a deterministic function for reproducible schedules and tests. |
| Schedule op | Schedule<'env, 'input, 'output> |
Returns
Schedule<'env, 'input, 'output>
Verification Examples
let schedule = Schedule.spaced (TimeSpan.FromSeconds 1.0) |> Schedule.jitteredWith (fun () -> 0.25)
// Every delay becomes 750ms.kind:member
Continues while either schedule continues, waiting for the shorter of their delays.
Parameters
| Name | Type | Description |
|---|---|---|
| other | Schedule<'env, 'input, 'otherOutput> | The schedule combined with the piped-in schedule; its output is the second element. |
| schedule | Schedule<'env, 'input, 'output> | The piped-in schedule; its output is the first element. |
Returns
Schedule<'env, 'input, ('output option * 'otherOutput option)>
Verification Examples
// Exponential back-off capped at 30 s, retrying forever
Schedule.exponential (TimeSpan.FromMilliseconds 200.0)
|> Schedule.union (Schedule.spaced (TimeSpan.FromSeconds 30.0))kind:member
Continues while both schedules continue, waiting for the longer of their delays.
Parameters
| Name | Type | Description |
|---|---|---|
| other | Schedule<'env, 'input, 'otherOutput> | The schedule combined with the piped-in schedule; its output is the second element. |
| schedule | Schedule<'env, 'input, 'output> | The piped-in schedule; its output is the first element. |
Returns
Schedule<'env, 'input, ('output * 'otherOutput)>
Verification Examples
// At most 10 retries, with exponential back-off
Schedule.recurs 10
|> Schedule.intersect (Schedule.exponential (TimeSpan.FromMilliseconds 200.0))kind:member
Recurs at a fixed rate aligned to when the first run began, emitting the recurrence count.
Parameters
| Name | Type | Description |
|---|---|---|
| period | TimeSpan |
Returns
Schedule<'env, 'input, int>
Verification Examples
scanOnce |> Flow.repeat (Schedule.fixedRate (TimeSpan.FromMilliseconds 50.0))kind:member
Continues only while the input satisfies a predicate.
Parameters
| Name | Type | Description |
|---|---|---|
| predicate | 'input -> bool | Returns true for inputs that may recur. |
| Schedule op | Schedule<'env, 'input, 'output> |
Returns
Schedule<'env, 'input, 'output>
Verification Examples
Schedule.exponential (TimeSpan.FromMilliseconds 200.0)
|> Schedule.recursAtMost 3
|> Schedule.whileInput HttpError.isTransientkind:member
Continues until the input satisfies a predicate.
Parameters
| Name | Type | Description |
|---|---|---|
| predicate | 'input -> bool | Returns true for inputs that stop the schedule. |
| schedule | Schedule<'env, 'input, 'output> | The schedule consulted for other inputs. |
Returns
Schedule<'env, 'input, 'output>
kind:member
Stops a schedule after at most
n recurrences, keeping its output and delays.Parameters
| Name | Type | Description |
|---|---|---|
| n | int | The maximum number of recurrences. |
| Schedule op | Schedule<'env, 'input, 'output> |
Returns
Schedule<'env, 'input, 'output>
Verification Examples
Schedule.exponential (TimeSpan.FromMilliseconds 100.0) |> Schedule.recursAtMost 5kind:member
Transforms a schedule's output, keeping its decisions and delays.
Parameters
| Name | Type | Description |
|---|---|---|
| mapper | 'output -> 'next | Maps each output. |
| Schedule op | Schedule<'env, 'input, 'output> |
Returns
Schedule<'env, 'input, 'next>
Verification Examples
Schedule.exponential (TimeSpan.FromMilliseconds 100.0) |> Schedule.map (fun delay -> delay.TotalSeconds)kind:member
kind:member
Continues only while the schedule's output satisfies a predicate.
Parameters
| Name | Type | Description |
|---|---|---|
| predicate | 'output -> bool | Returns true for outputs that may recur. |
| Schedule op | Schedule<'env, 'input, 'output> |
Returns
Schedule<'env, 'input, 'output>
Verification Examples
// Back off exponentially, but stop once the delay would reach 30 seconds
Schedule.exponential (TimeSpan.FromMilliseconds 200.0)
|> Schedule.whileOutput (fun delay -> delay < TimeSpan.FromSeconds 30.0)kind:member
Continues until the schedule's output satisfies a predicate.
Parameters
| Name | Type | Description |
|---|---|---|
| predicate | 'output -> bool | Returns true for outputs that stop the schedule. |
| schedule | Schedule<'env, 'input, 'output> | The schedule whose output is checked. |
Returns
Schedule<'env, 'input, 'output>
kind:member
Stops a schedule once
budget has passed since the first run began.Parameters
| Name | Type | Description |
|---|---|---|
| budget | TimeSpan | The total time the schedule may keep recurring. |
| Schedule op | Schedule<'env, 'input, 'output> |
Returns
Schedule<'env, 'input, 'output>
Verification Examples
// Retry with backoff, but give up after two minutes in total
Schedule.exponential (TimeSpan.FromMilliseconds 200.0) |> Schedule.upTo (TimeSpan.FromMinutes 2.0)kind:member
Runs
schedule until it stops, then continues with next.Parameters
| Name | Type | Description |
|---|---|---|
| next | Schedule<'env, 'input, 'nextOutput> | The schedule that takes over once the first stops. |
| schedule | Schedule<'env, 'input, 'output> | The schedule that runs first. |
Returns
Schedule<'env, 'input, Choice<'output, 'nextOutput>>
Verification Examples
// Three quick retries, then slower ones
Schedule.spaced (TimeSpan.FromMilliseconds 100.0)
|> Schedule.recursAtMost 3
|> Schedule.andThen (Schedule.exponential (TimeSpan.FromSeconds 1.0) |> Schedule.recursAtMost 5)kind:member
Starts a schedule's count again after a run that lasted at least
healthy.Parameters
| Name | Type | Description |
|---|---|---|
| healthy | TimeSpan | How long a run must last for the count to restart. |
| Schedule op | Schedule<'env, 'input, 'output> |
Returns
Schedule<'env, 'input, 'output>
Verification Examples
worker |> Flow.supervise (Schedule.recurs 5 |> Schedule.resetAfter (TimeSpan.FromMinutes 10.0))
