@push.rocks/taskbuffer 3.5.0 → 4.1.0
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/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/index.d.ts +1 -1
- package/dist_ts/taskbuffer.classes.bufferrunner.js +17 -4
- package/dist_ts/taskbuffer.classes.cyclecounter.d.ts +1 -0
- package/dist_ts/taskbuffer.classes.cyclecounter.js +14 -1
- package/dist_ts/taskbuffer.classes.task.d.ts +14 -1
- package/dist_ts/taskbuffer.classes.task.js +89 -8
- package/dist_ts/taskbuffer.classes.taskchain.d.ts +2 -2
- package/dist_ts/taskbuffer.classes.taskchain.js +14 -5
- package/dist_ts/taskbuffer.classes.taskdebounced.js +14 -3
- package/dist_ts/taskbuffer.classes.taskmanager.d.ts +6 -1
- package/dist_ts/taskbuffer.classes.taskmanager.js +39 -9
- package/dist_ts/taskbuffer.classes.taskparallel.js +4 -2
- package/dist_ts/taskbuffer.classes.taskrunner.d.ts +6 -6
- package/dist_ts/taskbuffer.classes.taskrunner.js +19 -13
- package/dist_ts/taskbuffer.interfaces.d.ts +11 -0
- package/dist_ts_web/ts/index.d.ts +1 -1
- package/dist_ts_web/ts/taskbuffer.classes.bufferrunner.js +17 -4
- package/dist_ts_web/ts/taskbuffer.classes.cyclecounter.d.ts +1 -0
- package/dist_ts_web/ts/taskbuffer.classes.cyclecounter.js +14 -1
- package/dist_ts_web/ts/taskbuffer.classes.task.d.ts +14 -1
- package/dist_ts_web/ts/taskbuffer.classes.task.js +89 -8
- package/dist_ts_web/ts/taskbuffer.classes.taskchain.d.ts +2 -2
- package/dist_ts_web/ts/taskbuffer.classes.taskchain.js +14 -5
- package/dist_ts_web/ts/taskbuffer.classes.taskdebounced.js +14 -3
- package/dist_ts_web/ts/taskbuffer.classes.taskmanager.d.ts +6 -1
- package/dist_ts_web/ts/taskbuffer.classes.taskmanager.js +39 -9
- package/dist_ts_web/ts/taskbuffer.classes.taskparallel.js +4 -2
- package/dist_ts_web/ts/taskbuffer.classes.taskrunner.d.ts +6 -6
- package/dist_ts_web/ts/taskbuffer.classes.taskrunner.js +19 -13
- package/dist_ts_web/ts/taskbuffer.interfaces.d.ts +11 -0
- package/dist_ts_web/ts_web/00_commitinfo_data.js +1 -1
- package/npmextra.json +14 -8
- package/package.json +10 -6
- package/readme.hints.md +42 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/index.ts +1 -1
- package/ts/taskbuffer.classes.bufferrunner.ts +14 -3
- package/ts/taskbuffer.classes.cyclecounter.ts +12 -0
- package/ts/taskbuffer.classes.task.ts +111 -20
- package/ts/taskbuffer.classes.taskchain.ts +17 -10
- package/ts/taskbuffer.classes.taskdebounced.ts +12 -2
- package/ts/taskbuffer.classes.taskmanager.ts +41 -9
- package/ts/taskbuffer.classes.taskparallel.ts +3 -1
- package/ts/taskbuffer.classes.taskrunner.ts +17 -12
- package/ts/taskbuffer.interfaces.ts +13 -0
- package/ts_web/00_commitinfo_data.ts +1 -1
|
@@ -4,7 +4,8 @@ import {
|
|
|
4
4
|
AbstractDistributedCoordinator,
|
|
5
5
|
type IDistributedTaskRequestResult,
|
|
6
6
|
} from './taskbuffer.classes.distributedcoordinator.js';
|
|
7
|
-
import type { ITaskMetadata, ITaskExecutionReport, IScheduledTaskInfo } from './taskbuffer.interfaces.js';
|
|
7
|
+
import type { ITaskMetadata, ITaskExecutionReport, IScheduledTaskInfo, ITaskEvent } from './taskbuffer.interfaces.js';
|
|
8
|
+
import { logger } from './taskbuffer.logging.js';
|
|
8
9
|
|
|
9
10
|
export interface ICronJob {
|
|
10
11
|
cronString: string;
|
|
@@ -19,6 +20,8 @@ export interface ITaskManagerConstructorOptions {
|
|
|
19
20
|
export class TaskManager {
|
|
20
21
|
public randomId = plugins.smartunique.shortId();
|
|
21
22
|
public taskMap = new plugins.lik.ObjectMap<Task<any, any>>();
|
|
23
|
+
public readonly taskSubject = new plugins.smartrx.rxjs.Subject<ITaskEvent>();
|
|
24
|
+
private taskSubscriptions = new Map<Task<any, any>, plugins.smartrx.rxjs.Subscription>();
|
|
22
25
|
private cronJobManager = new plugins.smarttime.CronManager();
|
|
23
26
|
public options: ITaskManagerConstructorOptions = {
|
|
24
27
|
distributedCoordinator: null,
|
|
@@ -37,6 +40,19 @@ export class TaskManager {
|
|
|
37
40
|
throw new Error('Task must have a name to be added to taskManager');
|
|
38
41
|
}
|
|
39
42
|
this.taskMap.add(task);
|
|
43
|
+
const subscription = task.eventSubject.subscribe((event) => {
|
|
44
|
+
this.taskSubject.next(event);
|
|
45
|
+
});
|
|
46
|
+
this.taskSubscriptions.set(task, subscription);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public removeTask(task: Task<any, any>): void {
|
|
50
|
+
this.taskMap.remove(task);
|
|
51
|
+
const subscription = this.taskSubscriptions.get(task);
|
|
52
|
+
if (subscription) {
|
|
53
|
+
subscription.unsubscribe();
|
|
54
|
+
this.taskSubscriptions.delete(task);
|
|
55
|
+
}
|
|
40
56
|
}
|
|
41
57
|
|
|
42
58
|
public addAndScheduleTask(task: Task<any, any>, cronString: string) {
|
|
@@ -75,31 +91,35 @@ export class TaskManager {
|
|
|
75
91
|
triggerTime,
|
|
76
92
|
);
|
|
77
93
|
if (!announcementResult.shouldTrigger) {
|
|
78
|
-
|
|
94
|
+
logger.log('info', 'Distributed coordinator result: NOT EXECUTING');
|
|
79
95
|
return;
|
|
80
96
|
} else {
|
|
81
|
-
|
|
97
|
+
logger.log('info', 'Distributed coordinator result: CHOSEN AND EXECUTING');
|
|
82
98
|
}
|
|
83
99
|
}
|
|
84
|
-
|
|
100
|
+
try {
|
|
101
|
+
await task.trigger();
|
|
102
|
+
} catch (err) {
|
|
103
|
+
logger.log('error', `TaskManager: scheduled task "${task.name || 'unnamed'}" failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
104
|
+
}
|
|
85
105
|
},
|
|
86
106
|
);
|
|
87
107
|
task.cronJob = cronJob;
|
|
88
108
|
}
|
|
89
109
|
|
|
90
110
|
private logTaskState(task: Task<any, any>) {
|
|
91
|
-
|
|
111
|
+
logger.log('info', `Taskbuffer schedule triggered task >>${task.name}<<`);
|
|
92
112
|
const bufferState = task.buffered
|
|
93
113
|
? `buffered with max ${task.bufferMax} buffered calls`
|
|
94
114
|
: `unbuffered`;
|
|
95
|
-
|
|
115
|
+
logger.log('info', `Task >>${task.name}<< is ${bufferState}`);
|
|
96
116
|
}
|
|
97
117
|
|
|
98
118
|
private async performDistributedConsultation(
|
|
99
119
|
task: Task<any, any>,
|
|
100
120
|
triggerTime: number,
|
|
101
121
|
): Promise<IDistributedTaskRequestResult> {
|
|
102
|
-
|
|
122
|
+
logger.log('info', 'Found a distributed coordinator, performing consultation.');
|
|
103
123
|
|
|
104
124
|
return this.options.distributedCoordinator.fireDistributedTaskRequest({
|
|
105
125
|
submitterId: this.randomId,
|
|
@@ -145,6 +165,10 @@ export class TaskManager {
|
|
|
145
165
|
if (this.options.distributedCoordinator) {
|
|
146
166
|
await this.options.distributedCoordinator.stop();
|
|
147
167
|
}
|
|
168
|
+
for (const [, subscription] of this.taskSubscriptions) {
|
|
169
|
+
subscription.unsubscribe();
|
|
170
|
+
}
|
|
171
|
+
this.taskSubscriptions.clear();
|
|
148
172
|
}
|
|
149
173
|
|
|
150
174
|
// Get metadata for a specific task
|
|
@@ -193,6 +217,14 @@ export class TaskManager {
|
|
|
193
217
|
return scheduledRuns;
|
|
194
218
|
}
|
|
195
219
|
|
|
220
|
+
public getTasksByLabel(key: string, value: string): Task<any, any>[] {
|
|
221
|
+
return this.taskMap.getArray().filter(task => task.labels[key] === value);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
public getTasksMetadataByLabel(key: string, value: string): ITaskMetadata[] {
|
|
225
|
+
return this.getTasksByLabel(key, value).map(task => task.getMetadata());
|
|
226
|
+
}
|
|
227
|
+
|
|
196
228
|
// Add, execute, and remove a task while collecting metadata
|
|
197
229
|
public async addExecuteRemoveTask<T, TSteps extends ReadonlyArray<{ name: string; description: string; percentage: number }>>(
|
|
198
230
|
task: Task<T, TSteps>,
|
|
@@ -231,7 +263,7 @@ export class TaskManager {
|
|
|
231
263
|
};
|
|
232
264
|
|
|
233
265
|
// Remove task from manager
|
|
234
|
-
this.
|
|
266
|
+
this.removeTask(task);
|
|
235
267
|
|
|
236
268
|
// Deschedule if it was scheduled
|
|
237
269
|
if (options?.schedule && task.name) {
|
|
@@ -255,7 +287,7 @@ export class TaskManager {
|
|
|
255
287
|
};
|
|
256
288
|
|
|
257
289
|
// Remove task from manager even on error
|
|
258
|
-
this.
|
|
290
|
+
this.removeTask(task);
|
|
259
291
|
|
|
260
292
|
// Deschedule if it was scheduled
|
|
261
293
|
if (options?.schedule && task.name) {
|
|
@@ -13,7 +13,9 @@ export class Taskparallel extends Task {
|
|
|
13
13
|
this.taskArray.forEach(function (taskArg) {
|
|
14
14
|
promiseArray.push(taskArg.trigger());
|
|
15
15
|
});
|
|
16
|
-
Promise.all(promiseArray)
|
|
16
|
+
Promise.all(promiseArray)
|
|
17
|
+
.then((results) => done.resolve(results))
|
|
18
|
+
.catch((err) => done.reject(err));
|
|
17
19
|
return done.promise;
|
|
18
20
|
},
|
|
19
21
|
},
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import * as plugins from './taskbuffer.plugins.js';
|
|
2
2
|
|
|
3
3
|
import { Task } from './taskbuffer.classes.task.js';
|
|
4
|
+
import { logger } from './taskbuffer.logging.js';
|
|
4
5
|
|
|
5
6
|
export class TaskRunner {
|
|
6
|
-
public
|
|
7
|
+
public maxParallelJobs: number = 1;
|
|
7
8
|
public status: 'stopped' | 'running' = 'stopped';
|
|
8
9
|
public runningTasks: plugins.lik.ObjectMap<Task> =
|
|
9
10
|
new plugins.lik.ObjectMap<Task>();
|
|
10
|
-
public
|
|
11
|
+
public queuedTasks: Task[] = [];
|
|
11
12
|
|
|
12
13
|
constructor() {
|
|
13
14
|
this.runningTasks.eventSubject.subscribe(async (eventArg) => {
|
|
@@ -16,19 +17,19 @@ export class TaskRunner {
|
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
|
-
* adds a task to the
|
|
20
|
+
* adds a task to the queue
|
|
20
21
|
*/
|
|
21
22
|
public addTask(taskArg: Task) {
|
|
22
|
-
this.
|
|
23
|
+
this.queuedTasks.push(taskArg);
|
|
23
24
|
this.checkExecution();
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
28
|
* set amount of parallel tasks
|
|
28
|
-
* be careful, you might
|
|
29
|
+
* be careful, you might lose dependability of tasks
|
|
29
30
|
*/
|
|
30
|
-
public setMaxParallelJobs(
|
|
31
|
-
this.
|
|
31
|
+
public setMaxParallelJobs(maxParallelJobsArg: number) {
|
|
32
|
+
this.maxParallelJobs = maxParallelJobsArg;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
/**
|
|
@@ -39,17 +40,21 @@ export class TaskRunner {
|
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
/**
|
|
42
|
-
* checks
|
|
43
|
+
* checks whether execution is on point
|
|
43
44
|
*/
|
|
44
45
|
public async checkExecution() {
|
|
45
46
|
if (
|
|
46
|
-
this.runningTasks.getArray().length < this.
|
|
47
|
+
this.runningTasks.getArray().length < this.maxParallelJobs &&
|
|
47
48
|
this.status === 'running' &&
|
|
48
|
-
this.
|
|
49
|
+
this.queuedTasks.length > 0
|
|
49
50
|
) {
|
|
50
|
-
const nextJob = this.
|
|
51
|
+
const nextJob = this.queuedTasks.shift();
|
|
51
52
|
this.runningTasks.add(nextJob);
|
|
52
|
-
|
|
53
|
+
try {
|
|
54
|
+
await nextJob.trigger();
|
|
55
|
+
} catch (err) {
|
|
56
|
+
logger.log('error', `TaskRunner: task "${nextJob.name || 'unnamed'}" failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
57
|
+
}
|
|
53
58
|
this.runningTasks.remove(nextJob);
|
|
54
59
|
this.checkExecution();
|
|
55
60
|
}
|
|
@@ -15,6 +15,9 @@ export interface ITaskMetadata {
|
|
|
15
15
|
buffered?: boolean;
|
|
16
16
|
bufferMax?: number;
|
|
17
17
|
timeout?: number;
|
|
18
|
+
lastError?: string;
|
|
19
|
+
errorCount?: number;
|
|
20
|
+
labels?: Record<string, string>;
|
|
18
21
|
}
|
|
19
22
|
|
|
20
23
|
export interface ITaskExecutionReport {
|
|
@@ -36,4 +39,14 @@ export interface IScheduledTaskInfo {
|
|
|
36
39
|
lastRun?: Date;
|
|
37
40
|
steps?: ITaskStep[];
|
|
38
41
|
metadata?: ITaskMetadata;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type TTaskEventType = 'started' | 'step' | 'completed' | 'failed';
|
|
45
|
+
|
|
46
|
+
export interface ITaskEvent {
|
|
47
|
+
type: TTaskEventType;
|
|
48
|
+
task: ITaskMetadata;
|
|
49
|
+
timestamp: number;
|
|
50
|
+
stepName?: string; // present when type === 'step'
|
|
51
|
+
error?: string; // present when type === 'failed'
|
|
39
52
|
}
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/taskbuffer',
|
|
6
|
-
version: '
|
|
6
|
+
version: '4.1.0',
|
|
7
7
|
description: 'A flexible task management library supporting TypeScript, allowing for task buffering, scheduling, and execution with dependency management.'
|
|
8
8
|
}
|