Skip to content

Instantly share code, notes, and snippets.

@M1kep
Last active August 22, 2022 02:52
Show Gist options
  • Save M1kep/693fa05df28c60d1c7e1d57e010490b7 to your computer and use it in GitHub Desktop.
Save M1kep/693fa05df28c60d1c7e1d57e010490b7 to your computer and use it in GitHub Desktop.
TypeScript/Node Background task handler
export class BackgroundHandler {
#tasks: Record<
string,
{
task: () => void;
timer: ReturnType<typeof setTimeout>;
isPaused: boolean;
}
> = {};
/**
* Calls the provided task callback and then schedules itself(#loop) to be called again after the provided interval.
* @param taskName The name of the task to loop.
* @param task The task to be called.
* @param interval The interval to wait before calling the task again in milliseconds.
* @private
*/
#loop(taskName: string, task: () => void, interval: number) {
task();
this.#tasks[taskName].timer = setTimeout(
() => this.#loop(taskName, task, interval),
interval,
);
}
/**
* Registers a task with the {@link BackgroundHandler} and starts it after the provided interval.
* @param taskName The name of the task to register.
* @param task The task to be called.
* @param interval The interval to wait between calls to the task in milliseconds.
*/
registerTask(taskName: string, task: () => void, interval: number) {
if (taskName in this.#tasks) {
throw new Error(`Task ${taskName} already registered.`);
}
this.#tasks[taskName] = {
task,
timer: setTimeout(() => this.#loop(taskName, task, interval), interval),
isPaused: false,
};
}
/**
* Calls clearTimeout on the timer associated with the task.
* @param taskName The name of the task to pause.
*/
pauseTask(taskName: string) {
if (!(taskName in this.#tasks)) {
return;
}
clearTimeout(this.#tasks[taskName].timer);
this.#tasks[taskName].isPaused = true;
}
/**
* Immediately calls the callback associated with {@link taskName} and will continue to be called until {@link unregisterTask} or {@link pauseTask} is called.
* @param taskName The name of the task to resume.
*/
resumeTask(taskName: string) {
if (!(taskName in this.#tasks)) {
console.warn(`Task ${taskName} not found.`);
return;
}
if (this.#tasks[taskName].isPaused) {
this.#tasks[taskName].isPaused = false;
this.#tasks[taskName].timer = setTimeout(
() => this.#loop(taskName, this.#tasks[taskName].task, 0),
0,
);
} else {
console.warn(`Task ${taskName} is not paused. Ignoring call.`);
}
}
/**
* Calls clearTimeout on the timer associated with the task and removes the task from the list of registered tasks.
* @param taskName The name of the task to unregister.
*/
unregisterTask(taskName: string) {
if (!(taskName in this.#tasks)) {
return;
}
clearTimeout(this.#tasks[taskName].timer);
delete this.#tasks[taskName];
}
/**
* Calls clearTimeout on all timers associated with registered tasks.
*/
killAllTasks() {
for (const taskName in this.#tasks) {
if (this.#tasks[taskName] !== undefined) {
clearTimeout(this.#tasks[taskName].timer);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment