1.0.0 • Published 1 year ago

uniform-scheduler v1.0.0

Weekly downloads
-
License
ISC
Repository
gitlab
Last release
1 year ago

Uniform Scheduler

Latest Release pipeline status coverage report

Schedules dynamic number of similar tasks uniformly in time.

Check out an interactive demo.

Installation

Requires Node >= 20.

npm i uniform-scheduler

Usage

import { UniformScheduler } from 'uniform-scheduler';

/** Returns a promise that resolves after `duration` amount of milliseconds */
declare const sleep: (duration: number) => Promise<void>;

const scheduler = new UniformScheduler(100 /* minInterval, ms */);

const taskA = () => { console.log('task A called'); };
const taskB = () => { console.log('task B called'); };

                             /* Time(ms):                                                          */
scheduler.addTask(taskA);    /* =>   0| task A called                                              */
await sleep(225);            /*     25|                                                            */
                             /*     50|                                                            */
                             /*     75|                                                            */
                             /*    100| task A called                                              */
                             /*       |                                                            */
                             /*       |                                                            */
                             /*       |                                                            */
                             /*    200| task A called                                              */
scheduler.addTask(taskB);    /* => 225|                                                            */
await sleep(150);            /*    250| task B called                                              */
                             /*       |                                                            */
                             /*    300| task A called, minInterval = 100ms for task A is preserved */
                             /*       |                                                            */
                             /*    350| task B called, 2 tasks are now spread uniformly in time    */
scheduler.removeTask(taskA); /* => 375|                                                            */
await sleep(100);            /*    400| task A would've been called but was just removed           */
                             /*       |                                                            */
                             /*    450| task B called, minInterval for task B still preserved      */
scheduler.stop();            /* => 475| scheduler stopped, no tasks will be called anymore         */

Q&A

Q: Why is this useful?

A: One case I could think of is a web scraper that needs a low refresh latency.

Q: My tasks are drifting. The task that was supposed to run at t=250ms actually ran at t=251ms

A: The scheduler uses setTimeout under the hood. And just like setTimeout, it is a best-effort API. The scheduler only calculates the time when a task is supposed to be run and then passes it to setTimeout without doing any additional event loop magic. Consequently, +-1ms drift is common.

1.0.0

1 year ago

0.2.1

1 year ago

0.2.0

1 year ago

0.1.0

1 year ago