ScheduleUnion

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.

Specification

Kind
Union
Members
17
Examples
0
recursSignature
Schedule.recurs n
spacedSignature
Schedule.spaced delay
exponentialSignature
Schedule.exponential baseDelay
jitteredWithSignature
Schedule.jitteredWith sample (Schedule op)
unionSignature
Schedule.union other schedule

Summary

NameSignatureSynopsis
Operations
recursSchedule.recurs nCreates a schedule that recurs a fixed number of times.
spacedSchedule.spaced delayCreates a schedule that recurs with a fixed delay between attempts.
exponentialSchedule.exponential baseDelayCreates a schedule that recurs with exponential backoff.
jitteredWithSchedule.jitteredWith sample (Schedule op)Adds jitter to a schedule's delay using a caller-supplied sample source.
unionSchedule.union other scheduleContinues while either schedule continues, waiting for the shorter of their delays.
intersectSchedule.intersect other scheduleContinues while both schedules continue, waiting for the longer of their delays.
fixedRateSchedule.fixedRate periodRecurs at a fixed rate aligned to when the first run began, emitting the recurrence count.
whileInputSchedule.whileInput predicate (Schedule op)Continues only while the input satisfies a predicate.
untilInputSchedule.untilInput predicate scheduleContinues until the input satisfies a predicate.
recursAtMostSchedule.recursAtMost n (Schedule op)Stops a schedule after at most n recurrences, keeping its output and delays.
mapSchedule.map mapper (Schedule op)Transforms a schedule's output, keeping its decisions and delays.
elapsedSchedule.elapsed Recurs forever without waiting, emitting the time elapsed since the first run began.
whileOutputSchedule.whileOutput predicate (Schedule op)Continues only while the schedule's output satisfies a predicate.
untilOutputSchedule.untilOutput predicate scheduleContinues until the schedule's output satisfies a predicate.
upToSchedule.upTo budget (Schedule op)Stops a schedule once budget has passed since the first run began.
andThenSchedule.andThen next scheduleRuns schedule until it stops, then continues with next.
resetAfterSchedule.resetAfter healthy (Schedule op)Starts a schedule's count again after a run that lasted at least healthy.

Operations

kind:member

recurs

Schedule.recurs n
Member
Creates a schedule that recurs a fixed number of times.

Parameters

NameTypeDescription
nintThe 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

spaced

Schedule.spaced delay
Member
Creates a schedule that recurs with a fixed delay between attempts.

Parameters

NameTypeDescription
delayTimeSpanThe 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

exponential

Schedule.exponential baseDelay
Member
Creates a schedule that recurs with exponential backoff.

Parameters

NameTypeDescription
baseDelayTimeSpanThe 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

jitteredWith

Schedule.jitteredWith sample (Schedule op)
Member
Adds jitter to a schedule's delay using a caller-supplied sample source.

Parameters

NameTypeDescription
sampleunit -> floatA function returning a value in [0.0, 1.0), sampled once per attempt. Supply a deterministic function for reproducible schedules and tests.
Schedule opSchedule<'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

union

Schedule.union other schedule
Member
Continues while either schedule continues, waiting for the shorter of their delays.

Parameters

NameTypeDescription
otherSchedule<'env, 'input, 'otherOutput>The schedule combined with the piped-in schedule; its output is the second element.
scheduleSchedule<'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

intersect

Schedule.intersect other schedule
Member
Continues while both schedules continue, waiting for the longer of their delays.

Parameters

NameTypeDescription
otherSchedule<'env, 'input, 'otherOutput>The schedule combined with the piped-in schedule; its output is the second element.
scheduleSchedule<'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

fixedRate

Schedule.fixedRate period
Member
Recurs at a fixed rate aligned to when the first run began, emitting the recurrence count.

Parameters

NameTypeDescription
periodTimeSpan

Returns

Schedule<'env, 'input, int>

Verification Examples

