fix(core): update

This commit is contained in:
Philipp Kunz 2019-09-23 18:06:43 +02:00
parent 2d2788d1ca
commit 2cc212f210
5 changed files with 214 additions and 182 deletions

View File

@ -37,12 +37,14 @@ tap.test('should create tasks', async () => {
console.log('afterTask executed :)'); console.log('afterTask executed :)');
return x; return x;
}, },
preTask, preTask: () => {
return preTask;
},
afterTask afterTask
}); });
}); });
tap.test('should execute the mainTasj', async () => { tap.test('should execute the mainTask', async () => {
await mainTask.trigger(); await mainTask.trigger();
}); });

View File

@ -0,0 +1,42 @@
import { Task } from "./taskbuffer.classes.task";
export class BufferRunner {
public task: Task;
// initialze by default
public bufferCounter: number = 0;
public running: boolean = false;
constructor(taskArg: Task) {
this.task = taskArg;
}
public trigger(x): Promise<any> {
if (!(this.bufferCounter >= this.task.bufferMax)) {
this.bufferCounter++;
}
const returnPromise: Promise<any> = this.task.cycleCounter.getPromiseForCycle(
this.bufferCounter + 1
);
if (!this.running) {
this._run(x);
}
return returnPromise;
}
private _run(x) {
const recursiveBufferRunner = x => {
if (this.bufferCounter >= 0) {
this.running = true;
this.task.running = true;
Task.runTask(this.task, { x: x }).then(x => {
this.bufferCounter--;
this.task.cycleCounter.informOfCycle(x);
recursiveBufferRunner(x);
});
} else {
this.running = false;
this.task.running = false;
}
};
recursiveBufferRunner(x);
}
}

View File

@ -0,0 +1,36 @@
import * as plugins from './taskbuffer.plugins';
import { Task } from './taskbuffer.classes.task';
export interface ICycleObject {
cycleCounter: number;
deferred: plugins.smartpromise.Deferred<any>;
}
export class CycleCounter {
public task: Task;
public cycleObjectArray: ICycleObject[] = [];
constructor(taskArg: Task) {
this.task = taskArg;
}
public getPromiseForCycle(cycleCountArg: number) {
const done = plugins.smartpromise.defer();
const cycleObject: ICycleObject = {
cycleCounter: cycleCountArg,
deferred: done
};
this.cycleObjectArray.push(cycleObject);
return done.promise;
}
public informOfCycle(x) {
const newCycleObjectArray: ICycleObject[] = [];
this.cycleObjectArray.forEach(cycleObjectArg => {
cycleObjectArg.cycleCounter--;
if (cycleObjectArg.cycleCounter <= 0) {
cycleObjectArg.deferred.resolve(x);
} else {
newCycleObjectArray.push(cycleObjectArg);
}
});
this.cycleObjectArray = newCycleObjectArray;
}
}

View File

