Hyperlinkv0.8.0-beta.28

Polling

Polling.acceleratingWithRefsconstsrc/Polling.ts:428
(options: {
  readonly config: Ref.Ref<{
    minIntervalMs: number
    maxIntervalMs: number
    decayK: number
  }>
  readonly iteration: Ref.Ref<number>
  readonly excitement: Ref.Ref<number>
}): Layer.Layer<PollingTag>

Accelerating cadence with externally-managed refs for live tuning. Prefer accelerating unless you need runtime parameter changes via refs.

Source src/Polling.ts:42877 lines
export const acceleratingWithRefs = (options: {
  readonly config: Ref.Ref<{
    minIntervalMs: number;
    maxIntervalMs: number;
    decayK: number;
  }>;
  readonly iteration: Ref.Ref<number>;
  readonly excitement: Ref.Ref<number>;
}): Layer.Layer<PollingTag> =>
  registerPollingLayer(
    Layer.effect(
      PollingTag,
      Effect.gen(function* () {
        const {
          config: configRef,
          iteration: iterationRef,
          excitement: excRef,
        } = options;
        const wakeRef = yield* Ref.make<Deferred.Deferred<void, never>>(
          Deferred.makeUnsafe()
        );

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

        const awaitNextTick: Effect.Effect<void> = Effect.gen(function* () {
          const d = Deferred.makeUnsafe<void, never>();
          yield* Ref.set(wakeRef, d);
          const n = yield* Ref.get(iterationRef);
          const cfg = yield* Ref.get(configRef);
          const exc = yield* Ref.get(excRef);
          const ms = delayMsForIteration(
            cfg.minIntervalMs,
            cfg.maxIntervalMs,
            cfg.decayK,
            exc,
            n
          );
          yield* Effect.race(
            Effect.sleep(Duration.millis(ms)),
            Deferred.await(d)
          ).pipe(Effect.asVoid);
        });

        const resetCadence = Ref.set(iterationRef, 0).pipe(
          Effect.andThen(requestWake)
        );
        const afterTick = Ref.update(iterationRef, (n) => n + 1);

        const peekCadence = Effect.gen(function* () {
          const n = yield* Ref.get(iterationRef);
          const cfg = yield* Ref.get(configRef);
          const exc = yield* Ref.get(excRef);
          return Option.some(
            Duration.millis(
              delayMsForIteration(
                cfg.minIntervalMs,
                cfg.maxIntervalMs,
                cfg.decayK,
                exc,
                n
              )
            )
          );
        });

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