Hyperlinkv0.8.0-beta.28

Polling

Polling.backoffconstsrc/Polling.ts:234
(options: {
  readonly initial: Duration.Input
  readonly max: Duration.Input
  readonly factor?: number
}): Layer.Layer<PollingTag>

Exponential backoff: starts at initial, doubles (or multiplies by factor) each tick, caps at max. resetCadence resets to initial.

presets
Source src/Polling.ts:23457 lines
export const backoff = (options: {
  readonly initial: Duration.Input;
  readonly max: Duration.Input;
  readonly factor?: number;
}): Layer.Layer<PollingTag> => {
  const initialMs = Duration.toMillis(
    Duration.fromInputUnsafe(options.initial)
  );
  const maxMs = Duration.toMillis(Duration.fromInputUnsafe(options.max));
  const factor = options.factor ?? 2;

  return registerPollingLayer(
    Layer.effect(
      PollingTag,
      Effect.gen(function* () {
        const currentMs = yield* Ref.make(initialMs);
        const wakeRef = yield* Ref.make<Deferred.Deferred<void, never>>(
          Deferred.makeUnsafe()
        );

        const awaitNextTick: Effect.Effect<void> = Effect.gen(function* () {
          const d = Deferred.makeUnsafe<void, never>();
          yield* Ref.set(wakeRef, d);
          const ms = yield* Ref.get(currentMs);
          yield* Effect.race(
            Effect.sleep(Duration.millis(ms)),
            Deferred.await(d)
          ).pipe(Effect.asVoid);
        });

        const requestWake = Effect.flatMap(Ref.get(wakeRef), (d) =>
          Deferred.succeed(d, undefined)
        ).pipe(Effect.asVoid);

        const afterTick = Ref.update(currentMs, (ms) =>
          Math.min(ms * factor, maxMs)
        );

        const resetCadence = Ref.set(currentMs, initialMs).pipe(
          Effect.andThen(requestWake)
        );

        const peekCadence = Effect.map(Ref.get(currentMs), (ms) =>
          Option.some(Duration.millis(ms))
        );

        return {
          awaitNextTick,
          requestWake,
          resetCadence,
          afterTick,
          peekCadence,
        } satisfies PollingService;
      })
    )
  );
};