Skip to content
Source
Sign inSign up

DueHint.ts

30 lines1.0 KB

1import * as Effect from "effect/Effect";
2​
3// Backstop for a write path that forgets to invalidate; the tick still runs every few seconds.
4const DUE_HINT_MAX_AGE_MS = 10 * 60 * 1_000;
5​
6/**
7 * Remembers when a poller next has work so idle scheduler ticks skip SQL.
8 * `invalidate` after every write that can move work earlier; a tick records
9 * only if no write happened since it read `version`.
10 */
11export const make = () => {
12 let version = 0;
13 let hint: { readonly dueAtMs: number; readonly checkedAtMs: number } | null = null;
14 return {
15 invalidate: Effect.sync(() => {
16 version++;
17 hint = null;
18 }),
19 version: Effect.sync(() => version),
20 isIdle: (nowMs: number) =>
21 Effect.sync(
22 () =>
23 hint !== null && hint.dueAtMs > nowMs && nowMs - hint.checkedAtMs < DUE_HINT_MAX_AGE_MS,
24 ),
25 record: (readVersion: number, dueAtMs: number, nowMs: number) =>
26 Effect.sync(() => {
27 if (readVersion === version) hint = { dueAtMs, checkedAtMs: nowMs };
28 }),
29 };
30};