clever-queue 0.1.2 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitlab-ci.yml +79 -0
- package/README.md +66 -6
- package/dist/engine/index.d.ts +14 -10
- package/dist/engine/index.js +45 -46
- package/dist/engine/index.js.map +1 -1
- package/dist/engine/interfaces.d.ts +3 -2
- package/dist/engine/interfaces.js.map +1 -1
- package/dist/helpers/id.d.ts +2 -0
- package/dist/helpers/id.js +7 -0
- package/dist/helpers/id.js.map +1 -0
- package/dist/helpers/index.d.ts +1 -0
- package/dist/helpers/index.js +19 -8
- package/dist/helpers/index.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.js +25 -15
- package/dist/index.js.map +1 -1
- package/dist/{queue → queues}/index.d.ts +8 -5
- package/dist/{queue → queues}/index.js +27 -33
- package/dist/queues/index.js.map +1 -0
- package/dist/{queue → queues}/interfaces.d.ts +9 -4
- package/dist/{queue → queues}/interfaces.js +4 -2
- package/dist/queues/interfaces.js.map +1 -0
- package/dist/{runner → runners}/index.d.ts +7 -3
- package/dist/{runner → runners}/index.js +33 -15
- package/dist/runners/index.js.map +1 -0
- package/dist/{runner → runners}/interfaces.d.ts +2 -1
- package/dist/{runner → runners}/interfaces.js +1 -1
- package/dist/runners/interfaces.js.map +1 -0
- package/dist/{task → tasks}/index.d.ts +8 -2
- package/dist/{task → tasks}/index.js +27 -15
- package/dist/tasks/index.js.map +1 -0
- package/dist/{task → tasks}/interfaces.d.ts +1 -0
- package/dist/tasks/interfaces.js.map +1 -0
- package/documentation/demo_1E_1Q_1R_4T.svg +1 -0
- package/documentation/demo_1E_1Q_2R_4T.svg +1 -0
- package/documentation/demo_1E_2Q_1R_8T.svg +1 -0
- package/eslint.config.mjs +68 -68
- package/examples/package-lock.json +19 -0
- package/examples/package.json +15 -0
- package/examples/src/demo_1E_1Q_1R_4T.ts +37 -0
- package/examples/src/demo_1E_1Q_2R_4T.ts +36 -0
- package/examples/src/demo_1E_2Q_1R_8T.ts +40 -0
- package/examples/src/example00.ts +16 -0
- package/examples/src/helpers/animations.ts +295 -0
- package/examples/src/helpers/index.ts +2 -0
- package/examples/src/helpers/myAsyncTaskToExecute.ts +6 -0
- package/examples/src/helpers/svg.ts +155 -0
- package/examples/src/tsconfig.json +24 -0
- package/package.json +16 -6
- package/src/engine/index.ts +37 -48
- package/src/engine/interfaces.ts +3 -2
- package/src/helpers/id.ts +4 -0
- package/src/helpers/index.ts +1 -0
- package/src/index.ts +7 -7
- package/src/{queue → queues}/index.ts +11 -28
- package/src/{queue → queues}/interfaces.ts +4 -3
- package/src/{runner → runners}/index.ts +17 -12
- package/src/{runner → runners}/interfaces.ts +2 -1
- package/src/{task → tasks}/index.ts +11 -10
- package/src/{task → tasks}/interfaces.ts +1 -0
- package/test/issues/00001.mjs +1 -1
- package/test/miscellaneous/test.mjs +13 -13
- package/test/units/engine.mjs +5 -5
- package/test/units/queue.mjs +4 -4
- package/test/units/task.mjs +6 -6
- package/dist/errors.d.ts +0 -13
- package/dist/errors.js +0 -42
- package/dist/errors.js.map +0 -1
- package/dist/queue/index.js.map +0 -1
- package/dist/queue/interfaces.js.map +0 -1
- package/dist/runner/index.js.map +0 -1
- package/dist/runner/interfaces.js.map +0 -1
- package/dist/task/index.js.map +0 -1
- package/dist/task/interfaces.js.map +0 -1
- package/exemples/index01.js +0 -116
- package/exemples/index01.ts +0 -98
- package/exemples/index02.mjs +0 -13
- package/exemples/tsconfig.json +0 -24
- /package/dist/{task → tasks}/interfaces.js +0 -0
package/src/engine/index.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// clever-queue
|
|
2
2
|
|
|
3
3
|
import * as _ from "../helpers";
|
|
4
|
-
import * as
|
|
5
|
-
import * as
|
|
6
|
-
import * as
|
|
4
|
+
import * as cqQueue from "../queues";
|
|
5
|
+
import * as cqRunner from "../runners";
|
|
6
|
+
import * as cqTask from "../tasks";
|
|
7
7
|
|
|
8
8
|
type Status = "unknown" | "initialiazing" | "running" | "stopping" | "destroying";
|
|
9
9
|
|
|
10
|
-
const TICK_START = 42;
|
|
10
|
+
const TICK_START = 42; // RANDOM ? ;-) value to avoid zero division
|
|
11
11
|
|
|
12
12
|
import { Options, Statistics, ErrorsList } from "./interfaces";
|
|
13
13
|
|
|
@@ -19,18 +19,21 @@ const defaultOptions: Options = {
|
|
|
19
19
|
|
|
20
20
|
class Engine {
|
|
21
21
|
status: Status = "unknown";
|
|
22
|
-
readonly
|
|
23
|
-
|
|
22
|
+
readonly options: Options;
|
|
23
|
+
tags: { [key: string]: string | number | boolean } = {};
|
|
24
|
+
readonly runners: cqRunner.Runner[] = [];
|
|
25
|
+
readonly queues: cqQueue.Queue[] = [];
|
|
24
26
|
|
|
25
27
|
constructor(opt: Options) {
|
|
26
28
|
this.status = "initialiazing";
|
|
27
|
-
|
|
28
|
-
this
|
|
29
|
+
this.options = { ...defaultOptions, ...opt };
|
|
30
|
+
if (!this.options.id) this.options.id = _.Id.generate();
|
|
31
|
+
this.#checkOptionsConsistancy(this.options);
|
|
29
32
|
|
|
30
33
|
// create runners
|
|
31
|
-
for (let index = 0; index < (options.bestEffortRunners ?? 0); index++) this.createRunner({ priority:
|
|
32
|
-
if (options.logFunction) options.logFunction({ body: "engine has been initialized" });
|
|
33
|
-
if (options.autostart) this.start();
|
|
34
|
+
for (let index = 0; index < (this.options.bestEffortRunners ?? 0); index++) this.createRunner({ priority: cqRunner.Priorities.BestEffort });
|
|
35
|
+
if (this.options.logFunction) this.options.logFunction({ body: "engine has been initialized" });
|
|
36
|
+
if (this.options.autostart) this.start();
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
start(): void {
|
|
@@ -43,21 +46,21 @@ class Engine {
|
|
|
43
46
|
for (const runner of this.runners) runner.stop();
|
|
44
47
|
}
|
|
45
48
|
|
|
46
|
-
createQueue(options:
|
|
47
|
-
const queue = new
|
|
49
|
+
createQueue(options: cqQueue.Options = { priority: cqQueue.Priorities.Standard, weight: cqQueue.Weights.Default }): cqQueue.Queue {
|
|
50
|
+
const queue = new cqQueue.Queue({ logFunction: options.logFunction, ...options });
|
|
48
51
|
this.queues.push(queue);
|
|
49
52
|
this.#resetLastTick(options.priority);
|
|
50
53
|
return queue;
|
|
51
54
|
}
|
|
52
55
|
|
|
53
|
-
createRunner(options:
|
|
54
|
-
const runner = new
|
|
56
|
+
createRunner(options: cqRunner.Options): cqRunner.Runner {
|
|
57
|
+
const runner = new cqRunner.Runner({ logFunction: options.logFunction, ...options }, this);
|
|
55
58
|
this.runners.push(runner);
|
|
56
59
|
return runner;
|
|
57
60
|
}
|
|
58
61
|
|
|
59
|
-
createTask(function_:
|
|
60
|
-
return new
|
|
62
|
+
createTask(function_: cqTask.FunctionToExecute, options: cqTask.Options): cqTask.Task {
|
|
63
|
+
return new cqTask.Task(function_, { logFunction: options.logFunction, ...options });
|
|
61
64
|
}
|
|
62
65
|
|
|
63
66
|
#checkOptionsConsistancy(options: Options): void {
|
|
@@ -65,19 +68,25 @@ class Engine {
|
|
|
65
68
|
if (!options.bestEffortRunners || options.bestEffortRunners < 1) throw new _.Errors.CQError(ErrorsList.bestEffortRunnersOptionMustBeGreaterThanZero);
|
|
66
69
|
}
|
|
67
70
|
|
|
68
|
-
#getSumWeightFunction:
|
|
71
|
+
#getSumWeightFunction: cqQueue.GetSumWeightFunction = (priority: number): number => {
|
|
69
72
|
let result = 0;
|
|
70
73
|
for (const q of this.queues) if (q.options.priority === priority) result += q.options.weight;
|
|
71
74
|
return result;
|
|
72
75
|
};
|
|
73
76
|
|
|
74
77
|
#resetLastTick(priority: number): void {
|
|
75
|
-
for (
|
|
78
|
+
for (let i = 0; i < this.queues.length; i++) {
|
|
79
|
+
const q = this.queues[i];
|
|
80
|
+
if (q.options.priority === priority)
|
|
81
|
+
q.tick = TICK_START
|
|
82
|
+
+ this.#getSumWeightFunction(priority) / q.options.weight // set tick to max weight / queue weight to favorize low weight queues
|
|
83
|
+
+ i / 255; // slight increment to favorize first created queues
|
|
84
|
+
}
|
|
76
85
|
}
|
|
77
86
|
|
|
78
|
-
#getNextWeightedQueue(priority: number):
|
|
87
|
+
#getNextWeightedQueue(priority: number): cqQueue.Queue | undefined {
|
|
79
88
|
let minTick = Infinity;
|
|
80
|
-
let result:
|
|
89
|
+
let result: cqQueue.Queue | undefined = undefined;
|
|
81
90
|
for (const q of this.queues)
|
|
82
91
|
if (q.options.priority === priority && q.tick <= minTick) {
|
|
83
92
|
minTick = q.tick;
|
|
@@ -91,32 +100,12 @@ class Engine {
|
|
|
91
100
|
for (const q of this.queues) if (q.options.priority === priority) result += q.tasks.length;
|
|
92
101
|
return result;
|
|
93
102
|
}
|
|
94
|
-
/*
|
|
95
|
-
async getNextTask(priorityGreaterOrEqualTo: number): Promise<Task.Task> {
|
|
96
|
-
for (let priority = Queue.Priorities.Absolute; priority <= priorityGreaterOrEqualTo; priority++) {
|
|
97
|
-
// Iterate on Each PriorityLevel From Absolute to param function
|
|
98
|
-
while (this.#howMuchTasksWaitingInQueues(priority) > 0) {
|
|
99
|
-
let task: Task.Task | undefined;
|
|
100
|
-
while (!task) {
|
|
101
|
-
const nextPriorityQueue = this.#getNextQueue(priority); // Find Next Priority Queue to process
|
|
102
|
-
if (nextPriorityQueue) {
|
|
103
|
-
nextPriorityQueue.tick += this.#getSumWeightFunction(priority) / nextPriorityQueue.options.weight; // Update tick with related weight
|
|
104
|
-
if (nextPriorityQueue.tasks.length > 0) {
|
|
105
|
-
task = nextPriorityQueue.tasks.shift(); // If queue is not empty, this is our next Task to process
|
|
106
|
-
if (task) task.runner();
|
|
107
|
-
console.log(nextPriorityQueue.options.name, nextPriorityQueue.tick);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
*/
|
|
115
103
|
|
|
116
|
-
async getNextTask(priorityGreaterOrEqualTo: number): Promise<
|
|
117
|
-
|
|
104
|
+
async getNextTask(priorityGreaterOrEqualTo: number): Promise<cqTask.Task | undefined> {
|
|
105
|
+
if (this.status !== "running") return undefined;
|
|
106
|
+
let task: cqTask.Task | undefined = undefined;
|
|
118
107
|
// Iterate on Each PriorityLevel From Absolute to parameter
|
|
119
|
-
for (let priority =
|
|
108
|
+
for (let priority = cqQueue.Priorities.Absolute; priority >= priorityGreaterOrEqualTo; priority--) {
|
|
120
109
|
// Check if there is task waiting of this priority level
|
|
121
110
|
while (this.#howMuchTasksWaitingInQueues(priority) > 0) {
|
|
122
111
|
// Find Next Weighted Queue of this priority level to check
|
|
@@ -138,8 +127,8 @@ class Engine {
|
|
|
138
127
|
|
|
139
128
|
statistics(): Statistics {
|
|
140
129
|
let taskCount = 0;
|
|
141
|
-
const runners:
|
|
142
|
-
const queues:
|
|
130
|
+
const runners: cqRunner.Statistics[] = [];
|
|
131
|
+
const queues: cqQueue.Statistics[] = [];
|
|
143
132
|
for (const runner of this.runners) {
|
|
144
133
|
if (runner.status == "running") taskCount += 1;
|
|
145
134
|
runners.push(runner.statistics());
|
|
@@ -162,5 +151,5 @@ class Engine {
|
|
|
162
151
|
}
|
|
163
152
|
}
|
|
164
153
|
|
|
165
|
-
export { Options, Statistics, ErrorsList } from "./interfaces";
|
|
154
|
+
export { Options, Statistics, ErrorsList, LogFunction } from "./interfaces";
|
|
166
155
|
export { Engine };
|
package/src/engine/interfaces.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as _ from "../helpers";
|
|
2
2
|
|
|
3
|
-
import * as Runner from "../
|
|
4
|
-
import * as Queue from "../
|
|
3
|
+
import * as Runner from "../runners/interfaces";
|
|
4
|
+
import * as Queue from "../runners/interfaces";
|
|
5
5
|
|
|
6
6
|
interface Options {
|
|
7
|
+
id?: string;
|
|
7
8
|
autostart?: boolean;
|
|
8
9
|
bestEffortRunners?: number;
|
|
9
10
|
logFunction?: _.Logs.LogFunction;
|
package/src/helpers/index.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// clever-queue
|
|
2
|
-
import * as
|
|
2
|
+
import * as engine from "./engine";
|
|
3
3
|
|
|
4
|
-
function createEngine(options:
|
|
5
|
-
return new
|
|
4
|
+
function createEngine(options: engine.Options = {}): engine.Engine {
|
|
5
|
+
return new engine.Engine(options);
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
export * as
|
|
9
|
-
export * as
|
|
10
|
-
export * as
|
|
11
|
-
export * as
|
|
8
|
+
export * as engine from "./engine";
|
|
9
|
+
export * as runners from "./runners";
|
|
10
|
+
export * as queues from "./queues";
|
|
11
|
+
export * as tasks from "./tasks";
|
|
12
12
|
|
|
13
13
|
export { createEngine };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// clever-queue
|
|
2
2
|
|
|
3
3
|
import * as _ from "../helpers";
|
|
4
|
-
import * as
|
|
4
|
+
import * as cqTask from "../tasks";
|
|
5
5
|
import { Options, Statistics, ErrorsList, Priorities } from "./interfaces";
|
|
6
6
|
|
|
7
7
|
type GetSumWeightFunction = (priority: number) => number;
|
|
@@ -18,12 +18,15 @@ const defaultOptions: Options = {
|
|
|
18
18
|
class Queue {
|
|
19
19
|
status: Status = "unknown";
|
|
20
20
|
readonly options: Options;
|
|
21
|
+
tags: { [key: string]: string | number | boolean } = {};
|
|
22
|
+
|
|
21
23
|
tick: number = 0;
|
|
22
|
-
tasks:
|
|
24
|
+
tasks: cqTask.Task[] = [];
|
|
23
25
|
|
|
24
26
|
constructor(opt: Options) {
|
|
25
27
|
this.status = "initialiazing";
|
|
26
28
|
this.options = this.#checkOptionsConsistancy({ ...defaultOptions, ...opt });
|
|
29
|
+
if (!this.options.id) this.options.id = _.Id.generate();
|
|
27
30
|
if (this.options.autostart) this.start();
|
|
28
31
|
}
|
|
29
32
|
|
|
@@ -43,34 +46,14 @@ class Queue {
|
|
|
43
46
|
this.status = "stopping";
|
|
44
47
|
}
|
|
45
48
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (typeof function_ !== "function") {
|
|
49
|
-
console.error("raisong Task.ErrorsList.FunctionIsNotAFunction", Task.ErrorsList.FunctionIsNotAFunction);
|
|
50
|
-
throw new _.Errors.CQError(Task.ErrorsList.FunctionIsNotAFunction);
|
|
51
|
-
}
|
|
52
|
-
return new Promise((resolve, reject) => {
|
|
53
|
-
try {
|
|
54
|
-
const taskRunner = async (): Promise<void> => {
|
|
55
|
-
console.log("running Task");
|
|
56
|
-
const result = await function_();
|
|
57
|
-
console.log("task runned", result);
|
|
58
|
-
resolve(result);
|
|
59
|
-
};
|
|
60
|
-
const task = new Task.Task(taskRunner, {});
|
|
61
|
-
this.tasks.push(task);
|
|
62
|
-
} catch (error) {
|
|
63
|
-
reject(error);
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
*/
|
|
68
|
-
async createTaskAndEnqueue(function_: Task.FunctionToExecute, options: Task.Options): Promise<unknown> {
|
|
69
|
-
const task = new Task.Task(function_, options);
|
|
49
|
+
async createTaskAndEnqueue(function_: cqTask.FunctionToExecute, options: cqTask.Options = {}): Promise<unknown> {
|
|
50
|
+
const task = new cqTask.Task(function_, options);
|
|
70
51
|
return this.enqueue(task);
|
|
71
52
|
}
|
|
72
53
|
|
|
73
|
-
async enqueue(task:
|
|
54
|
+
async enqueue(task: cqTask.Task): Promise<unknown> {
|
|
55
|
+
task.status = "queued";
|
|
56
|
+
task.queueId = this.options.id; // store queue that handle task for future references
|
|
74
57
|
return new Promise((resolve, reject) => {
|
|
75
58
|
task.resolver = resolve;
|
|
76
59
|
task.rejecter = reject;
|
|
@@ -89,5 +72,5 @@ class Queue {
|
|
|
89
72
|
}
|
|
90
73
|
}
|
|
91
74
|
|
|
92
|
-
export { Options, Statistics, ErrorsList, Priorities } from "./interfaces";
|
|
75
|
+
export { Options, Statistics, ErrorsList, Priorities, Weights } from "./interfaces";
|
|
93
76
|
export { Queue, GetSumWeightFunction };
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as _ from "../helpers";
|
|
2
2
|
|
|
3
|
-
const Priorities = {
|
|
3
|
+
const Priorities = { BestEffort: 0, Standard: 128, Absolute: 255};
|
|
4
|
+
const Weights = { Lowest: 0, Default: 128, Highest: 255 };
|
|
4
5
|
|
|
5
6
|
interface Options {
|
|
6
|
-
|
|
7
|
+
id?: string;
|
|
7
8
|
priority: number;
|
|
8
9
|
weight: number;
|
|
9
10
|
autostart?: boolean;
|
|
@@ -35,4 +36,4 @@ const ErrorsList: {
|
|
|
35
36
|
NoOptionsOnQueueInitialization: { name: "NoOptionsOnQueueInitialization", message: "You must provide an options parameter to Queue" },
|
|
36
37
|
};
|
|
37
38
|
|
|
38
|
-
export { Options, Statistics, ErrorsList, Priorities };
|
|
39
|
+
export { Options, Statistics, ErrorsList, Priorities, Weights };
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
import * as _ from "../helpers";
|
|
4
4
|
import { Options, Statistics, ErrorsList, Priorities } from "./interfaces";
|
|
5
|
-
import
|
|
5
|
+
import * as cqEngine from "../engine";
|
|
6
6
|
|
|
7
7
|
export * from "./interfaces";
|
|
8
8
|
|
|
9
|
-
type Status = "unknown" | "initialiazing" | "running" | "stopping" | "destroying";
|
|
9
|
+
type Status = "unknown" | "initialiazing" | "idle" | "running" | "stopping" | "destroying";
|
|
10
10
|
|
|
11
11
|
const defaultOptions: Options = {
|
|
12
12
|
priority: Priorities.BestEffort,
|
|
@@ -16,14 +16,16 @@ const defaultOptions: Options = {
|
|
|
16
16
|
|
|
17
17
|
class Runner {
|
|
18
18
|
status: Status = "unknown";
|
|
19
|
-
readonly
|
|
20
|
-
|
|
19
|
+
readonly options: Options;
|
|
20
|
+
tags: { [key: string]: string | number | boolean } = {};
|
|
21
|
+
readonly #engine: cqEngine.Engine;
|
|
21
22
|
|
|
22
|
-
constructor(opt: Options, engine: Engine) {
|
|
23
|
+
constructor(opt: Options, engine: cqEngine.Engine) {
|
|
23
24
|
this.status = "initialiazing";
|
|
24
|
-
this
|
|
25
|
+
this.options = this.#checkOptionsConsistancy({ ...defaultOptions, ...opt });
|
|
26
|
+
if (!this.options.id) this.options.id = _.Id.generate();
|
|
25
27
|
this.#engine = engine; // Store parent engine for later callbacks
|
|
26
|
-
if (this
|
|
28
|
+
if (this.options.autostart) this.start();
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
#checkOptionsConsistancy(options: Options): Options {
|
|
@@ -32,18 +34,21 @@ class Runner {
|
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
async #run(): Promise<void> {
|
|
35
|
-
while (
|
|
37
|
+
while (["idle", "running"].includes(this.status)) {
|
|
36
38
|
await new Promise((resolve) => setTimeout(resolve, 10)); // Do not freeze the event loop with infinite loop.
|
|
37
39
|
// get the next task to run according to this runner priority
|
|
38
|
-
const task = await this.#engine.getNextTask(this
|
|
40
|
+
const task = await this.#engine.getNextTask(this.options.priority);
|
|
39
41
|
if (task) {
|
|
40
|
-
|
|
42
|
+
if (this.status === "idle") this.status = "running";
|
|
43
|
+
task.runnerId = this.options.id; // store runner that handle task for future references
|
|
44
|
+
await task.run();
|
|
45
|
+
if (this.status === "running") this.status = "idle";
|
|
41
46
|
}
|
|
42
47
|
}
|
|
43
48
|
}
|
|
44
49
|
|
|
45
50
|
start(): void {
|
|
46
|
-
this.status = "
|
|
51
|
+
this.status = "idle";
|
|
47
52
|
this.#run();
|
|
48
53
|
}
|
|
49
54
|
|
|
@@ -54,7 +59,7 @@ class Runner {
|
|
|
54
59
|
statistics(): Statistics {
|
|
55
60
|
const stat: Statistics = {
|
|
56
61
|
status: this.status,
|
|
57
|
-
priority: this
|
|
62
|
+
priority: this.options.priority,
|
|
58
63
|
};
|
|
59
64
|
return stat;
|
|
60
65
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as _ from "../helpers";
|
|
2
2
|
|
|
3
3
|
interface Options {
|
|
4
|
+
id?: string;
|
|
4
5
|
autostart?: boolean;
|
|
5
6
|
priority: number;
|
|
6
7
|
logFunction?: _.Logs.LogFunction;
|
|
@@ -20,5 +21,5 @@ const ErrorsList: {
|
|
|
20
21
|
},
|
|
21
22
|
};
|
|
22
23
|
|
|
23
|
-
export { Priorities } from "../
|
|
24
|
+
export { Priorities } from "../queues/interfaces";
|
|
24
25
|
export { Options, Statistics, ErrorsList };
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import * as _ from "../helpers";
|
|
4
4
|
import { Options, Statistics, ErrorsList, FunctionToExecute } from "./interfaces";
|
|
5
5
|
|
|
6
|
-
type Status = "unknown" | "initialiazing" | "running" | "
|
|
6
|
+
type Status = "unknown" | "initialiazing" | "queued" | "running" | "runned" | "exception" | "destroying";
|
|
7
7
|
|
|
8
8
|
const defaultOptions: Options = {
|
|
9
9
|
logFunction: undefined,
|
|
@@ -11,10 +11,14 @@ const defaultOptions: Options = {
|
|
|
11
11
|
|
|
12
12
|
class Task {
|
|
13
13
|
status: Status = "unknown";
|
|
14
|
-
readonly
|
|
14
|
+
readonly options: Options;
|
|
15
|
+
tags: { [key: string]: string | number | boolean } = {};
|
|
16
|
+
queueId: string | undefined;
|
|
17
|
+
runnerId: string | undefined;
|
|
18
|
+
|
|
15
19
|
#functionToExecute: FunctionToExecute;
|
|
16
20
|
result: unknown | undefined = undefined;
|
|
17
|
-
readonly
|
|
21
|
+
readonly run: () => Promise<unknown>;
|
|
18
22
|
|
|
19
23
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
24
|
resolver: (value: any | PromiseLike<any>) => void;
|
|
@@ -30,24 +34,21 @@ class Task {
|
|
|
30
34
|
|
|
31
35
|
constructor(function_: FunctionToExecute, opt: Options) {
|
|
32
36
|
this.status = "initialiazing";
|
|
33
|
-
this
|
|
34
|
-
|
|
37
|
+
this.options = this.#checkOptionsConsistancy({ ...defaultOptions, ...opt });
|
|
38
|
+
if (!this.options.id) this.options.id = _.Id.generate();
|
|
35
39
|
if (typeof function_ !== "function") throw new _.Errors.CQError(ErrorsList.FunctionIsNotAFunction);
|
|
36
40
|
|
|
37
41
|
this.resolver = this.#defaultResolver;
|
|
38
42
|
this.rejecter = this.#defaultRejecter;
|
|
39
43
|
this.#functionToExecute = function_;
|
|
40
44
|
|
|
41
|
-
this.
|
|
45
|
+
this.run = async (): Promise<void> => {
|
|
42
46
|
this.status = "running";
|
|
43
|
-
// console.log("running Task");
|
|
44
47
|
try {
|
|
45
48
|
this.result = await this.#functionToExecute();
|
|
46
|
-
|
|
47
|
-
this.status = "stopping";
|
|
49
|
+
this.status = "runned";
|
|
48
50
|
this.resolver(this.result);
|
|
49
51
|
} catch (error) {
|
|
50
|
-
// console.log("task error", this.result);
|
|
51
52
|
this.status = "exception";
|
|
52
53
|
this.rejecter(new _.Errors.CQError(ErrorsList.FunctionRaisedAnHundledException));
|
|
53
54
|
}
|
package/test/issues/00001.mjs
CHANGED
|
@@ -20,7 +20,7 @@ describe("Issue #1", () => {
|
|
|
20
20
|
const engine = cleverQueue.createEngine(engineOptions);
|
|
21
21
|
const queue1 = engine.createQueue({
|
|
22
22
|
name: "A",
|
|
23
|
-
priority: cleverQueue.
|
|
23
|
+
priority: cleverQueue.queues.Priorities.Absolute,
|
|
24
24
|
weight: 50,
|
|
25
25
|
});
|
|
26
26
|
assert.rejects(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import { describe, it } from "node:test";
|
|
3
3
|
|
|
4
|
-
import * as
|
|
4
|
+
import * as cleverQueue from "../../dist/index.js";
|
|
5
5
|
|
|
6
6
|
const engineOptions = {
|
|
7
7
|
bestEffortRunners: 3,
|
|
@@ -10,22 +10,22 @@ const engineOptions = {
|
|
|
10
10
|
|
|
11
11
|
describe("Scheduler Unit Tests", () => {
|
|
12
12
|
it("Priority Test", () => {
|
|
13
|
-
const engine =
|
|
13
|
+
const engine = cleverQueue.createEngine(engineOptions);
|
|
14
14
|
const queue1 = engine.createQueue({
|
|
15
15
|
name: "A",
|
|
16
|
-
priority:
|
|
16
|
+
priority: cleverQueue.queues.Priorities.Absolute,
|
|
17
17
|
weight: 50,
|
|
18
18
|
});
|
|
19
19
|
for (let index = 0; index < 100; index++) queue1.enqueue(engine.createTask(() => {}, {}));
|
|
20
20
|
const queue2 = engine.createQueue({
|
|
21
21
|
name: "B",
|
|
22
|
-
priority:
|
|
22
|
+
priority: cleverQueue.queues.Priorities.Standard,
|
|
23
23
|
weight: 50,
|
|
24
24
|
});
|
|
25
25
|
for (let index = 0; index < 100; index++) queue2.enqueue(engine.createTask(() => {}, {}));
|
|
26
26
|
const queue3 = engine.createQueue({
|
|
27
27
|
name: "C",
|
|
28
|
-
priority:
|
|
28
|
+
priority: cleverQueue.queues.Priorities.BestEffort,
|
|
29
29
|
weight: 50,
|
|
30
30
|
});
|
|
31
31
|
for (let index = 0; index < 100; index++) queue3.enqueue(engine.createTask(() => {}, {}));
|
|
@@ -36,22 +36,22 @@ describe("Scheduler Unit Tests", () => {
|
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
it("Weighted Test", () => {
|
|
39
|
-
const engine =
|
|
39
|
+
const engine = cleverQueue.createEngine(engineOptions);
|
|
40
40
|
const queue1 = engine.createQueue({
|
|
41
41
|
name: "A",
|
|
42
|
-
priority:
|
|
42
|
+
priority: cleverQueue.queues.Priorities.Absolute,
|
|
43
43
|
weight: 80,
|
|
44
44
|
});
|
|
45
45
|
for (let index = 0; index < 100; index++) queue1.enqueue(engine.createTask(() => {}, {}));
|
|
46
46
|
const queue2 = engine.createQueue({
|
|
47
47
|
name: "B",
|
|
48
|
-
priority:
|
|
48
|
+
priority: cleverQueue.queues.Priorities.Absolute,
|
|
49
49
|
weight: 50,
|
|
50
50
|
});
|
|
51
51
|
for (let index = 0; index < 100; index++) queue2.enqueue(engine.createTask(() => {}, {}));
|
|
52
52
|
const queue3 = engine.createQueue({
|
|
53
53
|
name: "C",
|
|
54
|
-
priority:
|
|
54
|
+
priority: cleverQueue.queues.Priorities.Absolute,
|
|
55
55
|
weight: 20,
|
|
56
56
|
});
|
|
57
57
|
for (let index = 0; index < 100; index++) queue3.enqueue(engine.createTask(() => {}, {}));
|
|
@@ -62,25 +62,25 @@ describe("Scheduler Unit Tests", () => {
|
|
|
62
62
|
});
|
|
63
63
|
|
|
64
64
|
it("Combine Test", () => {
|
|
65
|
-
const engine =
|
|
65
|
+
const engine = cleverQueue.createEngine(engineOptions);
|
|
66
66
|
|
|
67
67
|
const queue1 = engine.createQueue({
|
|
68
68
|
name: "A - Absolute - 80",
|
|
69
|
-
priority:
|
|
69
|
+
priority: cleverQueue.queues.Priorities.Absolute,
|
|
70
70
|
weight: 80,
|
|
71
71
|
});
|
|
72
72
|
for (let index = 0; index < 100; index++) queue1.enqueue(engine.createTask(() => {}, {}));
|
|
73
73
|
|
|
74
74
|
const queue2 = engine.createQueue({
|
|
75
75
|
name: "B - Standard - 50",
|
|
76
|
-
priority:
|
|
76
|
+
priority: cleverQueue.queues.Priorities.Standard,
|
|
77
77
|
weight: 50,
|
|
78
78
|
});
|
|
79
79
|
for (let index = 0; index < 100; index++) queue2.enqueue(engine.createTask(() => {}, {}));
|
|
80
80
|
|
|
81
81
|
const queue3 = engine.createQueue({
|
|
82
82
|
name: "C- Standard - 20",
|
|
83
|
-
priority:
|
|
83
|
+
priority: cleverQueue.queues.Priorities.Standard,
|
|
84
84
|
weight: 20,
|
|
85
85
|
});
|
|
86
86
|
for (let index = 0; index < 100; index++) queue3.enqueue(engine.createTask(() => {}, {}));
|
package/test/units/engine.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import { describe, it } from "node:test";
|
|
3
3
|
|
|
4
|
-
import * as
|
|
4
|
+
import * as cleverQueue from "../../dist/index.js";
|
|
5
5
|
|
|
6
6
|
describe("Engine Class Unit Tests", () => {
|
|
7
7
|
it("Successfull Initialisation without any option (use hardcoded default options)", () => {
|
|
8
|
-
const engine =
|
|
8
|
+
const engine = cleverQueue.createEngine();
|
|
9
9
|
const statistics = engine.statistics();
|
|
10
10
|
assert.equal(statistics.engine.runners, 1);
|
|
11
11
|
assert.equal(statistics.engine.queues, 0);
|
|
@@ -15,10 +15,10 @@ describe("Engine Class Unit Tests", () => {
|
|
|
15
15
|
it("Exception with stupid bestEffortRunners Options", () => {
|
|
16
16
|
assert.throws(
|
|
17
17
|
() =>
|
|
18
|
-
|
|
18
|
+
cleverQueue.createEngine({
|
|
19
19
|
bestEffortRunners: -1,
|
|
20
20
|
}),
|
|
21
|
-
{ name:
|
|
21
|
+
{ name: cleverQueue.engine.ErrorsList.bestEffortRunnersOptionMustBeGreaterThanZero.name },
|
|
22
22
|
);
|
|
23
23
|
});
|
|
24
24
|
|
|
@@ -26,7 +26,7 @@ describe("Engine Class Unit Tests", () => {
|
|
|
26
26
|
const engineOptions = {
|
|
27
27
|
bestEffortRunners: 3,
|
|
28
28
|
};
|
|
29
|
-
const engine =
|
|
29
|
+
const engine = cleverQueue.createEngine(engineOptions);
|
|
30
30
|
const statistics = engine.statistics();
|
|
31
31
|
assert.equal(statistics.engine.runners, engineOptions.bestEffortRunners);
|
|
32
32
|
assert.equal(statistics.engine.queues, 0);
|
package/test/units/queue.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import { describe, it } from "node:test";
|
|
3
3
|
|
|
4
|
-
import * as
|
|
4
|
+
import * as cleverQueue from "../../dist/index.js";
|
|
5
5
|
|
|
6
6
|
const engineOptions = {
|
|
7
7
|
bestEffortRunners: 3,
|
|
@@ -10,7 +10,7 @@ const engineOptions = {
|
|
|
10
10
|
|
|
11
11
|
describe("Queue Class Unit Tests", () => {
|
|
12
12
|
it("Successfull Initialisation without any option (use hardcoded default options)", () => {
|
|
13
|
-
const engine =
|
|
13
|
+
const engine = cleverQueue.createEngine();
|
|
14
14
|
const statistics = engine.statistics();
|
|
15
15
|
assert.equal(statistics.engine.runners, 1);
|
|
16
16
|
assert.equal(statistics.engine.queues, 0);
|
|
@@ -18,9 +18,9 @@ describe("Queue Class Unit Tests", () => {
|
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
it("Successfull Initialisation", () => {
|
|
21
|
-
const engine =
|
|
21
|
+
const engine = cleverQueue.createEngine(engineOptions);
|
|
22
22
|
const queueOptions = {
|
|
23
|
-
priority:
|
|
23
|
+
priority: cleverQueue.queues.Priorities.Standard,
|
|
24
24
|
weight: 50,
|
|
25
25
|
};
|
|
26
26
|
const queue = engine.createQueue(queueOptions);
|
package/test/units/task.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import { describe, it } from "node:test";
|
|
3
3
|
|
|
4
|
-
import * as
|
|
4
|
+
import * as cleverQueue from "../../dist/index.js";
|
|
5
5
|
|
|
6
6
|
const engineOptions = {
|
|
7
7
|
bestEffortRunners: 3,
|
|
@@ -17,10 +17,10 @@ const task = async (string_) => {
|
|
|
17
17
|
|
|
18
18
|
describe("Scheduler Unit Tests", () => {
|
|
19
19
|
it("Exception if function passed is not a function (but a result of an executed function)", () => {
|
|
20
|
-
const engine =
|
|
20
|
+
const engine = cleverQueue.createEngine(engineOptions);
|
|
21
21
|
const queue1 = engine.createQueue({
|
|
22
22
|
name: "A",
|
|
23
|
-
priority:
|
|
23
|
+
priority: cleverQueue.queues.Priorities.Absolute,
|
|
24
24
|
weight: 50,
|
|
25
25
|
});
|
|
26
26
|
assert.rejects(
|
|
@@ -28,16 +28,16 @@ describe("Scheduler Unit Tests", () => {
|
|
|
28
28
|
const myTask = engine.createTask(task("myTask"), {});
|
|
29
29
|
await queue1.enqueue(myTask);
|
|
30
30
|
},
|
|
31
|
-
{ name:
|
|
31
|
+
{ name: cleverQueue.tasks.ErrorsList.FunctionIsNotAFunction.name },
|
|
32
32
|
);
|
|
33
33
|
engine.stop();
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
it("Priority Test", () => {
|
|
37
|
-
const engine =
|
|
37
|
+
const engine = cleverQueue.createEngine(engineOptions);
|
|
38
38
|
const queue1 = engine.createQueue({
|
|
39
39
|
name: "A",
|
|
40
|
-
priority:
|
|
40
|
+
priority: cleverQueue.queues.Priorities.Absolute,
|
|
41
41
|
weight: 50,
|
|
42
42
|
});
|
|
43
43
|
|