taskbuffer/ts/taskbuffer.classes.task.ts

227 lines
5.8 KiB
TypeScript
Raw Permalink Normal View History

2018-08-04 15:53:22 +00:00
import * as plugins from './taskbuffer.plugins';
2019-09-23 16:06:43 +00:00
import { BufferRunner } from './taskbuffer.classes.bufferrunner';
import { CycleCounter } from './taskbuffer.classes.cyclecounter';
2020-07-12 00:48:51 +00:00
import { logger } from './taskbuffer.logging';
2016-08-01 11:17:15 +00:00
export interface ITaskFunction {
2018-08-04 15:53:22 +00:00
(x?: any): PromiseLike<any>;
2016-08-01 11:17:15 +00:00
}
2019-09-23 16:06:43 +00:00
export type TPreOrAfterTaskFunction = () => Task;
export class Task {
2019-09-23 16:06:43 +00:00
// STATIC
public static extractTask(preOrAfterTaskArg: Task | TPreOrAfterTaskFunction): Task {
switch (true) {
case !preOrAfterTaskArg:
2019-09-23 16:06:43 +00:00
return null;
case preOrAfterTaskArg instanceof Task:
2019-09-23 16:06:43 +00:00
return preOrAfterTaskArg as Task;
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;
};
2019-09-23 16:06:43 +00:00
public static isTask = (taskArg: Task): boolean => {
if (taskArg instanceof Task && typeof taskArg.taskFunction === 'function') {
return true;
} else {
return false;
}
};
public static isTaskTouched = (
taskArg: Task | TPreOrAfterTaskFunction,
touchedTasksArray: Task[]
): 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;
};
public static runTask = async (
taskArg: Task | TPreOrAfterTaskFunction,
optionsArg: { x?; touchedTasksArray?: Task[] }
) => {
2019-09-23 16:06:43 +00:00
const taskToRun = Task.extractTask(taskArg);
const done = plugins.smartpromise.defer();
2019-09-23 16:06:43 +00:00
// pay respect to execDelay
if (taskToRun.execDelay) {
await plugins.smartdelay.delayFor(taskToRun.execDelay);
}
2019-09-23 16:06:43 +00:00
// set running params
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
// handle options
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;
const touchedTasksArray: Task[] = options.touchedTasksArray;
2019-09-23 16:06:43 +00:00
touchedTasksArray.push(taskToRun);
2019-09-23 16:06:43 +00:00
// run the task cascade
const localDeferred = plugins.smartpromise.defer();
localDeferred.promise
.then(() => {
// lets run any preTask
2019-09-23 16:06:43 +00:00
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
// lets run the main task
try {
return await taskToRun.taskFunction(x);
} 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
2017-07-10 10:42:06 +00:00
// man datory properties
2019-09-23 16:06:43 +00:00
public name: string;
public taskFunction: ITaskFunction;
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;
2017-07-10 10:42:06 +00:00
// tasks to run before and after
2019-09-23 16:06:43 +00:00
public preTask: Task | TPreOrAfterTaskFunction;
public afterTask: Task | TPreOrAfterTaskFunction;
2017-02-15 21:52:29 +00:00
// initialize by default
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
2017-07-10 10:42:06 +00:00
constructor(optionsArg: {
/**
* the task function to run, must return promise
*/
2018-08-04 15:53:22 +00:00
taskFunction: ITaskFunction;
2017-07-10 10:42:06 +00:00
/**
* any other task to run before
*/
2019-09-23 16:06:43 +00:00
preTask?: Task | TPreOrAfterTaskFunction;
2017-07-10 10:42:06 +00:00
/**
* any other task to run after
*/
2019-09-23 16:06:43 +00:00
afterTask?: Task | TPreOrAfterTaskFunction;
2017-07-10 10:42:06 +00:00
/**
* wether this task should run buffered
*/
2018-08-04 15:53:22 +00:00
buffered?: boolean;
2017-07-10 10:42:06 +00:00
/**
* the maximum buffer
*/
2018-08-04 15:53:22 +00:00
bufferMax?: number;
2017-07-10 10:42:06 +00:00
/**
* the execution delay, before the task is executed
* only makes sense when running in buffered mode
*/
2018-08-04 15:53:22 +00:00
execDelay?: number;
2017-07-10 10:42:06 +00:00
/**
* the name of the task
*/
2018-08-04 15:53:22 +00:00
name?: string;
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;
2017-02-15 21:52:29 +00:00
}
/**
* trigger the task. Will trigger buffered if this.buffered is true
*/
2019-09-23 16:06:43 +00:00
public trigger(x?): 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
2017-02-15 21:52:29 +00:00
/**
* trigger task unbuffered.
*/
2019-09-23 16:06:43 +00:00
public triggerUnBuffered(x?): Promise<any> {
return Task.runTask(this, { x: x });
2017-02-15 21:52:29 +00:00
}
2017-02-15 21:52:29 +00:00
/**
* trigger task buffered.
*/
2019-09-23 16:06:43 +00:00
public triggerBuffered(x?): 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
}