Schedule (Retry & Repeat)
The Schedule module provides a powerful DSL for describing policies that govern how and when a workflow should be executed again. You can use schedules to implement sophisticated retry strategies (like exponential backoff with jitter) or recurring tasks.
Note:
Scheduleis currently available on .NET only.
Basic Schedules
A schedule decides two things:
- Whether to continue (recur).
- How long to wait before the next attempt.
Fixed Number of Recursions
// Recur 5 times (6 attempts total)
let fiveTimes = Schedule.recurs 5
Fixed Spacing
// Recur indefinitely with 1 second between attempts
let everySecond = Schedule.spaced (TimeSpan.FromSeconds 1.0)
Exponential Backoff
// Delays: 100ms, 200ms, 400ms, 800ms...
let backoff = Schedule.exponential (TimeSpan.FromMilliseconds 100.0)
Adding Jitter
Jitter adds randomness to delays to prevent “thundering herd” problems in distributed systems. Schedule.jittered adds a random factor between 0.5x and 1.5x to the current delay.
let policy =
Schedule.exponential (TimeSpan.FromMilliseconds 100.0)
|> Schedule.jittered
Retrying Failures
Use Flow.Retry to apply a schedule to a flow that might fail with an expected domain error (Cause.Fail).
Important: If the flow fails with a defect (Cause.Die) or is interrupted (Cause.Interrupt), it will not be retried. This ensures that logic errors and cancellation signals are respected immediately.
let unstableCall =
flow {
printfn "Attempting call..."
return! Flow.fail "temporary-error"
}
// This will attempt the call up to 4 times (initial + 3 retries)
let resilientCall =
Flow.Retry(unstableCall, Schedule.recurs 3)
Repeating Successes
Use Flow.Repeat to execute a successful flow again. This is useful for polling, heartbeats, or recurring background tasks.
let pollStatus =
flow {
printfn "Polling status..."
return "Still working"
}
// This will poll every 5 seconds until it fails or is cancelled
let recurringPoll =
Flow.Repeat(pollStatus, Schedule.spaced (TimeSpan.FromSeconds 5.0))
API Reference: Module Schedule
| Function | Signature | Description |
|---|---|---|
recurs |
int -> Schedule<'env, 'i, int> |
Recurs exactly n times. The output value is the attempt index. |
spaced |
TimeSpan -> Schedule<'env, 'i, int> |
Recurs indefinitely with a fixed delay. |
exponential |
TimeSpan -> Schedule<'env, 'i, TimeSpan> |
Recurs indefinitely with doubling delays. |
jittered |
Schedule<'env, 'i, 'o> -> Schedule<'env, 'i, 'o> |
Wraps a schedule to add random jitter (0.5x to 1.5x). |
API Reference: Flow Extensions
| Function | Signature | Description |
|---|---|---|
Flow.Retry |
Flow<'e, 'err, 'v> * Schedule<'e, 'err, 'o> -> Flow<'e, 'err, 'v> |
Retries the flow on Cause.Fail. |
Flow.Repeat |
Flow<'e, 'err, 'v> * Schedule<'e, 'v, 'o> -> Flow<'e, 'err, 'v> |
Repeats the flow on success. |