Compare commits

..

64 Commits

Author SHA1 Message Date
dbcd5bbfc8 2.0.0 2018-08-04 18:00:22 +02:00
d91b6c8360 BREAKING CHANGE(scope): switch to pushrocks scope 2018-08-04 18:00:21 +02:00
b9af186190 update 2018-08-04 17:59:01 +02:00
bdb7064394 update 2018-08-04 17:58:46 +02:00
f60deddadd fix(tests): now using tstest 2018-08-04 17:53:22 +02:00
df18aba4b5 1.0.22 2017-07-12 16:45:21 +02:00
a3699f2869 introduce TaskOnce 2017-07-12 16:45:18 +02:00
017c0789ca 1.0.21 2017-07-10 14:29:02 +02:00
6e6d056617 update docs 2017-07-10 14:28:58 +02:00
3f7f38ee17 1.0.20 2017-07-10 12:49:04 +02:00
5bfc72a602 add docs 2017-07-10 12:48:57 +02:00
ca8882962e 1.0.19 2017-07-10 12:45:36 +02:00
df6bf2c681 updated dependencies 2017-07-10 12:45:33 +02:00
310a683e14 1.0.18 2017-07-10 12:42:11 +02:00
3f275ebc08 implemented execDelay 2017-07-10 12:42:06 +02:00
01d469960e 1.0.17 2017-06-18 13:25:12 +02:00
2ed701040a now has working TaskManager 2017-06-18 13:25:09 +02:00
ca3bb38205 update test texts 2017-06-17 17:29:26 +02:00
891d727fd4 1.0.16 2017-06-17 16:56:37 +02:00
e1424ea0fb implement TaskManager 2017-06-17 16:56:33 +02:00
cf1b31d635 1.0.15 2017-06-09 23:34:40 +02:00
d5570311ee update ci 2017-06-09 23:34:37 +02:00
44b3ba1313 1.0.14 2017-06-09 23:33:45 +02:00
4721d8c9e6 clean up code 2017-06-09 23:33:41 +02:00
c7336eedfb 1.0.13 2017-06-09 23:26:25 +02:00
5477911b5e update to latest standards 2017-06-09 23:26:23 +02:00
2f8d3f7625 1.0.12 2017-02-15 22:52:34 +01:00
b00d31b41a update dependencies 2017-02-15 22:52:29 +01:00
4031692f6f 1.0.11 2017-01-20 21:36:21 +01:00
174beae65f fix test 2017-01-20 21:36:18 +01:00
c1144d3405 add taskmanager class 2017-01-20 20:48:07 +01:00
065d92e573 1.0.10 2017-01-20 18:54:28 +01:00
46878819df add better readme 2017-01-20 18:54:23 +01:00
aa8df29bbb 1.0.9 2017-01-20 18:50:43 +01:00
f5cb0843fc smartq now working 2017-01-20 18:50:37 +01:00
1d52d098fb Merge branch 'master' into 'master'
update from q to smartq

See merge request !1
2017-01-20 08:33:32 +00:00
eb7eb14415 update from q to smartq 2017-01-19 17:26:35 +01:00
670bf5b124 1.0.8 2016-09-02 18:11:49 +02:00
fab863c66c update dependencies 2016-09-02 18:11:33 +02:00
402e2b982f 1.0.7 2016-08-03 14:51:47 +02:00
1d0a85e6ca now returning correct Promise types 2016-08-03 14:51:43 +02:00
7ded7b036e 1.0.6 2016-08-03 12:14:29 +02:00
03020eacbc update type versions 2016-08-03 12:14:21 +02:00
dc95885646 1.0.5 2016-08-03 11:28:21 +02:00
11cdaad226 add error catching 2016-08-03 11:28:13 +02:00
a1ad463140 1.0.4 2016-08-02 11:10:08 +02:00
76c57451b3 values now flow correctly between tasks 2016-08-02 11:09:42 +02:00
5dca9a9460 1.0.3 2016-08-01 16:10:06 +02:00
d30fb551f9 now running correctly in buffered mode 2016-08-01 16:10:00 +02:00
7a60f30f0b 1.0.2 2016-08-01 13:35:38 +02:00
9e175245ed update README 2016-08-01 13:35:33 +02:00
4bc5617240 1.0.1 2016-08-01 13:19:50 +02:00
39c41a817e now exporting interfaces 2016-08-01 13:19:42 +02:00
8823e2b01d 1.0.0 2016-08-01 13:17:36 +02:00
24e96926e3 update taskbuffer and add gitlab ci 2016-08-01 13:17:15 +02:00
8a414b9a7d update structure 2016-08-01 00:53:27 +02:00
a347ded65a 0.1.3 2016-05-23 05:37:12 +02:00
3ce4b200db add typings to package.json 2016-05-23 05:36:55 +02:00
cd6407f189 0.1.2 2016-05-17 03:32:57 +02:00
ca2afbd8c7 improve Readme 2016-05-17 03:32:47 +02:00
6640d5fb2f 0.1.1 2016-05-17 03:27:34 +02:00
7a3aed275f update README 2016-05-17 03:27:29 +02:00
19beb95e20 now logging allright 2016-05-15 15:52:59 +02:00
8944ae2462 added Taskparallel class that executest tasks in parallel 2016-05-15 15:28:38 +02:00
47 changed files with 2137 additions and 785 deletions

7
.gitignore vendored
View File