@ -1,166 +1,5 @@
import plugins = require('./taskbuffer.plugins'); import plugins = require('./taskbuffer.plugins');
import { Task, ITaskFunction } from './taskbuffer.classes.task'; import { Task, ITaskFunction } from './taskbuffer.classes.task';
export const emptyTaskFunction: ITaskFunction = function(x) {
const done = plugins.smartpromise.defer();
done.resolve();
return done.promise;
};
export const isTask = (taskArg: Task): boolean => {
if (taskArg instanceof Task && typeof taskArg.taskFunction === 'function') {
return true;
} else {
return false;
}
};
export const isTaskTouched = (taskArg: Task, touchedTasksArray: Task[]): boolean => {
let result = false;
for (const keyArg in touchedTasksArray) {
if (taskArg === touchedTasksArray[keyArg]) {
result = true;
}
}
return result;
};
export const runTask = async (taskArg: Task, optionsArg: { x?; touchedTasksArray?: Task[] }) => {
const done = plugins.smartpromise.defer();
// pay respect to execDelay
if (taskArg.execDelay) {
await plugins.smartdelay.delayFor(taskArg.execDelay);
}
// set running params
taskArg.running = true;
done.promise.then(async () => {
taskArg.running = false;
});
// handle options
const options = {
...{ x: undefined, touchedTasksArray: [] },
...optionsArg
};
const x = options.x;
const touchedTasksArray: Task[] = options.touchedTasksArray;
touchedTasksArray.push(taskArg);
// run the task cascade
const localDeferred = plugins.smartpromise.defer();
localDeferred.promise
.then(() => {
// lets run any preTask
if (taskArg.preTask && !isTaskTouched(taskArg.preTask, touchedTasksArray)) {
return runTask(taskArg.preTask, { x, touchedTasksArray });
} else {
const done2 = plugins.smartpromise.defer();
done2.resolve(x);
return done2.promise;
}
})
.then(async x => {
// lets run the main task
try {
return await taskArg.taskFunction(x);
} catch (e) {
console.log(e);
}
})
.then(x => {
if (taskArg.afterTask && !isTaskTouched(taskArg.afterTask, touchedTasksArray)) {
return runTask(taskArg.afterTask, { x: x, touchedTasksArray: touchedTasksArray });
} else {
const done2 = plugins.smartpromise.defer();
done2.resolve(x);
return done2.promise;
}
})
.then(x => {
done.resolve(x);
})
.catch(err => {
console.log(err);
});
localDeferred.resolve();
return await done.promise;
};
export interface cycleObject {
cycleCounter: number;
deferred: plugins.smartpromise.Deferred<any>;
}
export class CycleCounter {
task: Task;
cycleObjectArray: cycleObject[] = [];
constructor(taskArg: Task) {
this.task = taskArg;
}
getPromiseForCycle(cycleCountArg: number) {
const done = plugins.smartpromise.defer();
const cycleObject: cycleObject = {
cycleCounter: cycleCountArg,
deferred: done
};
this.cycleObjectArray.push(cycleObject);
return done.promise;
}
informOfCycle(x) {
const newCycleObjectArray: cycleObject[] = [];
this.cycleObjectArray.forEach(cycleObjectArg => {
cycleObjectArg.cycleCounter--;
if (cycleObjectArg.cycleCounter <= 0) {
cycleObjectArg.deferred.resolve(x);
} else {
newCycleObjectArray.push(cycleObjectArg);
}
});
this.cycleObjectArray = newCycleObjectArray;
}
}
export class BufferRunner {
task: Task;
// initialze by default
bufferCounter: number = 0;
running: boolean = false;
constructor(taskArg: Task) {
this.task = taskArg;
}
trigger(x): Promise<any> {
if (!(this.bufferCounter >= this.task.bufferMax)) {
this.bufferCounter++;
}
const returnPromise: Promise<any> = this.task.cycleCounter.getPromiseForCycle(
this.bufferCounter + 1
);
if (!this.running) {
this._run(x);
}
return returnPromise;
}
private _run(x) {
const recursiveBufferRunner = x => {
if (this.bufferCounter >= 0) {
this.running = true;
this.task.running = true;
runTask(this.task, { x: x }).then(x => {
this.bufferCounter--;
this.task.cycleCounter.informOfCycle(x);
recursiveBufferRunner(x);
});
} else {
this.running = false;
this.task.running = false;
}
};
recursiveBufferRunner(x);
}
}

View File

