als-task-manager
v3.2.0
Published
A simple and efficient task manager to prioritize, limit, and manage concurrent tasks.
Downloads
8
Maintainers
Readme
als-TaskManager
A simple and efficient task manager to prioritize, limit, and manage concurrent tasks and task groups.
Installation and import
npm install als-task-manager
Use as common js:
const {Task,TaskManager,TaskGroup} = require('als-task-manager');
Use as module:
import {Task,TaskManager,TaskGroup} from 'als-task-manager/taskManager.mjs'
Use in browser as module:
import {Task,TaskManager,TaskGroup} from '/node_modules/als-task-manager/taskManager.mjs'
Use as script in browser:
<script src="/node_modules/als-event-emitter/index.js"></script>
<script src="/node_modules/als-time-manager/time-manager.js"></script>
<script src="/node_modules/als-task-manager/taskManager.js"></script>
<script>
const {Task,TaskManager,TaskGroup} = taskManager
</script>
TaskManager Constructor
const options = {
taskTimeout: 20 * 1000, // time threshold for each task (undefined by default)
maxParallelTasks: 1, // Maximum parallel tasks (1 by default)
priorities:[], // keys for priorities ['a','b','c','d','e'] by default
}
const taskManager = new TaskManager(options)
Parameters
maxParallelTasks
: Maximum number of tasks that can run at the same time. Default is 1.taskTimeout
: Maximum time in milliseconds a task is allowed to run. If this time is exceeded, the task is terminated. Default is no limit.priorities
: array of priority names. Default is['a','b','c','d','e']
.
newTask
and runTask
method
Syntax:
taskManager.newTask(fn:Function,options={}:Object):instanceof Task
taskManager.runTask(fn:Function,options={}:Object):instanceof Task
runTask
- Creates a new task and immediately tries to run it.newTask
- Creates a new task but doesn't run it immediately.
Parameters:
fn
: The function to be executed.options
priority
: The priority of the task. Can be one of'a'
,'b'
,'c'
,'d'
,'e'
. Tasks with priority 'a' are executed first. Default is 'e'.timeout
: Timeout for task.Number
for amount of miliseconds, orString
, for formatd:h:m:s.ms
. Default isundefined
.retryAttempts
: You can define amount of ettempts in case of error. Default is 1.id
: custrom id for task if needed
The method returns an object which is instance of Task
- Task api further.
Event Emitter
TaskManager has emitter taskManager.emitter
which emits folowing events:
idle
: Emitted when no more tasks to executepause
: Emitted when TaskManager pausedresume
: Emitted when TaskManager resumederror
: Emitted when last task not ends aftertaskManager.waitForLast
(30 second by default)task:start
: Emitted when every task starts.task:result
: Emitted when every task completes successfully.task:error
: Emitted when every task encounters an error.task:done
: Emitted when every task is done (either successfully or with an error).task:cancel
: Emitted when every task is cancelled.task:pause
: Emitted when every task is paused.task:resume
: Emitted when every task is resumed.task:timeout
: Emitted when every task times out.task:restart
: Emitted when every task restarts.
The emitter has methods: on
,once
,off
,has
,... For more information look fro als-event-emitter
.
Example:
manager.emitter.on('task:start', (task) => {
console.log(`Task with ID ${task.id} has started`);
});
Task timeout and waitForLast = '0:0:0:30'
taskManager
instance has waitForLast property, which is by default equals to '0:0:0:30'
(30 seconds).
This property is a time which task manager will wait for executing last task and then will emit error
event.
Pause and resume methods
You can pause task manager from executing next tasks or resume it.
Then task manager paused, property paused = true
.
Important! pause will not stop tasks which allready running.
taskManager.pause() // Don't execute next tasks
console.log(taskManager.paused) // true
taskManager.resume() // Execute next tasks
console.log(taskManager.paused) // false
addGroup
method
Syntax:
const taskGroup = taskManager.addGroup({
priority = 'e', // priority for all tasks
maxTasks=1000, // maximum tasks to execute, each task after maxTasks, will be not added to taskManager
maxParallelTasks = 1, // maximum parallel tasks (limited with maxParallelTasks of taskManager)
retryAttempts=1, // amount of attempts to retry in case of error for taskGroup
taskTimeout=undefined // timeout for each task in task group
}):instanceof TaskGroup
addGroup
method adding task group which has common options like priority
,maxParallelTasks
,retryAttempts
,taskTimeout
and events and wait till all tasks in a group done. Also it has limit for amount of tasks which can be executed.
The method returns the object which is instance of TaskGroup
class. Look for TaskGroup api
furhter.
Stop method
stop
method canceling all tasks and cancel timeout for last task.
taskManager.stop()
Task class api
The Task
class provides a convenient way to manage asynchronous tasks with built-in retry attempts, timeout management, and event-driven callbacks.
Class Properties
emitter
: An instance of the EventEmitter. It is used to emit and listen to events based on the task's lifecycle.state
: Represents the current state of the task. Possible states are 0-INIT, 1-STARTED, 2-RESULT, 3-ERROR.paused
: Boolean indicating whether the task is paused or not.id
: "unique id" (task counter number from 1 to 1000000000)finished
: promise which will be resolved on result or on error
Constructor
constructor(fn, {timeout, retryAttempts = 1, id})
fn
: The function to run. Must be of type function.timeout
: The time duration (in milliseconds) after which the task should be considered timed out.retryAttempts
: The number of times the function should retry on failure. Defaults to 1.id
: custom id for task
Creating a New Task example
const task = new Task(async () => {
// Some asynchronous operation
const data = await fetchDataFromAPI();
return data;
}, {timeout:5000, retryAttempts:2});
Methods
run()
An asynchronous method to initiate the execution of the task. If the task is not in the INIT state or is paused, it won't start. This method will automatically manage retry attempts and handle timeouts.
cancel()
task.cancel()
emits cancel
event and sets task.cancelled = true
. Also, it's resolving promise by emitting done
event.
It can't cancel function execution if it's allready started. But prevent task from running.
If task has few attempts, cancel will stop retrying.
Cancelling a Task example
task.cancel();
By calling the cancel method, you can cancel the task if it's not already started.
restart()
task.restart()
, return task to init state. It does:
- reseting currentAttempts to 0
- reseting timout
- reseting state to 0
- emitting
restart
event
If function allready executed, it can't stop it. But finished
promise will not be resolved if it's finished.
If task has few attempts, cancel will stop retrying.
pause()
and resume()
pause()
- Pause the task if it is not already running.resume()
- Resume the paused task. If the task had a timeout set, the timer will be reset.
Pausing and Resuming a Task Exampe
// Pause the task
task.pause();
// Later... resume the task
task.resume();
Here, we're pausing the task and resuming it later. This can be useful in scenarios where you want to temporarily halt the task's execution and resume it based on certain conditions.
Event Handling
The Task
class heavily relies on events. You can listen to these events using the emitter
property:
start
: Emitted when the task starts.result
: Emitted when the task completes successfully.error
: Emitted when the task encounters an error.done
: Emitted when the task is done (either successfully or with an error).cancel
: Emitted when the task is cancelled.pause
: Emitted when the task is paused.resume
: Emitted when the task is resumed.timeout
: Emitted when the task times out.
Handling Task Events example
task.emitter.on('start', () => {
console.log('Task has started');
});
task.emitter.on('result', (result) => {
console.log('Task completed with result:', result);
});
task.emitter.on('error', (error) => {
console.error('Task encountered an error:', error);
});
task.emitter.on('timeout', () => {
console.error('Task timed out');
});
task.run();
In this example, we're listening to various events of the task and logging appropriate messages based on the event.
TaskGroup class api
The TaskGroup
class is designed to handle and manage groups of tasks. It allows for grouping tasks and managing them as a single unit within the broader context of the TaskManager
.
Class Properties
- running: Count of tasks that are currently running.
- paused: Boolean indicating if the task group is currently paused.
- done: Count of tasks that have completed.
- queue: A Set containing tasks that are waiting to be executed.
- priority: Task priority level.
- maxTasks: Maximum number of tasks allowed in the group.
- maxParallelTasks: Maximum number of tasks that can run concurrently.
- taskTimeout: Time duration after which the task should timeout.
- retryAttempts: Number of times a task should retry upon failure.
- wait: Indicates if there if done event has to be emitted.
- finished: Promise which will be resolved when all tasks has finished (on done event). Only if
wait === false
Constructor
constructor(options={}, tm)
options
: Object that can include priority, maxTasks, maxParallelTasks, retryAttempts, and taskTimeout.tm
: An instance of the TaskManager class.
Getters
taskGroup.running
: Returns the number of tasks that are currently running in the ran.taskGroup.total
: Returns the total number of tasks in the group (sum of done, waiting, and running).taskGroup.waiting
: Returns the number of tasks that are currently waiting in the queue.
Methods
newTask
and runTask
method
Adds a new task to the group. The task is not executed immediately but added to the queue.
Syntax:
taskGroup.newTask(fn:Function,options={}:Object):instanceof Task
taskGroup.runTask(fn:Function,options={}:Object):instanceof Task
- parameters:
fn
: The function that represents the task to be executed.options
: An object that can include priority, timeout, and retryAttempts.- Returns an instance of the Task.
runTask
- Creates a new task and immediately tries to run it.
newTask
- Creates a new task but doesn't run it immediately.
pause()
Pauses all tasks in the group that are currently in the queue. Tasks that are running aren't paused.
resume()
Resumes all tasks in the group that are currently in the queue. If the group is paused, it will be resumed.
restartAllTasks()
Restarting all tasks which are currently running with all it's limits.
run()
Running taskManager.
Usage Example
const tm = new TaskManager();
const group = new TaskGroup({ maxParallelTasks: 3 }, tm);
group.runTask(async () => {
// Some asynchronous operation here
}, { priority: 'a' });
This will create a new task group and add a task to it with the highest priority ('a'). The task will attempt to run immediately if the number of running tasks is less than maxParallelTasks.
Events and taskGroup.emitter
TaskGroup has emitter which emits the folowing events:
done
: Emitted when taskGroup has finished all taskspause
: Emitted when taskGroup pausedresume
: Emitted when taskGroup resumedtask:start
: Emitted when every task starts.task:result
: Emitted when every task completes successfully.task:error
: Emitted when every task encounters an error.task:done
: Emitted when every task is done (either successfully or with an error).task:cancel
: Emitted when every task is cancelled.task:pause
: Emitted when every task is paused.task:resume
: Emitted when every task is resumed.task:timeout
: Emitted when every task times out.
wait
property
By default wait is false. You can set it to true if task group needs to wait for some tasks before it will finish and resolve the promise.