Hyperlinkv0.8.0-beta.28

Schedule

Schedule.maxconsteffect/Schedule.ts:794
<
  const Schedules extends NonEmptyReadonlyArray<
    Schedule<any, any, any, any>
  >
>(
  schedules: Schedules
): Schedule<
  Duration.Duration,
  UnionToIntersection<Input<Schedules[number]>>,
  Error<Schedules[number]>,
  Env<Schedules[number]>
>

Combines schedules by recurring while all schedules want to recur, using the maximum delay between recurrences and outputting that maximum delay.

When to use

Use when a combined policy should continue only while every schedule still recurs, and should wait for the slowest schedule between recurrences.

Example (Combining retry schedules by their maximum delay)

import { Console, Data, Effect, Schedule } from "effect"

class RetryAttemptError extends Data.TaggedError("RetryAttemptError")<{ readonly message: string }> {}

const retrySchedule = Schedule.max([
  Schedule.fixed("5 seconds"),
  Schedule.exponential("5 seconds"),
  Schedule.spaced("10 seconds")
])

const program = Effect.gen(function*() {
  let attempt = 0

  yield* Effect.retry(
    Effect.gen(function*() {
      attempt++
      yield* Console.log(`Retry attempt ${attempt}`)
      if (attempt < 3) {
        return yield* Effect.fail(new RetryAttemptError({ message: `Attempt ${attempt} failed` }))
      }
      return "success"
    }),
    retrySchedule.pipe(
      Schedule.tap(({ output: duration }) =>
        Console.log(`Waiting for the slowest schedule: ${duration}`)
      )
    )
  )
})
combining
Source effect/Schedule.ts:79433 lines
export const max = <
  const Schedules extends NonEmptyReadonlyArray<
    Schedule<any, any, any, any>
  >
>(
  schedules: Schedules
): Schedule<
  Duration.Duration,
  UnionToIntersection<
    Input<Schedules[number]>
  >,
  Error<Schedules[number]>,
  Env<Schedules[number]>
> =>
  fromStep(effect.map(
    effect.all(schedules.map(toStep)),
    (steps) => (now, input) =>
      effect.flatMap(
        effect.forEach(steps, (step) =>
          Pull.matchEffect(step(now, input as never), {
            onSuccess: (result) => effect.succeed(result[1]),
            onDone: () => effect.undefined,
            onFailure: effect.failCause
          })),
        (results) => {
          const duration = maxDuration(results)
          if (duration === undefined) {
            return Cause.done(Duration.zero)
          }
          return effect.succeed([duration, duration] as [Duration.Duration, Duration.Duration])
        }
      )
  ))