| title |
Your First Schedule |
| id |
scheduling-hello-world |
| skillLevel |
beginner |
| applicationPatternId |
scheduling |
| summary |
Learn the basics of scheduling in Effect - retry operations and repeat them on intervals. |
| tags |
scheduling |
retry |
repeat |
getting-started |
|
| rule |
| description |
Use Schedule to control when and how often effects run. |
|
| author |
PaulJPhilp |
| related |
scheduling-repeat-interval |
scheduling-exponential-backoff |
|
| lessonOrder |
2 |
Use Schedule to control timing in Effect programs - retrying failed operations, repeating successful ones, or adding delays.
Schedules solve common timing problems:
- Retries - Try again after failures
- Polling - Check for updates periodically
- Rate limiting - Control how fast things run
- Backoff - Increase delays between attempts
import { Effect, Schedule } from "effect"
// ============================================
// 1. Retry a failing operation
// ============================================
let attempts = 0
const flakyOperation = Effect.gen(function* () {
attempts++
if (attempts < 3) {
yield* Effect.log(`Attempt ${attempts} failed`)
return yield* Effect.fail(new Error("Temporary failure"))
}
return `Success on attempt ${attempts}`
})
// Retry up to 5 times
const withRetry = flakyOperation.pipe(
Effect.retry(Schedule.recurs(5))
)
// ============================================
// 2. Repeat a successful operation
// ============================================
const logTime = Effect.gen(function* () {
const now = new Date().toISOString()
yield* Effect.log(`Current time: ${now}`)
return now
})
// Repeat 3 times
const repeated = logTime.pipe(
Effect.repeat(Schedule.recurs(3))
)
// ============================================
// 3. Add delays between operations
// ============================================
// Repeat every second, 5 times
const polling = logTime.pipe(
Effect.repeat(
Schedule.spaced("1 second").pipe(
Schedule.intersect(Schedule.recurs(5))
)
)
)
// ============================================
// 4. Common schedule patterns
// ============================================
// Fixed delay between attempts
const fixedDelay = Schedule.spaced("500 millis")
// Increasing delay (1s, 2s, 4s, 8s...)
const exponentialBackoff = Schedule.exponential("1 second")
// Maximum number of attempts
const limitedAttempts = Schedule.recurs(3)
// Combine: exponential backoff, max 5 attempts
const retryPolicy = Schedule.exponential("100 millis").pipe(
Schedule.intersect(Schedule.recurs(5))
)
// ============================================
// 5. Run examples
// ============================================
const program = Effect.gen(function* () {
yield* Effect.log("--- Retry Example ---")
const result = yield* withRetry
yield* Effect.log(`Result: ${result}`)
yield* Effect.log("\n--- Repeat Example ---")
yield* repeated
})
Effect.runPromise(program)
| Schedule |
What It Does |
Schedule.recurs(n) |
Run at most n times |
Schedule.spaced(duration) |
Wait duration between runs |
Schedule.exponential(base) |
Double the delay each time |
Schedule.forever |
Run indefinitely |
Schedule.once |
Run exactly once |
| Combinator |
Meaning |
intersect |
Both conditions must be true |
union |
Either condition can be true |
andThen |
First schedule, then second |
- Retries - Network requests, database connections
- Polling - Check for job completion
- Rate limiting - API call quotas
- Periodic tasks - Health checks, cache refresh