From 138aefc499ad0c0c0996780a5a56689eef718b64 Mon Sep 17 00:00:00 2001 From: Phil Kunz Date: Thu, 28 Nov 2019 11:33:26 +0000 Subject: [PATCH] feat(taskrunner): now has working taskrunner --- .gitlab-ci.yml | 85 +++++++++++++++------------ package.json | 14 ++--- readme.md | 5 ++ test/test.7.taskloop.ts | 8 +-- test/test.taskrunner.ts | 29 +++++++++ ts/index.ts | 4 +- ts/taskbuffer.classes.bufferrunner.ts | 4 +- ts/taskbuffer.classes.helpers.ts | 3 - ts/taskbuffer.classes.task.ts | 41 +++++++------ ts/taskbuffer.classes.taskmanager.ts | 4 +- ts/taskbuffer.classes.taskrunner.ts | 21 ++++++- 11 files changed, 137 insertions(+), 81 deletions(-) create mode 100644 test/test.taskrunner.ts diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1e3250b..a95dfb6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,14 +3,14 @@ image: registry.gitlab.com/hosttoday/ht-docker-node:npmci cache: paths: - - .npmci_cache/ - key: "$CI_BUILD_STAGE" + - .npmci_cache/ + key: '$CI_BUILD_STAGE' stages: -- security -- test -- release -- metadata + - security + - test + - release + - metadata # ==================== # security stage @@ -18,21 +18,23 @@ stages: mirror: stage: security script: - - npmci git mirror + - npmci git mirror tags: - - docker - - notpriv + - lossless + - docker + - notpriv snyk: + image: registry.gitlab.com/hosttoday/ht-docker-node:snyk stage: security script: - npmci npm prepare - - npmci command npm install -g snyk - npmci command npm install --ignore-scripts - npmci command snyk test tags: - - docker - - notpriv + - lossless + - docker + - notpriv # ==================== # test stage @@ -41,37 +43,40 @@ snyk: testStable: stage: test script: - - npmci npm prepare - - npmci node install stable - - npmci npm install - - npmci npm test + - npmci npm prepare + - npmci node install stable + - npmci npm install + - npmci npm test coverage: /\d+.?\d+?\%\s*coverage/ tags: - - docker - - priv + - lossless + - docker + - priv testBuild: stage: test script: - - npmci npm prepare - - npmci node install lts - - npmci npm install - - npmci command npm run build + - npmci npm prepare + - npmci node install stable + - npmci npm install + - npmci command npm run build coverage: /\d+.?\d+?\%\s*coverage/ tags: - - docker - - notpriv + - lossless + - docker + - notpriv release: stage: release script: - - npmci node install lts - - npmci npm publish + - npmci node install stable + - npmci npm publish only: - - tags + - tags tags: - - docker - - notpriv + - lossless + - docker + - notpriv # ==================== # metadata stage @@ -81,33 +86,35 @@ codequality: allow_failure: true script: - npmci command npm install -g tslint typescript + - npmci npm prepare - npmci npm install - npmci command "tslint -c tslint.json ./ts/**/*.ts" tags: - - docker - - priv + - lossless + - docker + - priv trigger: stage: metadata script: - - npmci trigger + - npmci trigger only: - - tags + - tags tags: - - docker - - notpriv + - lossless + - docker + - notpriv pages: - image: hosttoday/ht-docker-dbase:npmci - services: - - docker:stable-dind stage: metadata script: + - npmci node install lts - npmci command npm install -g @gitzone/tsdoc - npmci npm prepare - npmci npm install - npmci command tsdoc tags: + - lossless - docker - notpriv only: @@ -115,5 +122,5 @@ pages: artifacts: expire_in: 1 week paths: - - public + - public allow_failure: true diff --git a/package.json b/package.json index fcc8a5e..8d18850 100644 --- a/package.json +++ b/package.json @@ -44,14 +44,14 @@ "tslint-config-prettier": "^1.18.0" }, "files": [ - "ts/*", - "ts_web/*", - "dist/*", - "dist_web/*", - "dist_ts_web/*", - "assets/*", + "ts/**/*", + "ts_web/**/*", + "dist/**/*", + "dist_web/**/*", + "dist_ts_web/**/*", + "assets/**/*", "cli.js", "npmextra.json", "readme.md" ] -} +} \ No newline at end of file diff --git a/readme.md b/readme.md index 1875191..be91de0 100644 --- a/readme.md +++ b/readme.md @@ -44,6 +44,11 @@ For further information read the linked docs at the top of this README. [![repo-footer](https://pushrocks.gitlab.io/assets/repo-footer.svg)](https://push.rocks) + +## Contribution + +We are always happy for code contributions. If you are not the code contributing type that is ok. Still, maintaining Open Source repositories takes considerable time and thought. If you like the quality of what we do and our modules are useful to you we would appreciate a little monthly contribution: You can [contribute one time](https://lossless.link/contribute-onetime) or [contribute monthly](https://lossless.link/contribute). :) + For further information read the linked docs at the top of this readme. > MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh) diff --git a/test/test.7.taskloop.ts b/test/test.7.taskloop.ts index 25d1472..1e96b67 100644 --- a/test/test.7.taskloop.ts +++ b/test/test.7.taskloop.ts @@ -1,6 +1,6 @@ import { tap, expect } from '@pushrocks/tapbundle'; -import * as taskbuffer from '../ts'; +import * as taskbuffer from '../ts'; let preTask: taskbuffer.Task; let afterTask: taskbuffer.Task; @@ -17,7 +17,7 @@ tap.test('should create tasks', async () => { }); afterTask = new taskbuffer.Task({ name: 'myAfterTask', - taskFunction: async (x) => { + taskFunction: async x => { if (x === 'hi') { console.log('afterTask: values get passed along alright'); } @@ -30,7 +30,7 @@ tap.test('should create tasks', async () => { mainTask = new taskbuffer.Task({ name: 'mainTask', - taskFunction: async (x) => { + taskFunction: async x => { if (x === 'hi') { console.log('mainTask: values get passed along alright'); } @@ -48,4 +48,4 @@ tap.test('should execute the mainTask', async () => { await mainTask.trigger(); }); -tap.start(); \ No newline at end of file +tap.start(); diff --git a/test/test.taskrunner.ts b/test/test.taskrunner.ts new file mode 100644 index 0000000..84a259e --- /dev/null +++ b/test/test.taskrunner.ts @@ -0,0 +1,29 @@ +import { tap, expect } from '@pushrocks/tapbundle'; +import * as taskbuffer from '../ts/index'; + +let testTaskRunner: taskbuffer.TaskRunner; + +tap.test('should create a valid taskrunner', async () => { + testTaskRunner = new taskbuffer.TaskRunner(); + testTaskRunner.start(); +}); + +tap.test('should execute task when its scheduled', async (tools) => { + const done = tools.defer(); + testTaskRunner.addTask(new taskbuffer.Task({ + taskFunction: async () => { + console.log('hi'); + } + })); + + testTaskRunner.addTask(new taskbuffer.Task({ + taskFunction: async () => { + console.log('there'); + done.resolve(); + } + })); + + await done.promise; +}); + +tap.start(); \ No newline at end of file diff --git a/ts/index.ts b/ts/index.ts index 41fb1bc..6fe89ef 100644 --- a/ts/index.ts +++ b/ts/index.ts @@ -3,6 +3,4 @@ export { Taskchain } from './taskbuffer.classes.taskchain'; export { Taskparallel } from './taskbuffer.classes.taskparallel'; export { TaskManager } from './taskbuffer.classes.taskmanager'; export { TaskOnce } from './taskbuffer.classes.taskonce'; - -// import for naming only -import './taskbuffer.classes.helpers'; +export { TaskRunner } from './taskbuffer.classes.taskrunner'; diff --git a/ts/taskbuffer.classes.bufferrunner.ts b/ts/taskbuffer.classes.bufferrunner.ts index a007330..c4a0417 100644 --- a/ts/taskbuffer.classes.bufferrunner.ts +++ b/ts/taskbuffer.classes.bufferrunner.ts @@ -1,4 +1,4 @@ -import { Task } from "./taskbuffer.classes.task"; +import { Task } from './taskbuffer.classes.task'; export class BufferRunner { public task: Task; @@ -39,4 +39,4 @@ export class BufferRunner { }; recursiveBufferRunner(x); } -} \ No newline at end of file +} diff --git a/ts/taskbuffer.classes.helpers.ts b/ts/taskbuffer.classes.helpers.ts index 9357f5a..1d88ac2 100644 --- a/ts/taskbuffer.classes.helpers.ts +++ b/ts/taskbuffer.classes.helpers.ts @@ -1,5 +1,2 @@ import plugins = require('./taskbuffer.plugins'); import { Task, ITaskFunction } from './taskbuffer.classes.task'; - - - diff --git a/ts/taskbuffer.classes.task.ts b/ts/taskbuffer.classes.task.ts index 90ccf5e..8bb8bdd 100644 --- a/ts/taskbuffer.classes.task.ts +++ b/ts/taskbuffer.classes.task.ts @@ -12,12 +12,12 @@ export type TPreOrAfterTaskFunction = () => Task; export class Task { // STATIC public static extractTask(preOrAfterTaskArg: Task | TPreOrAfterTaskFunction): Task { - switch(true) { - case (!preOrAfterTaskArg): + switch (true) { + case !preOrAfterTaskArg: return null; - case (preOrAfterTaskArg instanceof Task): + case preOrAfterTaskArg instanceof Task: return preOrAfterTaskArg as Task; - case typeof preOrAfterTaskArg === "function": + case typeof preOrAfterTaskArg === 'function': const taskFunction = preOrAfterTaskArg as TPreOrAfterTaskFunction; return taskFunction(); default: @@ -25,13 +25,12 @@ export class Task { } } - 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; @@ -39,8 +38,11 @@ export class Task { return false; } }; - - public static isTaskTouched = (taskArg: Task | TPreOrAfterTaskFunction, touchedTasksArray: Task[]): boolean => { + + public static isTaskTouched = ( + taskArg: Task | TPreOrAfterTaskFunction, + touchedTasksArray: Task[] + ): boolean => { const taskToCheck = Task.extractTask(taskArg); let result = false; for (const keyArg in touchedTasksArray) { @@ -50,23 +52,26 @@ export class Task { } return result; }; - - public static runTask = async (taskArg: Task | TPreOrAfterTaskFunction, optionsArg: { x?; touchedTasksArray?: Task[] }) => { + + 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: [] }, @@ -74,15 +79,15 @@ export class Task { }; 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 { @@ -116,7 +121,7 @@ export class Task { }); localDeferred.resolve(); return await done.promise; - } + }; // INSTANCE // man datory properties diff --git a/ts/taskbuffer.classes.taskmanager.ts b/ts/taskbuffer.classes.taskmanager.ts index 1b690d7..5291ef2 100644 --- a/ts/taskbuffer.classes.taskmanager.ts +++ b/ts/taskbuffer.classes.taskmanager.ts @@ -10,7 +10,7 @@ export interface ICronJob { export class TaskManager { public taskMap = new plugins.lik.Objectmap(); private cronJobMap = new plugins.lik.Objectmap(); - + constructor() { // nothing here } @@ -85,7 +85,7 @@ export class TaskManager { /** * deschedules a task by name - * @param taskNameArg + * @param taskNameArg */ public descheduleTaskByName(taskNameArg: string) { const descheduledCron = this.cronJobMap.findOneAndRemove(itemArg => { diff --git a/ts/taskbuffer.classes.taskrunner.ts b/ts/taskbuffer.classes.taskrunner.ts index 7e7c562..a2ff5af 100644 --- a/ts/taskbuffer.classes.taskrunner.ts +++ b/ts/taskbuffer.classes.taskrunner.ts @@ -8,11 +8,18 @@ export class TaskRunner { public runningTasks: plugins.lik.Objectmap = new plugins.lik.Objectmap(); public qeuedTasks: Task[] = []; + constructor() { + this.runningTasks.eventSubject.subscribe(async eventArg => { + this.checkExecution(); + }); + } + /** * adds a task to the qeue */ public addTask(taskArg: Task) { this.qeuedTasks.push(taskArg); + this.checkExecution(); } /** @@ -30,12 +37,20 @@ export class TaskRunner { this.status = 'running'; } + /** + * checks wether execution is on point + */ public async checkExecution() { - if (this.runningTasks.getArray().length < this.maxParrallelJobs) { + if ( + this.runningTasks.getArray().length < this.maxParrallelJobs && + this.status === 'running' && + this.qeuedTasks.length > 0 + ) { const nextJob = this.qeuedTasks.shift(); this.runningTasks.add(nextJob); await nextJob.trigger(); - + this.runningTasks.remove(nextJob); + this.checkExecution(); } } @@ -44,5 +59,5 @@ export class TaskRunner { */ public stop() { this.status = 'stopped'; - }; + } }