Skip to content

Commit e9b4616

Browse files
committed
initial commit
0 parents  commit e9b4616

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+10343
-0
lines changed

.circleci/config.yml

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
version: 2.1
2+
orbs:
3+
codecov: codecov/[email protected]
4+
5+
aliases:
6+
- &job-defaults
7+
docker:
8+
- image: circleci/node:12.13.0
9+
working_directory: ~/repo
10+
- &attach_workspace
11+
attach_workspace:
12+
at: ~/
13+
14+
jobs:
15+
setup:
16+
<<: *job-defaults
17+
steps:
18+
- checkout
19+
- run:
20+
command: yarn install --frozen-lockfile --non-interactive
21+
- persist_to_workspace:
22+
root: ~/
23+
paths:
24+
- ./repo
25+
26+
build:
27+
<<: *job-defaults
28+
steps:
29+
- *attach_workspace
30+
- run:
31+
command: yarn build
32+
- persist_to_workspace:
33+
root: ~/
34+
paths:
35+
- ./repo/dist
36+
37+
lint:
38+
<<: *job-defaults
39+
steps:
40+
- *attach_workspace
41+
- run:
42+
command: yarn lint:ci
43+
- store_test_results:
44+
path: reports/junit
45+
46+
test:
47+
<<: *job-defaults
48+
steps:
49+
- *attach_workspace
50+
- run:
51+
command: yarn test:cov
52+
- run:
53+
command: yarn test:e2e
54+
- store_test_results:
55+
path: reports/junit
56+
- codecov/upload:
57+
file: reports/coverage/cobertura-coverage.xml
58+
flags: unittests
59+
60+
61+
check-dependencies:
62+
<<: *job-defaults
63+
steps:
64+
- *attach_workspace
65+
- run:
66+
command: yarn check-dependencies
67+
68+
check-formatting:
69+
<<: *job-defaults
70+
steps:
71+
- *attach_workspace
72+
- run:
73+
command: yarn check-formatting
74+
75+
release:
76+
<<: *job-defaults
77+
steps:
78+
- *attach_workspace
79+
- run:
80+
command: yarn semantic-release
81+
82+
workflows:
83+
version: 2
84+
install-test-build-and-publish:
85+
jobs:
86+
- setup
87+
- build:
88+
requires:
89+
- setup
90+
- lint:
91+
requires:
92+
- setup
93+
- test:
94+
requires:
95+
- setup
96+
- check-dependencies:
97+
requires:
98+
- build
99+
- check-formatting:
100+
requires:
101+
- setup
102+
- release:
103+
filters:
104+
branches:
105+
only:
106+
- master
107+
requires:
108+
- build
109+
- lint
110+
- test
111+
- check-dependencies
112+
- check-formatting

.editorconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[*]
2+
charset=utf-8
3+
end_of_line=lf
4+
insert_final_newline=true
5+
indent_style=space
6+
indent_size=4
7+
trim_trailing_whitespace=true

.eslintrc.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module.exports = {
2+
parser: '@typescript-eslint/parser', // Specifies the ESLint parser
3+
extends: [
4+
'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
5+
'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
6+
'plugin:prettier/recommended' // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
7+
],
8+
parserOptions: {
9+
ecmaVersion: 2019, // Allows for the parsing of modern ECMAScript features
10+
sourceType: 'module' // Allows for the use of imports
11+
} /*,
12+
rules: {
13+
"sort-imports": "error"
14+
}*/
15+
};

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
/dist
3+
/reports

.npmignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
*
3+
!/dist/**
4+
!package.json
5+
!yarn.lock
6+
!README.md

.prettierignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package.json
2+
yarn.lock
3+
.git/
4+
dist/
5+
node_modules/
6+
documentation/
7+
reports/
8+
LICENSE
9+
.*

.prettierrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"singleQuote": true,
3+
"trailingComma": "none",
4+
"printWidth": 120,
5+
"quoteProps": "consistent"
6+
}

.releaserc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"branch": "master",
3+
"verifyConditions": "condition-circle",
4+
"plugins": [
5+
"@semantic-release/commit-analyzer",
6+
["@semantic-release/changelog", {
7+
"changelogFile": "CHANGELOG.md"
8+
}],
9+
"@semantic-release/release-notes-generator",
10+
"@semantic-release/npm",
11+
"@semantic-release/github"
12+
]
13+
}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License
2+
3+
Copyright (c) 2019 Ivan Hell
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# ntsu - Node.js task scheduling utilities
2+
3+
[![Build Status](https://img.shields.io/circleci/build/github/hellivan/node-task-scheduling-utilities/master?logo=circleci&style=flat-square)](https://circleci.com/gh/hellivan/node-task-scheduling-utilities)
4+
[![Code Coverage](https://img.shields.io/codecov/c/github/hellivan/node-task-scheduling-utilities/master?logo=codecov&style=flat-square)](https://codecov.io/gh/hellivan/node-task-scheduling-utilities)
5+
[![MIT License](https://img.shields.io/npm/l/node-task-scheduling-utilities?style=flat-square)](LICENSE)
6+
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square)](https://github.com/semantic-release/semantic-release)
7+
[![Renovate enabled](https://img.shields.io/badge/renovate-enabled-brightgreen.svg?style=flat-square)](https://renovatebot.com/)
8+
[![NPM Package](https://img.shields.io/npm/v/node-task-scheduling-utilities?logo=npm&style=flat-square)](https://www.npmjs.com/package/node-task-scheduling-utilities)
9+
[![NPM Package Downloads](https://img.shields.io/npm/dm/node-task-scheduling-utilities?logo=npm&style=flat-square)](https://www.npmjs.com/package/node-task-scheduling-utilities)
10+
11+
Utility library that provides some basic mechanisms for task scheduling/execution in Node.js
12+
13+
## Installation
14+
15+
Using npm:
16+
17+
```
18+
npm install --save ntsu
19+
```
20+
21+
Using yarn
22+
23+
```
24+
yarn add ntsu
25+
```
26+
27+
## Usage
28+
29+
In ES6 / Typescript
30+
31+
```typescript
32+
import { DynamicWorkerPool, QdScheduler, WorkerThreadWorker } from 'ntsu';
33+
```
34+
35+
### QdScheduler
36+
37+
Queued task scheduler that executes provided tasks one after another or in parallel, depending on the provided
38+
configuration. Tasks that cannot be executed immediately are queued for later execution. Queued tasks are executed as
39+
soon as running tasks complete:
40+
41+
```typescript
42+
import { QdScheduler } from 'ntsu';
43+
44+
// create new queued scheduler that can execute 3 tasks in parallel
45+
// and is able to queue up to 100 tasks
46+
const scheduler = new QdScheduler(3, 100);
47+
48+
for (let i = 0; i < 100; i++) {
49+
scheduler.queueTask({ exec: () => complexFunction(i) });
50+
}
51+
52+
scheduler.start();
53+
```
54+
55+
### DynamicWorkerPool
56+
57+
Generic worker pool that dynamically instantiates new workers as needed. Initially the pool
58+
will be empty. When tasks are added for execution, the pool will create up to maxSize new workers
59+
that will execute the given tasks. After task execution, all superfluous workers are disposed after a given
60+
worker-idle timeout so that only minSize workers will remain in the pool. These workers are then reused in
61+
future task executions.
62+
63+
```typescript
64+
import { DynamicWorkerPool } from 'ntsu';
65+
66+
// create new dynamic worker pool that uses workerFactory to instantiate new workers
67+
// and has a max size of 10. The pool will keep at least 3 idle workers. Workers are
68+
// considered idle if no task is assigned withing 3 seconds
69+
const pool = new DynamicWorkerPool(workerFactory, 3, 10, 3000);
70+
71+
const results = Promise.all(tasks.map((task) => scheduler.executeTask(task)));
72+
```
73+
74+
### WorkerThreadWorker
75+
76+
WorkerPool worker implementation that is based on node.js `worker_threads`. This Worker implementation
77+
will automatically create a new `worker_thread` based on the given script path and post the task's data
78+
via `postMessage` method. Worker threads will be instantiated in a lazy way (as soon as `executeTask` is
79+
called for the first time). If `worker_thread` fails or exits before emitting a repsonse message via `postMessage`
80+
method, result-promise of `executeTask` will reject with an appropriate error message. `worker_thread`
81+
termination or failure between task-execution will also be catched by this implemenation. If `worker_thread`
82+
errors or terminates a new `worker_thread` will be instantiated upon next task execution.
83+
84+
```typescript
85+
import { DynamicWorkerPool, WorkerThreadWorker } from 'ntsu';
86+
87+
// create new dynamic worker pool that uses workerFactory to instantiate new workers
88+
// and has a max size of 10. The pool will keep at least 3 idle workers if
89+
const pool = new DynamicWorkerPool(
90+
{
91+
createWorker: () => new WorkerThreadWorker('workerThreadScript.js')
92+
},
93+
3,
94+
10
95+
);
96+
```
97+
98+
Where an example `worker_thread` script could be:
99+
100+
```js
101+
// workerThreadScript.js
102+
103+
const { parentPort } = require('worker_threads');
104+
105+
parentPort.on('message', (message) => {
106+
parentPort.postMessage(`Hello "${message}"!`);
107+
});
108+
```

jest.config.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"rootDir": "src",
3+
"testRegex": ".spec.ts$",
4+
"transform": {
5+
"^.+\\.(t|j)s$": "ts-jest"
6+
},
7+
"testEnvironment": "node",
8+
"reporters": [
9+
"default",
10+
[
11+
"jest-html-reporter",
12+
{
13+
"outputPath": "../reports/html/jest.junit.html",
14+
"includeFailureMsg": true
15+
}
16+
],
17+
[
18+
"jest-junit",
19+
{
20+
"outputDirectory": "./reports/junit/",
21+
"outputName": "jest.junit.xml"
22+
}
23+
]
24+
],
25+
"coverageDirectory": "../reports/coverage",
26+
"coverageReporters": ["html", "text", "text-summary", "cobertura"],
27+
"coverageThreshold": {
28+
"global": {
29+
"statements": 100,
30+
"branches": 100,
31+
"functions": 100,
32+
"lines": 100
33+
}
34+
},
35+
"testRunner": "jest-circus/runner"
36+
}

0 commit comments

Comments
 (0)