inSlices

tcmts.share.inSlices · #6ccb5z4y · term · runs on the server

uses setImmediate

Run steps in turn, letting other work run every slice milliseconds, so what a page or the warm-up makes in bulk doesn't hold up the pages asked for meanwhile; in the background, it waits while a page is making something. It stops when go says to; whether it finished.

import { pagesWorking } from "#codebase/tcmts/share";

export async function inSlices(
  steps: Iterable<() => unknown>,
  go: () => boolean = () => true,
  o: { slice?: number; background?: boolean } = {},
): Promise<boolean> {
  const slice = o.slice ?? 10;
  if (!o.background) pagesWorking.n++;
  try {
    let since = performance.now();
    for (const step of steps) {
      if (performance.now() - since > slice) {
        await new Promise((r) => setImmediate(r));
        while (o.background && pagesWorking.n > 0) await new Promise((r) => setTimeout(r, 5));
        if (!go()) return false;
        since = performance.now();
      }
      step();
    }
    return true;
  } finally {
    if (!o.background) pagesWorking.n--;
  }
}

uses

used by