MCPcopy Index your code
hub / github.com/codeaashu/claude-code / oneShotJitteredNextCronRunMs

Function oneShotJitteredNextCronRunMs

src/utils/cronTasks.ts:421–445  ·  view source on GitHub ↗
(
  cron: string,
  fromMs: number,
  taskId: string,
  cfg: CronJitterConfig = DEFAULT_CRON_JITTER_CONFIG,
)

Source from the content-addressed store, hash-verified

419 * inside its own jitter window doesn't fire before it was created.
420 */
421export function oneShotJitteredNextCronRunMs(
422 cron: string,
423 fromMs: number,
424 taskId: string,
425 cfg: CronJitterConfig = DEFAULT_CRON_JITTER_CONFIG,
426): number | null {
427 const t1 = nextCronRunMs(cron, fromMs)
428 if (t1 === null) return null
429 // Cron resolution is 1 minute → computed times always have :00 seconds,
430 // so a minute-field check is sufficient to identify the hot marks.
431 // getMinutes() (local), not getUTCMinutes(): cron is evaluated in local
432 // time, and "user picked a round time" means round in *their* TZ. In
433 // half-hour-offset zones (India UTC+5:30) local :00 is UTC :30 — the
434 // UTC check would jitter the wrong marks.
435 if (new Date(t1).getMinutes() % cfg.oneShotMinuteMod !== 0) return t1
436 // floor + frac * (max - floor) → uniform over [floor, max). With floor=0
437 // this reduces to the original frac * max. With floor>0, even a taskId
438 // hashing to 0 gets `floor` ms of lead — nobody fires on the exact mark.
439 const lead =
440 cfg.oneShotFloorMs +
441 jitterFrac(taskId) * (cfg.oneShotMaxMs - cfg.oneShotFloorMs)
442 // t1 > fromMs is guaranteed by nextCronRunMs (strictly after), so the
443 // max() only bites when the task was created inside its own lead window.
444 return Math.max(t1 - lead, fromMs)
445}
446
447/**
448 * A task is "missed" when its next scheduled run (computed from createdAt)

Callers 1

processFunction · 0.85

Calls 3

nextCronRunMsFunction · 0.85
jitterFracFunction · 0.85
maxMethod · 0.80

Tested by

no test coverage detected