Last active
August 22, 2022 02:52
-
-
Save M1kep/693fa05df28c60d1c7e1d57e010490b7 to your computer and use it in GitHub Desktop.
TypeScript/Node Background task handler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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