@ -1,29 +1,142 @@
import * as plugins from './taskbuffer.plugins'; import * as plugins from './taskbuffer.plugins';
import * as helpers from './taskbuffer.classes.helpers'; import * as helpers from './taskbuffer.classes.helpers';
import { BufferRunner } from './taskbuffer.classes.bufferrunner';
import { CycleCounter } from './taskbuffer.classes.cyclecounter';
export interface ITaskFunction { export interface ITaskFunction {
(x?: any): PromiseLike<any>; (x?: any): PromiseLike<any>;
} }
export class Task { export type TPreOrAfterTaskFunction = () => Task;
// man datory properties
name: string;
taskFunction: ITaskFunction;
buffered: boolean;
bufferMax: number; export class Task {
execDelay: number; // STATIC
public static extractTask(preOrAfterTaskArg: Task | TPreOrAfterTaskFunction): Task {
switch(true) {
case (!preOrAfterTaskArg):
return null;
case (preOrAfterTaskArg instanceof Task):
return preOrAfterTaskArg as Task;
case typeof preOrAfterTaskArg === "function":
const taskFunction = preOrAfterTaskArg as TPreOrAfterTaskFunction;
return taskFunction();
default:
return null;
}
}
public static emptyTaskFunction: ITaskFunction = function(x) {
const done = plugins.smartpromise.defer();
done.resolve();
return done.promise;
};
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 => {
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[] }) => {
const taskToRun = Task.extractTask(taskArg);
const done = plugins.smartpromise.defer();
// pay respect to execDelay
if (taskToRun.execDelay) {
await plugins.smartdelay.delayFor(taskToRun.execDelay);
}
// set running params
taskToRun.running = true;
done.promise.then(async () => {
taskToRun.running = false;
});
// handle options
const options = {
...{ x: undefined, touchedTasksArray: [] },
...optionsArg
};
const x = options.x;
const touchedTasksArray: Task[] = options.touchedTasksArray;
touchedTasksArray.push(taskToRun);
// run the task cascade
const localDeferred = plugins.smartpromise.defer();
localDeferred.promise
.then(() => {
// lets run any preTask
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;
}
})
.then(async x => {
// lets run the main task
try {
return await taskToRun.taskFunction(x);
} catch (e) {
console.log(e);
}
})
.then(x => {
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;
}
})
.then(x => {
done.resolve(x);
})
.catch(err => {
console.log(err);
});
localDeferred.resolve();
return await done.promise;
}
// INSTANCE
// man datory properties
public name: string;
public taskFunction: ITaskFunction;
public buffered: boolean;
public bufferMax: number;
public execDelay: number;
// tasks to run before and after // tasks to run before and after
preTask: Task; public preTask: Task | TPreOrAfterTaskFunction;
afterTask: Task; public afterTask: Task | TPreOrAfterTaskFunction;
// initialize by default // initialize by default
running: boolean = false; public running: boolean = false;
bufferRunner = new helpers.BufferRunner(this); public bufferRunner = new BufferRunner(this);
cycleCounter = new helpers.CycleCounter(this); public cycleCounter = new CycleCounter(this);
idle: boolean = true; public idle: boolean = true;
private _state: string = 'ready'; private _state: string = 'ready';
constructor(optionsArg: { constructor(optionsArg: {
@ -34,11 +147,11 @@ export class Task {
/** /**
* any other task to run before * any other task to run before
*/ */
preTask?: Task; preTask?: Task | TPreOrAfterTaskFunction;
/** /**
* any other task to run after * any other task to run after
*/ */
afterTask?: Task; afterTask?: Task | TPreOrAfterTaskFunction;
/** /**
* wether this task should run buffered * wether this task should run buffered
*/ */
@ -70,7 +183,7 @@ export class Task {
/** /**
* trigger the task. Will trigger buffered if this.buffered is true * trigger the task. Will trigger buffered if this.buffered is true
*/ */
trigger(x?): Promise<any> { public trigger(x?): Promise<any> {
if (this.buffered) { if (this.buffered) {
return this.triggerBuffered(x); return this.triggerBuffered(x);
} else { } else {
@ -81,14 +194,14 @@ export class Task {
/** /**
* trigger task unbuffered. * trigger task unbuffered.
*/ */
triggerUnBuffered(x?): Promise<any> { public triggerUnBuffered(x?): Promise<any> {
return helpers.runTask(this, { x: x }); return Task.runTask(this, { x: x });
} }
/** /**
* trigger task buffered. * trigger task buffered.
*/ */
triggerBuffered(x?): Promise<any> { public triggerBuffered(x?): Promise<any> {
return this.bufferRunner.trigger(x); return this.bufferRunner.trigger(x);
} }