0.1.1 • Published 7 months ago

@sisense/task-manager v0.1.1

Weekly downloads
-
License
ISC
Repository
gitlab
Last release
7 months ago

task-manager

What is a task-manager?

This library helps solve the common development problem of managing complex, resource-intensive asynchronous tasks (workflows).

Imagine you have a request for a Service that needs to execute a sequential workflow consisting of several lengthy asynchronous steps in order to return the final result.

Multi-step request

If this task takes a significant amount of time, the user may want to cancel it manually or by timeout. If this task has multiple lengthy asynchronous steps and a cancel request can be made at any point in this complex flow, you would want to cancel it as soon as possible and skip all subsequent steps. Each step's cancellation may require its own logic to clean up and free consumed resources.

Service with manager

If resources for doing smth 1 or doing smth 2 are limited - you may want to add some internal Queue to collect incoming requests and perform the execution of these workflow steps one by one.

In task-manager this possibility implemented as an addon and can be optionally added if needed. The basic behavior of task-manager includes only canceling logic.


The main idea of task-manager:

  • You create your own TaskManager where define ExecutionFlow. ExecutionFlow made of Steps - for each Step you define RunLogic - async function that performs logic you want to do, like doing smth 1, and CancelLogic - async function that performs all cleaning up you want to do if canceling happened during this step.

  • On incoming request, you create TaskPassport that contains the type of task and payload of your request.

  • Save taskId of the task you are performing to be able to cancel it if needed.

const STEP_2_RESULT = 'step_2_result';
const SOME_RUNTIME_VALUE = 'some_runtime_value';

const step1 = new Step(
    'step_1_name',
    async (task: MyTask) => {
        // do something 1
        task.addRuntimeInfo('someRuntimeValue', SOME_RUNTIME_VALUE);
        // return nothing
    },
    async () => {
        // clean up if canceled during step 1
    },
);
const step2 = new Step(
    'step_2_name',
    async () => {
        // do something 2
        return STEP_2_RESULT;
    },
    async () => {
        // clean up if canceled during step 2
    },
);

class MyTaskManager extends AbstractTaskManager {
    executeTestFlow = super.createFlow<MyTaskPassport, MyTaskRuntimeInfo, MyTaskResultData>([
        step1,
        step2,
    ]);
}

const manager = new MyTaskManager();
// for each incoming request
const taskPassport = new MyTaskPassport(/* payload */);
const result = await manager.executeTestFlow(taskPassport);

// if cancel request ->
manager.cancel(taskPassport.taskId);

// cancel by timeout
setTimeout(() => {
    manager.cancel(taskPassport.taskId);
}, 1000);
0.1.1

7 months ago