@ -1,7 +1,4 @@
.idea/
coverage/
docs/
ts/*.js
ts/*.js.map
ts/typings/
node_modules
pages/
.nogit/

142
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,142 @@
# gitzone standard
image: hosttoday/ht-docker-node:npmci
cache:
paths:
- .npmci_cache/
key: "$CI_BUILD_STAGE"
stages:
- security
- test
- release
- metadata
# ====================
# security stage
# ====================
mirror:
stage: security
script:
- npmci git mirror
tags:
- docker
- notpriv
snyk:
stage: security
script:
- npmci command npm install -g snyk
- npmci command npm install --ignore-scripts
- npmci command snyk test
tags:
- docker
- notpriv
# ====================
# test stage
# ====================
testLEGACY:
stage: test
script:
- npmci node install legacy
- npmci npm install
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- notpriv
allow_failure: true
testLTS:
stage: test
script:
- npmci node install lts
- npmci npm install
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- notpriv
testSTABLE:
stage: test
script:
- npmci node install stable
- npmci npm install
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- notpriv
release:
stage: release
script:
- npmci node install stable
- npmci npm publish
only:
- tags
tags:
- docker
- notpriv
# ====================
# metadata stage
# ====================
codequality:
stage: metadata
image: docker:stable
allow_failure: true
services:
- docker:stable-dind
script:
- export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
- docker run
--env SOURCE_CODE="$PWD"
--volume "$PWD":/code
--volume /var/run/docker.sock:/var/run/docker.sock
"registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code
artifacts:
paths: [codeclimate.json]
tags:
- docker
- priv
trigger:
stage: metadata
script:
- npmci trigger
only:
- tags
tags:
- docker
- notpriv
pages:
image: hosttoday/ht-docker-node:npmci
stage: metadata
script:
- npmci command npm install -g typedoc typescript
- npmci npm install
- npmci command typedoc --module "commonjs" --target "ES2016" --out public/ ts/
tags:
- docker
- notpriv
only:
- tags
artifacts:
expire_in: 1 week
paths:
- public
allow_failure: true
windowsCompatibility:
image: stefanscherer/node-windows:10-build-tools
stage: metadata
script:
- npm install & npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- windows
allow_failure: true

View File

@ -1,5 +1,5 @@
.idea/
docs/
coverage/
ts/
node_modules/
pages/

View File

@ -1,11 +0,0 @@
language: node_js
node_js:
- stable
deploy:
provider: npm
email: npm@lossless.digital
api_key:
secure: NejErc2+ohEEH8DecYcx6/2oSdEQQBRzlOwTMxQBftHdIkvziwOcCerqCJtrXuzalqAofVCcVisunWIXZmxfIBGV6mJVauCIp5KzH4JUhYzLym33p9MSphjlPNfsI6nKkW0LAgOMjkJGuHLqU3oskvBqYyh8m3NuCna5mNwm8lo5WGckzHSwdsmhnb839WhlZbmQc6M6WW6Ir7bbxX9ZOmNUYUWH6VdXfPBxoXN3nO21pXKt7Zg8/nU7IkF+VEUVfYNlR3xUiocWemuBFxjtsfoliQ/y/oGL7ccQ7OeE4PxSu+xNUpYYVipkQcRtyWDKCwJp4R2DNTj/ikOHH+BEFOBDG8qYxwf37Ju0jFybzslAEJLy5gl4bFjiZNA8ldUXY5ubJb56iZTNSbMU0lmXw+qKvIoyVY/1JAE5lzFGVA6nDdiUGAEOg/ajzAC3gjFU2QS2Wvncz3dky0k/2INBVUwmmAvAMazl5XkvHtQ3Wzb+Fc8TXWflqBDF0okySoJzlY13pm/OtOHipiqEyUCnqaUUwJtLIb6tHOPzxZKlWLCem7y84cDlxQSbLVItbArOJFHdr66sp/U/FqYAtWeLdbkhjCENFwzR9kYtEyEl+QWLTckO1/lVF4xJLh6drfhQ66CwF5bfqr5xIS08mnKuYBfJOA4/wV4bQFPhtYm7Oi8=
on:
tags: true
repo: pushrocks/taskbuffer

View File

@ -1,32 +0,0 @@
# taskbuffer
Flexible task organization for gulp.
## Status
[![Coverage Status](https://coveralls.io/repos/github/pushrocks/taskbuffer/badge.svg?branch=master)](https://coveralls.io/github/pushrocks/taskbuffer?branch=master)
## Install
```sh
npm install taskbuffer --save
```
## Concepts
#### Task
* A Task in its most simple form is a function that is executed when the task runs.
* A Task can have a **preTask** and an **afterTask**
(those are run before or after the main function whenever the task is called)
* A Task can be buffered.
That means it can be called multiple times in a very short time.
However execution happens in line:
meaning execution of the task's main function is on halt until the previous task call has finished.
You can set bufferMax number, which is the max number of buffered task calls.
Any additional calls will then be truncated
* Task.trigger() and Task.triggerBuffered() always return a Promise
which is fullfilled once the related task call has completed.
* Task.triggered() is an Observable stream that emits events every time a task call is called and every time a call is completed.
* Task is compatible to gulp streams.
#### Taskchain
* Multiple Tasks can be combined in a bigger task using a Taskchain. Taskchain extends Task.

2
dist/index.d.ts vendored
View File

@ -1,2 +0,0 @@
export * from "./taskbuffer.classes";
import "./taskbuffer.classes.helpers";

10
dist/index.js vendored
View File

@ -1,10 +0,0 @@
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
/// <reference path="./typings/main.d.ts" />
__export(require("./taskbuffer.classes"));
// import for naming only
require("./taskbuffer.classes.helpers");
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSw0Q0FBNEM7QUFDNUMsaUJBQWMsc0JBQXNCLENBQUMsRUFBQTtBQUVyQyx5QkFBeUI7QUFDekIsUUFBTyw4QkFBOEIsQ0FBQyxDQUFEIiwiZmlsZSI6ImluZGV4LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8vIDxyZWZlcmVuY2UgcGF0aD1cIi4vdHlwaW5ncy9tYWluLmQudHNcIiAvPlxyXG5leHBvcnQgKiBmcm9tIFwiLi90YXNrYnVmZmVyLmNsYXNzZXNcIjtcclxuXHJcbi8vIGltcG9ydCBmb3IgbmFtaW5nIG9ubHlcclxuaW1wb3J0IFwiLi90YXNrYnVmZmVyLmNsYXNzZXMuaGVscGVyc1wiIl19

View File

@ -1,2 +0,0 @@
export * from "./taskbuffer.classes.task";
export * from "./taskbuffer.classes.taskchain";

View File

@ -1,9 +0,0 @@
import { Task } from "./taskbuffer.classes";
export declare let emptyTaskFunction: () => any;
export declare let isTask: (taskArg: any) => boolean;
export declare let isTaskTouched: (taskArg: Task, touchedTasksArray: Task[]) => boolean;
export declare let runTask: (taskArg: Task, optionsArg?: {
touchedTasksArray: Task[];
}) => any;
export declare let runBufferedTask: (taskArg: Task) => void;
export declare let updateTaskStatus: (taskArg: any, statusArg: string) => void;

File diff suppressed because one or more lines are too long

View File

@ -1,8 +0,0 @@
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
__export(require("./taskbuffer.classes.task"));
__export(require("./taskbuffer.classes.taskchain"));
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRhc2tidWZmZXIuY2xhc3Nlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsaUJBQWMsMkJBQ2QsQ0FBQyxFQUR3QztBQUN6QyxpQkFBYyxnQ0FDZCxDQUFDLEVBRDZDIiwiZmlsZSI6InRhc2tidWZmZXIuY2xhc3Nlcy5qcyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gXCIuL3Rhc2tidWZmZXIuY2xhc3Nlcy50YXNrXCJcclxuZXhwb3J0ICogZnJvbSBcIi4vdGFza2J1ZmZlci5jbGFzc2VzLnRhc2tjaGFpblwiXHJcbiJdfQ==

View File

@ -1,25 +0,0 @@
export declare class Task {
name: string;
task: any;
running: boolean;
idle: boolean;
buffered: boolean;
bufferCounter: number;
bufferMax: number;
private _counterTriggerAbsolute;
private _state;
preTask: Task;
afterTask: Task;
constructor(optionsArg: {
taskFunction: any;
preTask?: Task;
afterTask?: Task;
buffered?: boolean;
bufferMax?: number;
name?: string;
});
trigger(): any;
triggerUnBuffered(): any;
triggerBuffered(): any;
state: string;
}

File diff suppressed because one or more lines are too long

View File

@ -1,14 +0,0 @@
import { Task } from "./taskbuffer.classes";
export declare class Taskchain extends Task {
taskArray: Task[];
private _oraObject;
constructor(optionsArg: {
name?: string;
log?: boolean;
taskArray: Task[];
});
addTask(taskArg: Task): void;
removeTask(taskArg: Task): void;
shiftTask(): void;
trigger(): any;
}

File diff suppressed because one or more lines are too long

View File

@ -1,3 +0,0 @@
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsImZpbGUiOiJ0YXNrYnVmZmVyLmNsYXNzZXMudGFza3NwYWNlLmpzIiwic291cmNlc0NvbnRlbnQiOltdfQ==

View File

@ -1,3 +0,0 @@
export import beautylog = require("beautylog");
export declare let Q: any;
export declare let lodash: any;

View File

@ -1,7 +0,0 @@
"use strict";
/// <reference path="./typings/main.d.ts" />
exports.beautylog = require("beautylog");
exports.Q = require("q");
exports.lodash = require("lodash");
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRhc2tidWZmZXIucGx1Z2lucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsNENBQTRDO0FBQzlCLGlCQUFTLFdBQVcsV0FBVyxDQUFDLENBQUM7QUFDcEMsU0FBQyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNqQixjQUFNLEdBQUUsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDIiwiZmlsZSI6InRhc2tidWZmZXIucGx1Z2lucy5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vLyA8cmVmZXJlbmNlIHBhdGg9XCIuL3R5cGluZ3MvbWFpbi5kLnRzXCIgLz5cclxuZXhwb3J0IGltcG9ydCBiZWF1dHlsb2cgPSByZXF1aXJlKFwiYmVhdXR5bG9nXCIpO1xyXG5leHBvcnQgbGV0IFEgPSByZXF1aXJlKFwicVwiKTtcclxuZXhwb3J0IGxldCBsb2Rhc2g9IHJlcXVpcmUoXCJsb2Rhc2hcIik7XHJcbiJdfQ==

87
docs/index.md Normal file
View File

@ -0,0 +1,87 @@
# taskbuffer
flexible task management. TypeScript ready!
## Availabililty
[![npm](https://pushrocks.gitlab.io/assets/repo-button-npm.svg)](https://www.npmjs.com/package/taskbuffer)
[![git](https://pushrocks.gitlab.io/assets/repo-button-git.svg)](https://GitLab.com/pushrocks/taskbuffer)
[![git](https://pushrocks.gitlab.io/assets/repo-button-mirror.svg)](https://github.com/pushrocks/taskbuffer)
[![docs](https://pushrocks.gitlab.io/assets/repo-button-docs.svg)](https://pushrocks.gitlab.io/taskbuffer/)
## Status for master
[![build status](https://GitLab.com/pushrocks/taskbuffer/badges/master/build.svg)](https://GitLab.com/pushrocks/taskbuffer/commits/master)
[![coverage report](https://GitLab.com/pushrocks/taskbuffer/badges/master/coverage.svg)](https://GitLab.com/pushrocks/taskbuffer/commits/master)
[![npm downloads per month](https://img.shields.io/npm/dm/taskbuffer.svg)](https://www.npmjs.com/package/taskbuffer)
[![Dependency Status](https://david-dm.org/pushrocks/taskbuffer.svg)](https://david-dm.org/pushrocks/taskbuffer)
[![bitHound Dependencies](https://www.bithound.io/github/pushrocks/taskbuffer/badges/dependencies.svg)](https://www.bithound.io/github/pushrocks/taskbuffer/master/dependencies/npm)
[![bitHound Code](https://www.bithound.io/github/pushrocks/taskbuffer/badges/code.svg)](https://www.bithound.io/github/pushrocks/taskbuffer)
[![TypeScript](https://img.shields.io/badge/TypeScript-2.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![node](https://img.shields.io/badge/node->=%206.x.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)
## Install
```sh
npm install taskbuffer --save
```
## Concepts
### class `Task`
- A Task in its most simple form is a function that is executed when the task runs.
- A Task can have a **preTask** and an **afterTask**
(those are run before or after the main function whenever the task is called)
- A Task can be buffered.
That means it can be called multiple times in a very short time.
However execution happens in line:
meaning execution of the task's main function is on halt until the previous task call has finished.
You can set bufferMax number, which is the max number of buffered task calls.
Any additional calls will then be truncated
- Task.trigger() and Task.triggerBuffered() always return a Promise
which is fullfilled once the related task call has completed.
- Task.triggered() is an Observable stream that emits events every time a task call is called and every time a call is completed.
- Task is compatible to gulp streams.
### class `TaskChain`
- TaskChain extends Task.
- Multiple Tasks can be combined in a bigger task using a TaskChain.
- While the tasks are async in themselve, TaskChain **runs Tasks serialized** (one after the other)
- that means that tasks can rely on each other and
### class `TaskParallel`
- TaskParallel extends Task.
- like TaskChain, however **tasks run in parallel**
- Tasks cannot rely on each other.
### Usage
We highly recommend TypeScript as this module supports **TypeScript intellisense**.
```javascript
import * as taskbuffer from "taskbuffer";
myTask = new taskbuffer.Task({
preTask: someOtherTask // optional, don't worry loops are prevented
afterTask: someOtherTask // optional, don't worry loops are prevented
name:"myTask1",
buffered: true, // optional
bufferMax: 3, // optional, call qeues greater than this are truncated
execDelay: 1000, // optional, time in ms to wait before executing task call
taskFunction:() => {
// do some stuff and return promise
// pass on any data through promise resolution
// Use TypeScript for better understanding and code completion
}
})
```
For further information read the linked docs at the top of this README.
> MIT licensed | **&copy;** [Lossless GmbH](https://lossless.gmbh)
[![repo-footer](https://pushrocks.gitlab.io/assets/repo-footer.svg)](https://push.rocks)

12
npmextra.json Normal file
View File

@ -0,0 +1,12 @@
{
"npmts":{
"mode":"default",
"testConfig": {
"parallel": false
}
},
"npmci": {
"npmGlobalTools": [],
"npmAccessLevel": "public"
}
}

View File

@ -1,4 +0,0 @@
{
"mode":"default",
"coveralls":true
}

1036
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,36 +1,43 @@
{
"name": "taskbuffer",
"version": "0.1.0",
"description": "manage triggers and execution of tasks with promises",
"name": "@pushrocks/taskbuffer",
"version": "2.0.0",
"description": "flexible task management. TypeScript ready!",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"scripts": {
"test": "(npmts)"
"test": "tstest test/",
"build": "echo \"Not needed for now\""
},
"repository": {
"type": "git",
"url": "git+https://github.com/pushrocks/taskbuffer.git"
"url": "git+https://gitlab.com/pushrocks/taskbuffer.git"
},
"keywords": [
"gulp",
"tasks",
"watch",
"buffer"
"task",
"buffer",
"TypeScript",
"push.rocks"
],
"author": "Lossless GmbH",
"license": "MIT",
"bugs": {
"url": "https://github.com/pushrocks/taskbuffer/issues"
"url": "https://gitlab.com/pushrocks/taskbuffer/issues"
},
"homepage": "https://github.com/pushrocks/taskbuffer#readme",
"homepage": "https://gitlab.com/pushrocks/taskbuffer#readme",
"dependencies": {
"beautylog": "^5.0.0",
"lodash": "^4.12.0",
"projectinfo": "1.0.1",
"q": "^1.4.1",
"rx": "^4.1.0"
"@pushrocks/lik": "^3.0.1",
"@pushrocks/smartdelay": "^2.0.1",
"@pushrocks/smartlog": "^2.0.1",
"@pushrocks/smartpromise": "^2.0.5",
"@types/cron": "^1.3.0",
"cron": "^1.3.0",
"rxjs": "^6.2.2"
},
"devDependencies": {
"should": "^8.3.1",
"npmts": "^5.1.5"
}
"@gitzone/tstest": "^1.0.7",
"@pushrocks/tapbundle": "^3.0.1",
"@types/node": "^10.5.4"
},
"private": true
}

33
readme.md Normal file
View File

@ -0,0 +1,33 @@
# @pushrocks/taskbuffer
flexible task management. TypeScript ready!
## Availabililty
[![npm](https://pushrocks.gitlab.io/assets/repo-button-npm.svg)](https://www.npmjs.com/package/taskbuffer)
[![git](https://pushrocks.gitlab.io/assets/repo-button-git.svg)](https://GitLab.com/pushrocks/taskbuffer)
[![git](https://pushrocks.gitlab.io/assets/repo-button-mirror.svg)](https://github.com/pushrocks/taskbuffer)
[![docs](https://pushrocks.gitlab.io/assets/repo-button-docs.svg)](https://pushrocks.gitlab.io/taskbuffer/)
## Status for master
[![build status](https://GitLab.com/pushrocks/taskbuffer/badges/master/build.svg)](https://GitLab.com/pushrocks/taskbuffer/commits/master)
[![coverage report](https://GitLab.com/pushrocks/taskbuffer/badges/master/coverage.svg)](https://GitLab.com/pushrocks/taskbuffer/commits/master)
[![npm downloads per month](https://img.shields.io/npm/dm/taskbuffer.svg)](https://www.npmjs.com/package/taskbuffer)
[![Dependency Status](https://david-dm.org/pushrocks/taskbuffer.svg)](https://david-dm.org/pushrocks/taskbuffer)
[![bitHound Dependencies](https://www.bithound.io/github/pushrocks/taskbuffer/badges/dependencies.svg)](https://www.bithound.io/github/pushrocks/taskbuffer/master/dependencies/npm)
[![bitHound Code](https://www.bithound.io/github/pushrocks/taskbuffer/badges/code.svg)](https://www.bithound.io/github/pushrocks/taskbuffer)
[![TypeScript](https://img.shields.io/badge/TypeScript-2.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![node](https://img.shields.io/badge/node->=%206.x.x-blue.svg)](https://nodejs.org/dist/latest-v6.x/docs/api/)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)
## Usage
Use TypeScript for best in class instellisense.
For further information read the linked docs at the top of this README.
> MIT licensed | **&copy;** [Lossless GmbH](https://lossless.gmbh)
> | By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy.html)
[![repo-footer](https://pushrocks.gitlab.io/assets/repo-footer.svg)](https://push.rocks)

118
test/test.1.task.ts Normal file
View File

@ -0,0 +1,118 @@
import { expect, tap } from '@pushrocks/tapbundle';
import taskbuffer = require('../ts/index');
import * as smartpromise from '@pushrocks/smartpromise';
import * as smartdelay from '@pushrocks/smartdelay';
// setup some testData to work with
let testTask: taskbuffer.Task;
let testPreTask = new taskbuffer.Task({
taskFunction: function() {
let done = smartpromise.defer();
console.log('preTask executed');
done.resolve();
return done.promise;
},
preTask: testTask
});
// some more tasks to test with
let task1Counter = 0; // how often task 1 is being executed
let task1 = new taskbuffer.Task({
name: 'Task 1',
taskFunction: () => {
let done = smartpromise.defer();
console.log('Task1 started');
setTimeout(() => {
task1Counter++;
console.log('Task1 executed');
done.resolve();
}, 5000);
return done.promise;
}
});
let task2 = new taskbuffer.Task({
name: 'Task 1',
taskFunction: () => {
let done = smartpromise.defer();
console.log('Task2 started');
setTimeout(() => {
console.log('Task2 executed');
done.resolve();
}, 5000);
return done.promise;
}
});
let task3 = new taskbuffer.Task({
name: 'Task 3',
taskFunction: () => {
let done = smartpromise.defer();
console.log('Task3 started');
setTimeout(() => {
console.log('Task3 executed');
done.resolve();
}, 5000);
return done.promise;
}
});
tap.test('new Task() should return a new task', async () => {
testTask = new taskbuffer.Task({
taskFunction: async () => {
console.log('executed twice');
},
preTask: testPreTask
});
});
tap.test('expect testTask to be an instance of Task', async () => {
expect(testTask).to.be.instanceof(taskbuffer.Task);
});
tap.test('expect testTask.idle is true', async () => {
if (!testTask.idle) {
throw new Error('testTask.idle is not true');
}
});
tap.test('testTask.running should be of type boolean and initially false', async () => {
expect(testTask.running).to.be.a('boolean');
// tslint:disable-next-line:no-unused-expression
expect(testTask.running).to.be.false;
});
tap.test('testTask.trigger() should return Promise', async () => {
expect(testTask.trigger()).to.be.instanceof(Promise);
});
tap.test('testTask.trigger() returned Promise should be fullfilled', async () => {
await testTask.trigger();
});
tap.test('expect to run a task without pre and afterTask errorless', async () => {
let localTestTask = new taskbuffer.Task({
taskFunction: async () => {
console.log('only once');
}
});
await localTestTask.trigger();
});
tap.test('expect task to run in buffered mode', async () => {
let localTestTask = new taskbuffer.Task({
taskFunction: async () => {
await smartdelay.delayFor(3000);
},
buffered: true,
bufferMax: 2
});
localTestTask.trigger();
localTestTask.trigger();
localTestTask.trigger();
await localTestTask.trigger();
});
tap.start();

48
test/test.2.taskchain.ts Normal file
View File

@ -0,0 +1,48 @@
import { expect, tap } from '@pushrocks/tapbundle';
import taskbuffer = require('../ts/index');
import * as smartq from 'smartq';
import * as smartdelay from '@pushrocks/smartdelay';
let task1Executed = false;
let task1 = new taskbuffer.Task({
taskFunction: async () => {
await smartdelay.delayFor(2000);
task1Executed = true;
}
});
let task2Executed = false;
let task2 = new taskbuffer.Task({
taskFunction: async () => {
await smartdelay.delayFor(2000);
task2Executed = true;
}
});
let task3Executed = false;
let task3 = new taskbuffer.Task({
taskFunction: async () => {
await smartdelay.delayFor(2000);
task3Executed = true;
}
});
tap.test('expect run tasks in sequence', async () => {
let testTaskchain = new taskbuffer.Taskchain({
name: 'Taskchain1',
taskArray: [task1, task2, task3]
});
let testPromise = testTaskchain.trigger();
await smartdelay.delayFor(2100);
// tslint:disable-next-line:no-unused-expression
expect(task1Executed).to.be.true;
// tslint:disable-next-line:no-unused-expression
expect(task2Executed).to.be.false;
await smartdelay.delayFor(2100);
// tslint:disable-next-line:no-unused-expression
expect(task2Executed).to.be.true;
await testPromise;
});
tap.start();

View File

@ -0,0 +1,38 @@
import { expect, tap } from '@pushrocks/tapbundle';
import taskbuffer = require('../ts/index');
import * as smartq from 'smartq';
import * as smartdelay from '@pushrocks/smartdelay';
let task1Executed = false;
let task1 = new taskbuffer.Task({
taskFunction: async () => {
await smartdelay.delayFor(2000);
task1Executed = true;
}
});
let task2Executed = false;
let task2 = new taskbuffer.Task({
taskFunction: async () => {
await smartdelay.delayFor(2000);
task2Executed = true;
}
});
let task3Executed = false;
let task3 = new taskbuffer.Task({
taskFunction: async () => {
await smartdelay.delayFor(2000);
task3Executed = true;
}
});
tap.test('expect run in Parallel', async () => {
let testTaskparallel = new taskbuffer.Taskparallel({
taskArray: [task1, task2, task3]
});
await testTaskparallel.trigger();
});
tap.start();

View File

@ -0,0 +1,42 @@
import { expect, tap } from '@pushrocks/tapbundle';
import taskbuffer = require('../ts/index');
import * as smartpromise from '@pushrocks/smartpromise';
import * as smartdelay from '@pushrocks/smartdelay';
let myTaskManager: taskbuffer.TaskManager;
let taskRunCounter = 0;
let taskDone = smartpromise.defer();
tap.test('should create an instance of TaskManager', async () => {
myTaskManager = new taskbuffer.TaskManager();
expect(myTaskManager).to.be.instanceof(taskbuffer.TaskManager);
});
tap.test('should run the task as expected', async () => {
let referenceBoolean = false;
myTaskManager.addTask(
new taskbuffer.Task({
name: 'myTask',
taskFunction: async () => {
console.log('Task executed!');
referenceBoolean = true;
taskRunCounter++;
if (taskRunCounter === 10) {
taskDone.resolve();
}
}
})
);
await myTaskManager.triggerTaskByName('myTask');
// tslint:disable-next-line:no-unused-expression
expect(referenceBoolean).to.be.true;
});
tap.test('should schedule task', async () => {
myTaskManager.scheduleTaskByName('myTask', '* * * * * *');
await taskDone.promise;
myTaskManager.descheduleTaskByName('myTask');
});
tap.start();

View File

@ -0,0 +1,64 @@
import { expect, tap } from '@pushrocks/tapbundle';
import taskbuffer = require('../ts/index');
import * as smartpromise from '@pushrocks/smartpromise';
import * as smartdelay from '@pushrocks/smartdelay';
let flowTask1 = new taskbuffer.Task({
taskFunction: (x: number) => {
let done = smartpromise.defer();
console.log('flowTask1');
console.log(x);
done.resolve(x);
return done.promise;
}
});
let flowTaskBuffered = new taskbuffer.Task({
taskFunction: (x: number) => {
let done = smartpromise.defer();
console.log('flowTask1');
console.log(x);
done.resolve(x);
return done.promise;
},
buffered: true,
bufferMax: 1
});
let flowTask2 = new taskbuffer.Task({
taskFunction: (x: number) => {
let done = smartpromise.defer();
console.log('flowTask2');
console.log(x);
done.resolve(x);
return done.promise;
},
preTask: flowTask1
});
let flowTask3 = new taskbuffer.Taskchain({
taskArray: [flowTask1, flowTask2]
});
tap.test('should let a value flow through a task', async () => {
let result = await flowTask1.trigger(12);
expect(result).to.equal(12);
});
tap.test('expect values to flow between tasks', async () => {
let result = await flowTask2.trigger(12);
expect(result).to.equal(12);
});
tap.test('expect values to flow between tasks when buffered', async () => {
let result = await flowTaskBuffered.trigger(12);
expect(result).to.equal(12);
});
tap.test('expect values to flow between tasks in Taskchain', async () => {
let result = await flowTask3.trigger(12);
expect(result).to.equal(12);
});
tap.start();

28
test/test.6.taskonce.ts Normal file
View File

@ -0,0 +1,28 @@
import { expect, tap } from '@pushrocks/tapbundle';
import * as taskbuffer from '../ts/index';
let myNumber = 0;
let myTaskOnce: taskbuffer.TaskOnce;
tap.test('should create a valid instance of TaskOnce', async () => {
myTaskOnce = new taskbuffer.TaskOnce({
taskFunction: async () => {
myNumber++;
}
});
expect(myTaskOnce).to.be.instanceof(taskbuffer.TaskOnce);
});
tap.test('myNumber should still be 0', async () => {
expect(myNumber).to.equal(0);
});
tap.test('myTaskOnce should trigger once', async () => {
await myTaskOnce.trigger();
await myTaskOnce.trigger();
await myTaskOnce.trigger();
expect(myNumber).to.equal(1);
});
tap.start();

0
test/test.d.ts vendored
View File

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
{"version":3,"file":"test.js","sourceRoot":"","sources":["test.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,IAAI,UAAU,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;AAC1C,IAAI,OAAO,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAAC;AACpD,IAAI,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AAC/B,QAAQ,CAAC,YAAY,EAAC;IAClB,QAAQ,CAAC,SAAS,EAAC;QACf,IAAI,QAAQ,CAAC;QACb,EAAE,CAAC,0CAA0C,EAAC;YAC1C,QAAQ,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAC;YACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,uBAAuB,EAAC;YACvB,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA,CAAC;gBAChB,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;YACjD,CAAC;QACL,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,sDAAsD,EAAC;YACtD,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC3C,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;QACvC,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}

View File

@ -1,84 +0,0 @@
/// <reference path="../ts/typings/main.d.ts" />
import taskbuffer = require("../dist/index");
let should = require("should");
let plugins = {
q: require("q")
}
// setup some testData to work with
let testTask:taskbuffer.Task;
let testTaskFunction = function(){
let done = plugins.q.defer();
console.log("main function executed!")
done.resolve();
return done.promise;
}
let testPreTask = new taskbuffer.Task({
taskFunction:function(){
console.log("preTask executed");
},
preTask:testTask
});
describe("taskbuffer",function(){
describe(".Task",function(){
it("new Task() should return a new task",function(){
testTask = new taskbuffer.Task({taskFunction:testTaskFunction,preTask:testPreTask});
});
it("testTask should be and instance of Task",function(){
testTask.should.be.instanceof(taskbuffer.Task);
});
it("testTask.idle is true",function(){
if (!testTask.idle){
throw new Error("testTask.idle is not true");
}
});
it("testTask.running is type boolean and initially false",function(){
testTask.running.should.be.type("boolean");
testTask.running.should.be.false();
});
it("testTask.trigger() should return Promise",function(){
testTask.trigger().should.be.Promise();
});
it("testTask.trigger() returned Promise should be fullfilled",function(done){
testTask.trigger()
.then(done);
});
it("should run a task without pre and afterTask",function(done){
let localTestTask = new taskbuffer.Task({taskFunction:testTaskFunction});
localTestTask.trigger().then(done);
});
});
describe("Taskchain",function(){
let testTaskchain;
let testTaskArray = [
new taskbuffer.Task({
name:"task1",
taskFunction:function(){
let done = plugins.q.defer();
console.log("Task1 run");
done.resolve();
return done.promise;
}
}),
new taskbuffer.Task({
name:"task2",
taskFunction: function(){
let done = plugins.q.defer();
console.log("Task2 run");
done.resolve();
return done.promise;
}
}),
];
it("should run tasks in sequence",function(done){
testTaskchain = new taskbuffer.Taskchain({
name:"Taskchain1",
taskArray:testTaskArray
});
testTaskchain.trigger().then(done);
});
});
});

View File

@ -1,5 +1,8 @@
/// <reference path="./typings/main.d.ts" />
export * from "./taskbuffer.classes";
export { Task, ITaskFunction } from './taskbuffer.classes.task';
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"
import './taskbuffer.classes.helpers';

View File

@ -1,97 +1,160 @@
/// <reference path="./typings/main.d.ts" />
import plugins = require("./taskbuffer.plugins");
import {Task} from "./taskbuffer.classes"
import plugins = require('./taskbuffer.plugins');
import { Task, ITaskFunction } from './taskbuffer.classes.task';
export let emptyTaskFunction = function(){
let done = plugins.Q.defer();
done.resolve();
return done.promise;
export let emptyTaskFunction: ITaskFunction = function(x) {
let done = plugins.smartpromise.defer();
done.resolve();
return done.promise;
};
export let isTask = function(taskArg):boolean{
if(
taskArg instanceof Task
&& typeof taskArg.task === "function"
){
return true;
} else {
return false;
}
export let isTask = function(taskArg: Task): boolean {
if (taskArg instanceof Task && typeof taskArg.taskFunction === 'function') {
return true;
} else {
return false;
}
};
export let isTaskTouched = (taskArg:Task, touchedTasksArray:Task[]):boolean => {
let result = false;
for (let keyArg in touchedTasksArray){
if(taskArg === touchedTasksArray[keyArg]){
result = true;
}
export let isTaskTouched = (taskArg: Task, touchedTasksArray: Task[]): boolean => {
let result = false;
for (let keyArg in touchedTasksArray) {
if (taskArg === touchedTasksArray[keyArg]) {
result = true;
}
return result;
}
return result;
};
export let runTask = async (taskArg: Task, optionsArg: { x?; touchedTasksArray?: Task[] }) => {
let 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
let options = {
...{ x: undefined, touchedTasksArray: [] },
...optionsArg
};
let x = options.x;
let touchedTasksArray: Task[] = options.touchedTasksArray;
touchedTasksArray.push(taskArg);
// run the task cascade
let localDeferred = plugins.smartpromise.defer();
localDeferred.promise
.then(() => {
if (taskArg.preTask && !isTaskTouched(taskArg.preTask, touchedTasksArray)) {
return runTask(taskArg.preTask, { x: x, touchedTasksArray: touchedTasksArray });
} else {
let done2 = plugins.smartpromise.defer();
done2.resolve(x);
return done2.promise;
}
})
.then(x => {
return taskArg.taskFunction(x);
})
.then(x => {
if (taskArg.afterTask && !isTaskTouched(taskArg.afterTask, touchedTasksArray)) {
return runTask(taskArg.afterTask, { x: x, touchedTasksArray: touchedTasksArray });
} else {
let 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 let runTask = function(taskArg:Task,optionsArg:{touchedTasksArray:Task[]} = {touchedTasksArray:[]}){
let done = plugins.Q.defer();
updateTaskStatus(taskArg,"running");
done.promise.then(function(){updateTaskStatus(taskArg,"idle")})
let localDeferred = plugins.Q.defer();
let touchedTasksArray:Task[];
if(optionsArg.touchedTasksArray){
touchedTasksArray = optionsArg.touchedTasksArray;
} else {
touchedTasksArray = [];
export class CycleCounter {
task: Task;
cycleObjectArray: cycleObject[] = [];
constructor(taskArg: Task) {
this.task = taskArg;
}
getPromiseForCycle(cycleCountArg: number) {
let done = plugins.smartpromise.defer();
let cycleObject: cycleObject = {
cycleCounter: cycleCountArg,
deferred: done
};
this.cycleObjectArray.push(cycleObject);
return done.promise;
}
informOfCycle(x) {
let 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++;
}
touchedTasksArray.push(taskArg);
localDeferred.promise
.then(() =>{
if(taskArg.preTask && !isTaskTouched(taskArg.preTask,touchedTasksArray)){
return runTask(taskArg.preTask,{touchedTasksArray:touchedTasksArray})
} else {
let done2 = plugins.Q.defer();
done2.resolve();
return done2.promise;
}
})
.then(() => {
return taskArg.task();
})
.then(() => {
if(taskArg.afterTask && !isTaskTouched(taskArg.afterTask,touchedTasksArray)){
return runTask(taskArg.afterTask,{touchedTasksArray:touchedTasksArray})
} else {
let done2 = plugins.Q.defer();
done2.resolve();
return done2.promise;
}
})
.then(() => {
done.resolve();
let returnPromise: Promise<any> = this.task.cycleCounter.getPromiseForCycle(
this.bufferCounter + 1
);
if (!this.running) {
this._run(x);
}
return returnPromise;
}
private _run(x) {
let 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);
});
localDeferred.resolve();
return done.promise;
};
export let runBufferedTask = (taskArg:Task) => {
let recursiveBufferRunner = () => {
if(taskArg.bufferCounter > 0){
taskArg.bufferCounter--;
runTask(taskArg)
.then(recursiveBufferRunner);
}
}
} else {
this.running = false;
this.task.running = false;
}
};
recursiveBufferRunner(x);
}
}
export let updateTaskStatus = (taskArg,statusArg:string) => {
switch (statusArg) {
case "running":
taskArg.running = true;
taskArg.idle = false;
break;
case "idle":
taskArg.running = false;
taskArg.idle = true;
break;
default:
throw new Error("status not recognised");
}
}

View File

@ -1,72 +1,106 @@
/// <reference path="./typings/main.d.ts" />
import * as plugins from "./taskbuffer.plugins"
import * as helpers from "./taskbuffer.classes.helpers"
import * as plugins from './taskbuffer.plugins';
import * as helpers from './taskbuffer.classes.helpers';
export interface ITaskFunction {
(x?: any): PromiseLike<any>;
}
export class Task {
name:string;
task:any;
running:boolean;
idle:boolean;
buffered:boolean;
bufferCounter:number;
bufferMax:number;
private _counterTriggerAbsolute:number;
private _state:string;
preTask:Task;
afterTask:Task;
// man datory properties
name: string;
taskFunction: ITaskFunction;
buffered: boolean;
constructor(optionsArg:{
taskFunction:any,
preTask?:Task,
afterTask?:Task,
buffered?:boolean,
bufferMax?:number,
name?:string
}){
if (!optionsArg){optionsArg = {taskFunction:function(){}}}
var options = optionsArg;
this.task = optionsArg.taskFunction;
this.preTask = options.preTask;
this.afterTask = options.afterTask;
this.running = false;
this.idle = true;
this.buffered = options.buffered;
this.bufferMax = options.bufferMax;
this.name = options.name;
}
trigger(){
let done = plugins.Q.defer();
if(this.buffered) {
this.triggerBuffered()
.then(done.resolve);
}
else {
this.triggerUnBuffered()
.then(done.resolve);
};
return done.promise;
};
triggerUnBuffered(){
return helpers.runTask(this);
}
triggerBuffered(){
var done = plugins.Q.defer();
if(!(this.bufferCounter >= this.bufferMax)){
this.bufferCounter++
}
helpers.runBufferedTask(this);
return done.promise;
}
bufferMax: number;
execDelay: number;
get state():string {
return this._state;
// tasks to run before and after
preTask: Task;
afterTask: Task;
// initialize by default
running: boolean = false;
bufferRunner = new helpers.BufferRunner(this);
cycleCounter = new helpers.CycleCounter(this);
idle: boolean = true;
private _state: string = 'ready';
constructor(optionsArg: {
/**
* the task function to run, must return promise
*/
taskFunction: ITaskFunction;
/**
* any other task to run before
*/
preTask?: Task;
/**
* any other task to run after
*/
afterTask?: Task;
/**
* wether this task should run buffered
*/
buffered?: boolean;
/**
* the maximum buffer
*/
bufferMax?: number;
/**
* the execution delay, before the task is executed
* only makes sense when running in buffered mode
*/
execDelay?: number;
/**
* the name of the task
*/
name?: string;
}) {
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;
}
/**
* trigger the task. Will trigger buffered if this.buffered is true
*/
trigger(x?): Promise<any> {
if (this.buffered) {
return this.triggerBuffered(x);
} else {
return this.triggerUnBuffered(x);
}
set state(stateArg:string){
if (stateArg == "locked"){
this._state = "locked";
} else {
plugins.beautylog.error("state type " + stateArg.blue + " could not be set");
}
}
/**
* trigger task unbuffered.
*/
triggerUnBuffered(x?): Promise<any> {
return helpers.runTask(this, { x: x });
}
/**
* trigger task buffered.
*/
triggerBuffered(x?): Promise<any> {
return this.bufferRunner.trigger(x);
}
get state(): string {
return this._state;
}
set state(stateArg: string) {
if (stateArg === 'locked') {
this._state = 'locked';
} else {
plugins.smartlog.defaultLogger.error('state type ' + stateArg + ' could not be set');
}
}
}
}