scanOnce |> Flow.repeat (Schedule.fixedRate (TimeSpan.FromMilliseconds 50.0))
kind:member

whileInput

Schedule.whileInput predicate (Schedule op)
Member
Continues only while the input satisfies a predicate.

Parameters

NameTypeDescription
predicate'input -> boolReturns true for inputs that may recur.
Schedule opSchedule<'env, 'input, 'output>

Returns

Schedule<'env, 'input, 'output>

Verification Examples

Schedule.exponential (TimeSpan.FromMilliseconds 200.0)
|> Schedule.recursAtMost 3
|> Schedule.whileInput HttpError.isTransient
kind:member

untilInput

Schedule.untilInput predicate schedule
Member
Continues until the input satisfies a predicate.

Parameters

NameTypeDescription
predicate'input -> boolReturns true for inputs that stop the schedule.
scheduleSchedule<'env, 'input, 'output>The schedule consulted for other inputs.

Returns

Schedule<'env, 'input, 'output>
kind:member

recursAtMost

Schedule.recursAtMost n (Schedule op)
Member
Stops a schedule after at most n recurrences, keeping its output and delays.

Parameters

NameTypeDescription
nintThe maximum number of recurrences.
Schedule opSchedule<'env, 'input, 'output>

Returns

Schedule<'env, 'input, 'output>

Verification Examples

Schedule.exponential (TimeSpan.FromMilliseconds 100.0) |> Schedule.recursAtMost 5
kind:member

map

Schedule.map mapper (Schedule op)
Member
Transforms a schedule's output, keeping its decisions and delays.

Parameters

NameTypeDescription
mapper'output -> 'nextMaps each output.
Schedule opSchedule<'env, 'input, 'output>

Returns

Schedule<'env, 'input, 'next>

Verification Examples

Schedule.exponential (TimeSpan.FromMilliseconds 100.0) |> Schedule.map (fun delay -> delay.TotalSeconds)
kind:member

elapsed

Schedule.elapsed
Member
Recurs forever without waiting, emitting the time elapsed since the first run began.

Returns

Schedule<'env, 'input, TimeSpan>

Verification Examples

Schedule.elapsed |> Schedule.whileOutput (fun elapsed -> elapsed < TimeSpan.FromMinutes 2.0)
kind:member

whileOutput

Schedule.whileOutput predicate (Schedule op)
Member
Continues only while the schedule's output satisfies a predicate.

Parameters

NameTypeDescription
predicate'output -> boolReturns true for outputs that may recur.
Schedule opSchedule<'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

untilOutput

Schedule.untilOutput predicate schedule
Member
Continues until the schedule's output satisfies a predicate.

Parameters

NameTypeDescription
predicate'output -> boolReturns true for outputs that stop the schedule.
scheduleSchedule<'env, 'input, 'output>The schedule whose output is checked.

Returns

Schedule<'env, 'input, 'output>
kind:member

upTo

Schedule.upTo budget (Schedule op)
Member
Stops a schedule once budget has passed since the first run began.

Parameters

NameTypeDescription
budgetTimeSpanThe total time the schedule may keep recurring.
Schedule opSchedule<'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

andThen

Schedule.andThen next schedule
Member
Runs schedule until it stops, then continues with next.

Parameters

NameTypeDescription
nextSchedule<'env, 'input, 'nextOutput>The schedule that takes over once the first stops.
scheduleSchedule<'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

resetAfter

Schedule.resetAfter healthy (Schedule op)
Member
Starts a schedule's count again after a run that lasted at least healthy.

Parameters

NameTypeDescription
healthyTimeSpanHow long a run must last for the count to restart.
Schedule opSchedule<'env, 'input, 'output>

Returns

Schedule<'env, 'input, 'output>

Verification Examples

worker |> Flow.supervise (Schedule.recurs 5 |> Schedule.resetAfter (TimeSpan.FromMinutes 10.0))