taskbuffer/ts/taskbuffer.classes.task.ts

201 lines
5.5 KiB
TypeScript
Raw Normal View History

2022-03-25 11:14:49 +00:00
import * as plugins from './taskbuffer.plugins.js';
import { BufferRunner } from './taskbuffer.classes.bufferrunner.js';
import { CycleCounter } from './taskbuffer.classes.cyclecounter.js';
2022-03-25 11:14:49 +00:00
import { logger } from './taskbuffer.logging.js';
2020-07-12 00:48:51 +00:00
2023-08-01 22:51:43 +00:00
export interface ITaskFunction<T = undefined> {
(x?: any, setupValue?: T): PromiseLike<any>;
2016-08-01 11:17:15 +00:00
}
2023-08-01 22:51:43 +00:00
export interface ITaskSetupFunction<T = undefined> {
(): Promise<T>;
}
export type TPreOrAfterTaskFunction = () => Task<any>;
2019-09-23 16:06:43 +00:00
2023-08-01 22:51:43 +00:00
export class Task<T = undefined> {
2019-09-23 16:06:43 +00:00
// STATIC
2023-08-01 22:51:43 +00:00
public static extractTask<T = undefined>(preOrAfterTaskArg: Task<T> | TPreOrAfterTaskFunction): Task<T> {
switch (true) {
case !preOrAfterTaskArg:
2019-09-23 16:06:43 +00:00
return null;
case preOrAfterTaskArg instanceof Task:
2023-08-01 22:51:43 +00:00
return preOrAfterTaskArg as Task<T>;
case typeof preOrAfterTaskArg === 'function':
2019-09-23 16:06:43 +00:00
const taskFunction = preOrAfterTaskArg as TPreOrAfterTaskFunction;
return taskFunction();
default:
return null;
}
}
2020-07-12 00:48:51 +00:00
public static emptyTaskFunction: ITaskFunction = function (x) {
2019-09-23 16:06:43 +00:00
const done = plugins.smartpromise.defer();
done.resolve();
return done.promise;
};
2023-08-01 22:51:43 +00:00
public static isTask = (taskArg: Task<any>): boolean => {
2019-09-23 16:06:43 +00:00
if (taskArg instanceof Task && typeof taskArg.taskFunction === 'function') {
return true;
} else {
return false;
}
};
2023-08-01 22:51:43 +00:00
public static isTaskTouched<T = undefined> (
taskArg: Task<T> | TPreOrAfterTaskFunction,
touchedTasksArray: Task<T>[]
): boolean {
2019-09-23 16:06:43 +00:00
const taskToCheck = Task.extractTask(taskArg);
let result = false;
for (const keyArg in touchedTasksArray) {
if (taskToCheck === touchedTasksArray[keyArg]) {
result = true;
}
}
return result;
};
2023-08-01 22:51:43 +00:00
public static runTask = async <T>(
taskArg: Task<T> | TPreOrAfterTaskFunction,
optionsArg: { x?: any; touchedTasksArray?: Task<T>[] }
) => {
2019-09-23 16:06:43 +00:00
const taskToRun = Task.extractTask(taskArg);
const done = plugins.smartpromise.defer();
2023-08-01 22:51:43 +00:00
if (!taskToRun.setupValue && taskToRun.taskSetup) {
taskToRun.setupValue = await taskToRun.taskSetup();
}
2019-09-23 16:06:43 +00:00
if (taskToRun.execDelay) {
await plugins.smartdelay.delayFor(taskToRun.execDelay);
}
2019-09-23 16:06:43 +00:00
taskToRun.running = true;
2019-09-23 16:06:43 +00:00
done.promise.then(async () => {
taskToRun.running = false;
});
2019-09-23 16:06:43 +00:00
const options = {
...{ x: undefined, touchedTasksArray: [] },
2020-07-12 00:48:51 +00:00
...optionsArg,
2019-09-23 16:06:43 +00:00
};
const x = options.x;
2023-08-01 22:51:43 +00:00
const touchedTasksArray: Task<T>[] = options.touchedTasksArray;
2019-09-23 16:06:43 +00:00
touchedTasksArray.push(taskToRun);
2019-09-23 16:06:43 +00:00
const localDeferred = plugins.smartpromise.defer();
localDeferred.promise
.then(() => {
if (taskToRun.preTask && !Task.isTaskTouched(taskToRun.preTask, touchedTasksArray)) {
return Task.runTask(taskToRun.preTask, { x, touchedTasksArray });
} else {
const done2 = plugins.smartpromise.defer();
done2.resolve(x);
return done2.promise;
}
})
2020-07-12 00:48:51 +00:00
.then(async (x) => {
2019-09-23 16:06:43 +00:00
try {
2023-08-01 22:51:43 +00:00
return await taskToRun.taskFunction(x, taskToRun.setupValue);
2019-09-23 16:06:43 +00:00
} catch (e) {
console.log(e);
}
})
2020-07-12 00:48:51 +00:00
.then((x) => {
2019-09-23 16:06:43 +00:00
if (taskToRun.afterTask && !Task.isTaskTouched(taskToRun.afterTask, touchedTasksArray)) {
return Task.runTask(taskToRun.afterTask, { x: x, touchedTasksArray: touchedTasksArray });
} else {
const done2 = plugins.smartpromise.defer();
done2.resolve(x);
return done2.promise;
}
})
2020-07-12 00:48:51 +00:00
.then((x) => {
2019-09-23 16:06:43 +00:00
done.resolve(x);
})
2020-07-12 00:48:51 +00:00
.catch((err) => {
2019-09-23 16:06:43 +00:00
console.log(err);
});
localDeferred.resolve();
return await done.promise;
};
2019-09-23 16:06:43 +00:00
// INSTANCE
public name: string;
2022-11-14 13:54:26 +00:00
public version: string;
2023-08-01 22:51:43 +00:00
public taskFunction: ITaskFunction<T>;
2019-09-23 16:06:43 +00:00
public buffered: boolean;
2020-07-12 00:48:51 +00:00
public cronJob: plugins.smarttime.CronJob;
2017-07-10 10:42:06 +00:00
2019-09-23 16:06:43 +00:00
public bufferMax: number;
public execDelay: number;
2022-11-14 13:54:26 +00:00
public timeout: number;
2017-07-10 10:42:06 +00:00
2023-08-01 22:51:43 +00:00
public preTask: Task<T> | TPreOrAfterTaskFunction;
public afterTask: Task<T> | TPreOrAfterTaskFunction;
2019-09-23 16:06:43 +00:00
public running: boolean = false;
public bufferRunner = new BufferRunner(this);
public cycleCounter = new CycleCounter(this);
2017-07-10 10:42:06 +00:00
2019-09-23 16:06:43 +00:00
public idle: boolean = true;
2018-08-04 15:53:22 +00:00
private _state: string = 'ready';
2016-08-01 14:10:00 +00:00
2023-08-01 22:51:43 +00:00
public taskSetup: ITaskSetupFunction<T>;
public setupValue: T;
2017-07-10 10:42:06 +00:00
constructor(optionsArg: {
2023-08-01 22:51:43 +00:00
taskFunction: ITaskFunction<T>;
preTask?: Task<T> | TPreOrAfterTaskFunction;
afterTask?: Task<T> | TPreOrAfterTaskFunction;
2018-08-04 15:53:22 +00:00
buffered?: boolean;
bufferMax?: number;
execDelay?: number;
name?: string;
2023-08-01 22:51:43 +00:00
taskSetup?: ITaskSetupFunction<T>;
2017-02-15 21:52:29 +00:00
}) {
2018-08-04 15:53:22 +00:00
this.taskFunction = optionsArg.taskFunction;
this.preTask = optionsArg.preTask;
this.afterTask = optionsArg.afterTask;
this.idle = !this.running;
this.buffered = optionsArg.buffered;
this.bufferMax = optionsArg.bufferMax;
this.execDelay = optionsArg.execDelay;
this.name = optionsArg.name;
2023-08-01 22:51:43 +00:00
this.taskSetup = optionsArg.taskSetup;
2017-02-15 21:52:29 +00:00
}
2021-09-26 12:45:02 +00:00
public trigger(x?: any): Promise<any> {
2017-02-15 21:52:29 +00:00
if (this.buffered) {
2018-08-04 15:53:22 +00:00
return this.triggerBuffered(x);
2017-06-09 21:33:41 +00:00
} else {
2018-08-04 15:53:22 +00:00
return this.triggerUnBuffered(x);
2017-06-09 21:33:41 +00:00
}
}
2016-08-01 11:17:15 +00:00
2021-09-26 12:45:02 +00:00
public triggerUnBuffered(x?: any): Promise<any> {
2023-08-01 22:51:43 +00:00
return Task.runTask<T>(this, { x: x });
2017-02-15 21:52:29 +00:00
}
2021-09-26 12:45:02 +00:00
public triggerBuffered(x?: any): Promise<any> {
2018-08-04 15:53:22 +00:00
return this.bufferRunner.trigger(x);
2017-02-15 21:52:29 +00:00
}
2017-07-10 10:42:06 +00:00
get state(): string {
2018-08-04 15:53:22 +00:00
return this._state;
2017-02-15 21:52:29 +00:00
}
2017-07-10 10:42:06 +00:00
set state(stateArg: string) {
2017-02-15 21:52:29 +00:00
if (stateArg === 'locked') {
2018-08-04 15:53:22 +00:00
this._state = 'locked';
2017-02-15 21:52:29 +00:00
} else {
2020-07-12 00:48:51 +00:00
logger.log('error', `state type ${stateArg} could not be set`);
}
2017-02-15 21:52:29 +00:00
}
2017-06-09 21:33:41 +00:00
}