View File

@ -1,68 +1,58 @@
/// <reference path="./typings/main.d.ts" />
import * as plugins from "./taskbuffer.plugins";
import {Task} from "./taskbuffer.classes";
import helpers = require("./taskbuffer.classes.helpers");
// TaskChain chains tasks
// and extends Task
import * as plugins from './taskbuffer.plugins';
import { Task } from './taskbuffer.classes.task';
import helpers = require('./taskbuffer.classes.helpers');
export class Taskchain extends Task {
taskArray:Task[];
private _oraObject;
constructor(optionsArg:{
name?:string,
log?:boolean,
taskArray:Task[]
}){
let options = plugins.lodash.assign(
{
name:"unnamed Task",
log:false
},
optionsArg,
{
taskFunction: () => { // this is the function that gets executed when TaskChain is triggered
console.log("running taskchain function");
let done = plugins.Q.defer(); // this is the starting Deferred object
let taskCounter = 0;
let iterateTasks = () => {
if(typeof this.taskArray[taskCounter] != "undefined"){
this.taskArray[taskCounter].trigger()
.then(()=>{
taskCounter++;
iterateTasks();
});
} else {
done.resolve();
}
};
iterateTasks();
return done.promise;
}
taskArray: Task[];
constructor(optionsArg: {
taskArray: Task[];
name?: string;
log?: boolean;
buffered?: boolean;
bufferMax?: number;
}) {
let options = {
...{
name: 'unnamed Taskchain',
log: false
},
...optionsArg,
...{
taskFunction: (x: any) => {
// this is the function that gets executed when TaskChain is triggered
let done = plugins.smartpromise.defer(); // this is the starting Deferred object
let taskCounter = 0; // counter for iterating async over the taskArray
let iterateTasks = x => {
if (typeof this.taskArray[taskCounter] !== 'undefined') {
console.log(this.name + ' running: Task' + this.taskArray[taskCounter].name);
this.taskArray[taskCounter].trigger(x).then(x => {
plugins.smartlog.defaultLogger.info(this.taskArray[taskCounter].name);
taskCounter++;
iterateTasks(x);
});
} else {
console.log('Taskchain "' + this.name + '" completed successfully');
done.resolve(x);
}
);
super(options);
this.taskArray = optionsArg.taskArray;
this._oraObject = new plugins.beautylog.Ora("Taskchain idle","blue");
}
addTask(taskArg:Task){
this.taskArray.push(taskArg);
};
iterateTasks(x);
return done.promise;
}
}
};
removeTask(taskArg:Task){
//TODO
};
shiftTask(){
};
trigger(){
this._oraObject.start(this.name + " running...");
return helpers.runTask(this);
}
};
let myTask = new Taskchain(
{
taskArray: [
new Task({
taskFunction:function(){}
})
]
}
);
super(options);
this.taskArray = optionsArg.taskArray;
}
addTask(taskArg: Task) {
this.taskArray.push(taskArg);
}
removeTask(taskArg: Task) {
// TODO:
}
shiftTask() {
// TODO:
}
}

View File

@ -0,0 +1,95 @@
import * as plugins from './taskbuffer.plugins';
import { Task } from './taskbuffer.classes.task';
// interfaces
import { Objectmap } from '@pushrocks/lik';
export class TaskManager {
taskMap = new plugins.lik.Objectmap<Task>();
private cronJobMap = new plugins.lik.Objectmap<ICronJob>();
constructor() {
// nothing here
}
/**
* checks if a task is already present
* @param taskNameArg
*/
getTaskByName(taskNameArg): Task {
return this.taskMap.find(itemArg => {
return itemArg.name === taskNameArg;
});
}
/**
* adds a Task to the TaskManager
* @param taskArg
*/
addTask(taskArg: Task): void {
if (!taskArg.name) {
throw new Error('taskArg needs a name to be added to taskManager');
}
this.taskMap.add(taskArg);
}
/**
* adds and schedules a task at once
* @param taskArg
* @param cronStringArg
*/
addAndScheduleTask(taskArg: Task, cronStringArg: string) {
this.addTask(taskArg);
let taskName = taskArg.name;
this.scheduleTaskByName(taskName, cronStringArg);
}
/**
* triggers a task in the TaskManagerByName
* @param taskNameArg
*/
triggerTaskByName(taskNameArg: string): Promise<any> {
let taskToTrigger = this.getTaskByName(taskNameArg);
if (!taskToTrigger) {
throw new Error(`There is no task with the name of ${taskNameArg}`);
}
return taskToTrigger.trigger();
}
/**
* schedules the task by name
* @param taskNameArg
*/
scheduleTaskByName(taskNameArg: string, cronStringArg: string) {
let taskToSchedule = this.getTaskByName(taskNameArg);
let job = new plugins.cron.CronJob({
cronTime: cronStringArg,
onTick: () => {
this.triggerTaskByName(taskNameArg);
},
start: true
});
this.cronJobMap.add({
taskNameArg: taskToSchedule.name,
cronString: cronStringArg,
job: job
});
}
descheduleTaskByName(taskNameArg: string) {
let descheduledCron = this.cronJobMap.findOneAndRemove(itemArg => {
return itemArg.taskNameArg === taskNameArg;
});
descheduledCron.job.stop();
}
/**
* returns all schedules of a specific task
* @param taskNameArg
*/
getSchedulesForTaskName(taskNameArg: string) {}
}
export interface ICronJob {
cronString: string;
taskNameArg: string;
job: any;
}

View File

@ -0,0 +1,21 @@
import * as plugins from './taskbuffer.plugins';
import { Task, ITaskFunction } from './taskbuffer.classes.task';
/**
* TaskOnce is run exactly once, no matter how often it is triggered
*/
export class TaskOnce extends Task {
hasTriggered: boolean = false;
constructor(optionsArg: { name?: string; taskFunction: ITaskFunction }) {
super({
name: optionsArg.name,
taskFunction: async () => {
if (!this.hasTriggered) {
this.hasTriggered = true;
await optionsArg.taskFunction();
}
}
});
}
}

View File

@ -0,0 +1,25 @@
import * as plugins from './taskbuffer.plugins';
import * as helpers from './taskbuffer.classes.helpers';
import { Task } from './taskbuffer.classes.task';
export class Taskparallel extends Task {
taskArray: Task[];
constructor(optionsArg: { taskArray: Task[] }) {
const options = {
...optionsArg,
...{
taskFunction: () => {
let done = plugins.smartpromise.defer();
let promiseArray: Promise<any>[] = []; // stores promises of all tasks, since they run in parallel
this.taskArray.forEach(function(taskArg) {
promiseArray.push(taskArg.trigger());
});
Promise.all(promiseArray).then(done.resolve);
return done.promise;
}
}
};
super(options);
this.taskArray = optionsArg.taskArray;
}
}

View File

@ -1,2 +0,0 @@
export * from "./taskbuffer.classes.task"
export * from "./taskbuffer.classes.taskchain"

View File

@ -1,4 +1,8 @@
/// <reference path="./typings/main.d.ts" />
export import beautylog = require("beautylog");
export let Q = require("q");
export let lodash= require("lodash");
import * as smartlog from '@pushrocks/smartlog';
let cron = require('cron');
import * as lik from '@pushrocks/lik';
import * as rxjs from 'rxjs';
import * as smartpromise from '@pushrocks/smartpromise';
import * as smartdelay from '@pushrocks/smartdelay';
export { smartlog, cron, lik, rxjs, smartpromise, smartdelay };

View File

@ -1,8 +0,0 @@
{
"ambientDependencies": {
"colors": "github:DefinitelyTyped/DefinitelyTyped/colors/colors.d.ts",
"mocha": "github:Bartvds/tsd-deftools/typings/DefinitelyTyped/mocha/mocha.d.ts",
"node": "github:DefinitelyTyped/DefinitelyTyped/node/node.d.ts",
"should": "registry:dt/should#8.1.1+20160316155526"
}
}

3
tslint.json Normal file
View File

@ -0,0 +1,3 @@
{
"extends": "tslint-config-standard"
}