@push.rocks/taskbuffer 3.1.1 → 3.1.3
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_bundle/bundle.js +63 -90
- package/dist_bundle/bundle.js.map +2 -2
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/taskbuffer.classes.distributedcoordinator.d.ts +8 -15
- package/dist_ts/taskbuffer.classes.distributedcoordinator.js +1 -1
- package/dist_ts/taskbuffer.classes.taskmanager.d.ts +14 -50
- package/dist_ts/taskbuffer.classes.taskmanager.js +65 -90
- package/package.json +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/taskbuffer.classes.distributedcoordinator.ts +10 -15
- package/ts/taskbuffer.classes.taskmanager.ts +70 -100
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/taskbuffer',
|
|
6
|
-
version: '3.1.
|
|
6
|
+
version: '3.1.3',
|
|
7
7
|
description: 'flexible task management. TypeScript ready!'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx3QkFBd0I7SUFDOUIsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLDZDQUE2QztDQUMzRCxDQUFBIn0=
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Contains all data for the final coordinator to make an informed decision.
|
|
3
3
|
*/
|
|
4
4
|
export interface IDistributedTaskRequest {
|
|
5
|
-
|
|
6
|
-
* this needs to correlate to the consultationResult
|
|
7
|
-
*/
|
|
8
|
-
submitterRandomId: string;
|
|
5
|
+
submitterId: string;
|
|
9
6
|
taskName: string;
|
|
10
7
|
taskVersion: string;
|
|
11
8
|
taskExecutionTime: number;
|
|
@@ -14,19 +11,15 @@ export interface IDistributedTaskRequest {
|
|
|
14
11
|
status: 'requesting' | 'gotRejected' | 'failed' | 'succeeded';
|
|
15
12
|
}
|
|
16
13
|
export interface IDistributedTaskRequestResult {
|
|
17
|
-
|
|
18
|
-
* this needs to correlate to the decisionInfoBasis
|
|
19
|
-
*/
|
|
20
|
-
submitterRandomId: string;
|
|
21
|
-
/**
|
|
22
|
-
* can be used while debugging
|
|
23
|
-
*/
|
|
14
|
+
submitterId: string;
|
|
24
15
|
considered: boolean;
|
|
25
|
-
rank:
|
|
16
|
+
rank: number;
|
|
26
17
|
reason: string;
|
|
27
18
|
shouldTrigger: boolean;
|
|
28
19
|
}
|
|
29
20
|
export declare abstract class AbstractDistributedCoordinator {
|
|
30
|
-
abstract fireDistributedTaskRequest(
|
|
31
|
-
abstract updateDistributedTaskRequest(
|
|
21
|
+
abstract fireDistributedTaskRequest(infoBasis: IDistributedTaskRequest): Promise<IDistributedTaskRequestResult>;
|
|
22
|
+
abstract updateDistributedTaskRequest(infoBasis: IDistributedTaskRequest): Promise<void>;
|
|
23
|
+
abstract start(): Promise<void>;
|
|
24
|
+
abstract stop(): Promise<void>;
|
|
32
25
|
}
|
|
@@ -2,4 +2,4 @@ import { Task } from './taskbuffer.classes.task.js';
|
|
|
2
2
|
import * as plugins from './taskbuffer.plugins.js';
|
|
3
3
|
export class AbstractDistributedCoordinator {
|
|
4
4
|
}
|
|
5
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFza2J1ZmZlci5jbGFzc2VzLmRpc3RyaWJ1dGVkY29vcmRpbmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy90YXNrYnVmZmVyLmNsYXNzZXMuZGlzdHJpYnV0ZWRjb29yZGluYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDcEQsT0FBTyxLQUFLLE9BQU8sTUFBTSx5QkFBeUIsQ0FBQztBQXVCbkQsTUFBTSxPQUFnQiw4QkFBOEI7Q0FXbkQifQ==
|
|
@@ -3,7 +3,7 @@ import { Task } from './taskbuffer.classes.task.js';
|
|
|
3
3
|
import { AbstractDistributedCoordinator } from './taskbuffer.classes.distributedcoordinator.js';
|
|
4
4
|
export interface ICronJob {
|
|
5
5
|
cronString: string;
|
|
6
|
-
|
|
6
|
+
taskName: string;
|
|
7
7
|
job: any;
|
|
8
8
|
}
|
|
9
9
|
export interface ITaskManagerConstructorOptions {
|
|
@@ -14,55 +14,19 @@ export declare class TaskManager {
|
|
|
14
14
|
taskMap: plugins.lik.ObjectMap<Task<undefined>>;
|
|
15
15
|
private cronJobManager;
|
|
16
16
|
options: ITaskManagerConstructorOptions;
|
|
17
|
-
constructor(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
getTaskByName(taskNameArg: string): Task;
|
|
23
|
-
/**
|
|
24
|
-
* adds a Task to the TaskManager
|
|
25
|
-
* @param taskArg
|
|
26
|
-
*/
|
|
27
|
-
addTask(taskArg: Task): void;
|
|
28
|
-
/**
|
|
29
|
-
* adds and schedules a task at once
|
|
30
|
-
* @param taskArg
|
|
31
|
-
* @param cronStringArg
|
|
32
|
-
*/
|
|
33
|
-
addAndScheduleTask(taskArg: Task, cronStringArg: string): void;
|
|
34
|
-
/**
|
|
35
|
-
* triggers a task in the TaskManagerByName
|
|
36
|
-
* @param taskNameArg
|
|
37
|
-
*/
|
|
38
|
-
triggerTaskByName(taskNameArg: string): Promise<any>;
|
|
17
|
+
constructor(options?: ITaskManagerConstructorOptions);
|
|
18
|
+
getTaskByName(taskName: string): Task;
|
|
19
|
+
addTask(task: Task): void;
|
|
20
|
+
addAndScheduleTask(task: Task, cronString: string): void;
|
|
21
|
+
triggerTaskByName(taskName: string): Promise<any>;
|
|
39
22
|
triggerTask(task: Task): Promise<any>;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* deschedules a task by name
|
|
47
|
-
* @param taskNameArg
|
|
48
|
-
*/
|
|
49
|
-
descheduleTaskByName(taskNameArg: string): void;
|
|
50
|
-
/**
|
|
51
|
-
* deschedules a task
|
|
52
|
-
* @param task
|
|
53
|
-
*/
|
|
23
|
+
scheduleTaskByName(taskName: string, cronString: string): void;
|
|
24
|
+
private handleTaskScheduling;
|
|
25
|
+
private logTaskState;
|
|
26
|
+
private performDistributedConsultation;
|
|
27
|
+
descheduleTaskByName(taskName: string): void;
|
|
54
28
|
descheduleTask(task: Task): Promise<void>;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
*/
|
|
59
|
-
getScheduleForTaskName(taskNameArg: string): string | null;
|
|
60
|
-
/**
|
|
61
|
-
* starts the taskmanager
|
|
62
|
-
*/
|
|
63
|
-
start(): void;
|
|
64
|
-
/**
|
|
65
|
-
* stops the taskmanager
|
|
66
|
-
*/
|
|
67
|
-
stop(): void;
|
|
29
|
+
getScheduleForTaskName(taskName: string): string | null;
|
|
30
|
+
start(): Promise<void>;
|
|
31
|
+
stop(): Promise<void>;
|
|
68
32
|
}
|
|
@@ -2,134 +2,109 @@ import * as plugins from './taskbuffer.plugins.js';
|
|
|
2
2
|
import { Task } from './taskbuffer.classes.task.js';
|
|
3
3
|
import { AbstractDistributedCoordinator } from './taskbuffer.classes.distributedcoordinator.js';
|
|
4
4
|
export class TaskManager {
|
|
5
|
-
constructor(
|
|
5
|
+
constructor(options = {}) {
|
|
6
6
|
this.randomId = plugins.isounique.uni();
|
|
7
7
|
this.taskMap = new plugins.lik.ObjectMap();
|
|
8
8
|
this.cronJobManager = new plugins.smarttime.CronManager();
|
|
9
9
|
this.options = {
|
|
10
10
|
distributedCoordinator: null,
|
|
11
11
|
};
|
|
12
|
-
this.options = Object.assign(this.options,
|
|
12
|
+
this.options = Object.assign(this.options, options);
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
* @param taskNameArg
|
|
17
|
-
*/
|
|
18
|
-
getTaskByName(taskNameArg) {
|
|
19
|
-
return this.taskMap.findSync((itemArg) => {
|
|
20
|
-
return itemArg.name === taskNameArg;
|
|
21
|
-
});
|
|
14
|
+
getTaskByName(taskName) {
|
|
15
|
+
return this.taskMap.findSync((task) => task.name === taskName);
|
|
22
16
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
*/
|
|
27
|
-
addTask(taskArg) {
|
|
28
|
-
if (!taskArg.name) {
|
|
29
|
-
throw new Error('taskArg needs a name to be added to taskManager');
|
|
17
|
+
addTask(task) {
|
|
18
|
+
if (!task.name) {
|
|
19
|
+
throw new Error('Task must have a name to be added to taskManager');
|
|
30
20
|
}
|
|
31
|
-
this.taskMap.add(
|
|
21
|
+
this.taskMap.add(task);
|
|
32
22
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
* @param cronStringArg
|
|
37
|
-
*/
|
|
38
|
-
addAndScheduleTask(taskArg, cronStringArg) {
|
|
39
|
-
this.addTask(taskArg);
|
|
40
|
-
this.scheduleTaskByName(taskArg.name, cronStringArg);
|
|
23
|
+
addAndScheduleTask(task, cronString) {
|
|
24
|
+
this.addTask(task);
|
|
25
|
+
this.scheduleTaskByName(task.name, cronString);
|
|
41
26
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
* @param taskNameArg
|
|
45
|
-
*/
|
|
46
|
-
triggerTaskByName(taskNameArg) {
|
|
47
|
-
const taskToTrigger = this.getTaskByName(taskNameArg);
|
|
27
|
+
async triggerTaskByName(taskName) {
|
|
28
|
+
const taskToTrigger = this.getTaskByName(taskName);
|
|
48
29
|
if (!taskToTrigger) {
|
|
49
|
-
throw new Error(`
|
|
30
|
+
throw new Error(`No task with the name ${taskName} found.`);
|
|
50
31
|
}
|
|
51
32
|
return taskToTrigger.trigger();
|
|
52
33
|
}
|
|
53
34
|
async triggerTask(task) {
|
|
54
35
|
return task.trigger();
|
|
55
36
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
: `unbuffered`}`);
|
|
37
|
+
scheduleTaskByName(taskName, cronString) {
|
|
38
|
+
const taskToSchedule = this.getTaskByName(taskName);
|
|
39
|
+
if (!taskToSchedule) {
|
|
40
|
+
throw new Error(`No task with the name ${taskName} found.`);
|
|
41
|
+
}
|
|
42
|
+
this.handleTaskScheduling(taskToSchedule, cronString);
|
|
43
|
+
}
|
|
44
|
+
handleTaskScheduling(task, cronString) {
|
|
45
|
+
const cronJob = this.cronJobManager.addCronjob(cronString, async (triggerTime) => {
|
|
46
|
+
this.logTaskState(task);
|
|
67
47
|
if (this.options.distributedCoordinator) {
|
|
68
|
-
|
|
69
|
-
const announcementResult = await this.options.distributedCoordinator.fireDistributedTaskRequest({
|
|
70
|
-
submitterRandomId: this.randomId,
|
|
71
|
-
status: 'requesting',
|
|
72
|
-
taskExecutionParallel: 1,
|
|
73
|
-
taskExecutionTime: triggerTimeArg,
|
|
74
|
-
taskExecutionTimeout: taskToSchedule.timeout,
|
|
75
|
-
taskName: taskToSchedule.name,
|
|
76
|
-
taskVersion: taskToSchedule.version,
|
|
77
|
-
});
|
|
48
|
+
const announcementResult = await this.performDistributedConsultation(task, triggerTime);
|
|
78
49
|
if (!announcementResult.shouldTrigger) {
|
|
79
|
-
console.log('
|
|
50
|
+
console.log('Distributed coordinator result: NOT EXECUTING');
|
|
80
51
|
return;
|
|
81
52
|
}
|
|
82
53
|
else {
|
|
83
|
-
console.log('
|
|
54
|
+
console.log('Distributed coordinator result: CHOSEN AND EXECUTING');
|
|
84
55
|
}
|
|
85
56
|
}
|
|
86
|
-
await
|
|
57
|
+
await task.trigger();
|
|
87
58
|
});
|
|
88
|
-
|
|
59
|
+
task.cronJob = cronJob;
|
|
89
60
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
61
|
+
logTaskState(task) {
|
|
62
|
+
console.log(`Taskbuffer schedule triggered task >>${task.name}<<`);
|
|
63
|
+
const bufferState = task.buffered
|
|
64
|
+
? `buffered with max ${task.bufferMax} buffered calls`
|
|
65
|
+
: `unbuffered`;
|
|
66
|
+
console.log(`Task >>${task.name}<< is ${bufferState}`);
|
|
67
|
+
}
|
|
68
|
+
async performDistributedConsultation(task, triggerTime) {
|
|
69
|
+
console.log('Found a distributed coordinator, performing consultation.');
|
|
70
|
+
return this.options.distributedCoordinator.fireDistributedTaskRequest({
|
|
71
|
+
submitterId: this.randomId,
|
|
72
|
+
status: 'requesting',
|
|
73
|
+
taskExecutionParallel: 1,
|
|
74
|
+
taskExecutionTime: triggerTime,
|
|
75
|
+
taskExecutionTimeout: task.timeout,
|
|
76
|
+
taskName: task.name,
|
|
77
|
+
taskVersion: task.version,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
descheduleTaskByName(taskName) {
|
|
81
|
+
const task = this.getTaskByName(taskName);
|
|
82
|
+
if (task && task.cronJob) {
|
|
83
|
+
this.cronJobManager.removeCronjob(task.cronJob);
|
|
84
|
+
task.cronJob = null;
|
|
99
85
|
}
|
|
100
86
|
if (this.cronJobManager.cronjobs.isEmpty) {
|
|
101
87
|
this.cronJobManager.stop();
|
|
102
88
|
}
|
|
103
89
|
}
|
|
104
|
-
/**
|
|
105
|
-
* deschedules a task
|
|
106
|
-
* @param task
|
|
107
|
-
*/
|
|
108
90
|
async descheduleTask(task) {
|
|
109
91
|
await this.descheduleTaskByName(task.name);
|
|
110
92
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
*/
|
|
115
|
-
getScheduleForTaskName(taskNameArg) {
|
|
116
|
-
const task = this.getTaskByName(taskNameArg);
|
|
117
|
-
if (!task || !task.cronJob) {
|
|
118
|
-
return null;
|
|
119
|
-
}
|
|
120
|
-
return task.cronJob.cronExpression;
|
|
93
|
+
getScheduleForTaskName(taskName) {
|
|
94
|
+
const task = this.getTaskByName(taskName);
|
|
95
|
+
return task && task.cronJob ? task.cronJob.cronExpression : null;
|
|
121
96
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
97
|
+
async start() {
|
|
98
|
+
if (this.options.distributedCoordinator) {
|
|
99
|
+
await this.options.distributedCoordinator.start();
|
|
100
|
+
}
|
|
126
101
|
this.cronJobManager.start();
|
|
127
102
|
}
|
|
128
|
-
|
|
129
|
-
* stops the taskmanager
|
|
130
|
-
*/
|
|
131
|
-
stop() {
|
|
103
|
+
async stop() {
|
|
132
104
|
this.cronJobManager.stop();
|
|
105
|
+
if (this.options.distributedCoordinator) {
|
|
106
|
+
await this.options.distributedCoordinator.stop();
|
|
107
|
+
}
|
|
133
108
|
}
|
|
134
109
|
}
|
|
135
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
110
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFza2J1ZmZlci5jbGFzc2VzLnRhc2ttYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvdGFza2J1ZmZlci5jbGFzc2VzLnRhc2ttYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0seUJBQXlCLENBQUM7QUFDbkQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ3BELE9BQU8sRUFBRSw4QkFBOEIsRUFBc0MsTUFBTSxnREFBZ0QsQ0FBQztBQVlwSSxNQUFNLE9BQU8sV0FBVztJQVF0QixZQUFZLFVBQTBDLEVBQUU7UUFQakQsYUFBUSxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDbkMsWUFBTyxHQUFHLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQVEsQ0FBQztRQUMzQyxtQkFBYyxHQUFHLElBQUksT0FBTyxDQUFDLFNBQVMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN0RCxZQUFPLEdBQW1DO1lBQy9DLHNCQUFzQixFQUFFLElBQUk7U0FDN0IsQ0FBQztRQUdBLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3RELENBQUM7SUFFTSxhQUFhLENBQUMsUUFBZ0I7UUFDbkMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxRQUFRLENBQUMsQ0FBQztJQUNqRSxDQUFDO0lBRU0sT0FBTyxDQUFDLElBQVU7UUFDdkIsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUU7WUFDZCxNQUFNLElBQUksS0FBSyxDQUFDLGtEQUFrRCxDQUFDLENBQUM7U0FDckU7UUFDRCxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN6QixDQUFDO0lBRU0sa0JBQWtCLENBQUMsSUFBVSxFQUFFLFVBQWtCO1FBQ3RELElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbkIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFDakQsQ0FBQztJQUVNLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxRQUFnQjtRQUM3QyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ25ELElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDbEIsTUFBTSxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsUUFBUSxTQUFTLENBQUMsQ0FBQztTQUM3RDtRQUNELE9BQU8sYUFBYSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2pDLENBQUM7SUFFTSxLQUFLLENBQUMsV0FBVyxDQUFDLElBQVU7UUFDakMsT0FBTyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDeEIsQ0FBQztJQUVNLGtCQUFrQixDQUFDLFFBQWdCLEVBQUUsVUFBa0I7UUFDNUQsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNwRCxJQUFJLENBQUMsY0FBYyxFQUFFO1lBQ25CLE1BQU0sSUFBSSxLQUFLLENBQUMseUJBQXlCLFFBQVEsU0FBUyxDQUFDLENBQUM7U0FDN0Q7UUFDRCxJQUFJLENBQUMsb0JBQW9CLENBQUMsY0FBYyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ3hELENBQUM7SUFFTyxvQkFBb0IsQ0FBQyxJQUFVLEVBQUUsVUFBa0I7UUFDekQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQzVDLFVBQVUsRUFDVixLQUFLLEVBQUUsV0FBbUIsRUFBRSxFQUFFO1lBQzVCLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDeEIsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLHNCQUFzQixFQUFFO2dCQUN2QyxNQUFNLGtCQUFrQixHQUFHLE1BQU0sSUFBSSxDQUFDLDhCQUE4QixDQUFDLElBQUksRUFBRSxXQUFXLENBQUMsQ0FBQztnQkFDeEYsSUFBSSxDQUFDLGtCQUFrQixDQUFDLGFBQWEsRUFBRTtvQkFDckMsT0FBTyxDQUFDLEdBQUcsQ0FBQywrQ0FBK0MsQ0FBQyxDQUFDO29CQUM3RCxPQUFPO2lCQUNSO3FCQUFNO29CQUNMLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0RBQXNELENBQUMsQ0FBQztpQkFDckU7YUFDRjtZQUNELE1BQU0sSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3ZCLENBQUMsQ0FDRixDQUFDO1FBQ0YsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7SUFDekIsQ0FBQztJQUVPLFlBQVksQ0FBQyxJQUFVO1FBQzdCLE9BQU8sQ0FBQyxHQUFHLENBQUMsd0NBQXdDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDO1FBQ25FLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxRQUFRO1lBQy9CLENBQUMsQ0FBQyxxQkFBcUIsSUFBSSxDQUFDLFNBQVMsaUJBQWlCO1lBQ3RELENBQUMsQ0FBQyxZQUFZLENBQUM7UUFDakIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLElBQUksQ0FBQyxJQUFJLFNBQVMsV0FBVyxFQUFFLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBRU8sS0FBSyxDQUFDLDhCQUE4QixDQUFDLElBQVUsRUFBRSxXQUFtQjtRQUMxRSxPQUFPLENBQUMsR0FBRyxDQUFDLDJEQUEyRCxDQUFDLENBQUM7UUFDekUsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLHNCQUFzQixDQUFDLDBCQUEwQixDQUFDO1lBQ3BFLFdBQVcsRUFBRSxJQUFJLENBQUMsUUFBUTtZQUMxQixNQUFNLEVBQUUsWUFBWTtZQUNwQixxQkFBcUIsRUFBRSxDQUFDO1lBQ3hCLGlCQUFpQixFQUFFLFdBQVc7WUFDOUIsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLE9BQU87WUFDbEMsUUFBUSxFQUFFLElBQUksQ0FBQyxJQUFJO1lBQ25CLFdBQVcsRUFBRSxJQUFJLENBQUMsT0FBTztTQUMxQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU0sb0JBQW9CLENBQUMsUUFBZ0I7UUFDMUMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMxQyxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ3hCLElBQUksQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNoRCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztTQUNyQjtRQUNELElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFO1lBQ3hDLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLENBQUM7U0FDNUI7SUFDSCxDQUFDO0lBRU0sS0FBSyxDQUFDLGNBQWMsQ0FBQyxJQUFVO1FBQ3BDLE1BQU0sSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRU0sc0JBQXNCLENBQUMsUUFBZ0I7UUFDNUMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMxQyxPQUFPLElBQUksSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ25FLENBQUM7SUFFTSxLQUFLLENBQUMsS0FBSztRQUNoQixJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsc0JBQXNCLEVBQUU7WUFDdkMsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLHNCQUFzQixDQUFDLEtBQUssRUFBRSxDQUFDO1NBQ25EO1FBQ0QsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUM5QixDQUFDO0lBRU0sS0FBSyxDQUFDLElBQUk7UUFDZixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzNCLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxzQkFBc0IsRUFBRTtZQUN2QyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsc0JBQXNCLENBQUMsSUFBSSxFQUFFLENBQUM7U0FDbEQ7SUFDSCxDQUFDO0NBQ0YifQ==
|
package/package.json
CHANGED
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -2,13 +2,10 @@ import { Task } from './taskbuffer.classes.task.js';
|
|
|
2
2
|
import * as plugins from './taskbuffer.plugins.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Contains all data for the final coordinator to make an informed decision.
|
|
6
6
|
*/
|
|
7
7
|
export interface IDistributedTaskRequest {
|
|
8
|
-
|
|
9
|
-
* this needs to correlate to the consultationResult
|
|
10
|
-
*/
|
|
11
|
-
submitterRandomId: string;
|
|
8
|
+
submitterId: string;
|
|
12
9
|
taskName: string;
|
|
13
10
|
taskVersion: string;
|
|
14
11
|
taskExecutionTime: number;
|
|
@@ -18,24 +15,22 @@ export interface IDistributedTaskRequest {
|
|
|
18
15
|
}
|
|
19
16
|
|
|
20
17
|
export interface IDistributedTaskRequestResult {
|
|
21
|
-
|
|
22
|
-
* this needs to correlate to the decisionInfoBasis
|
|
23
|
-
*/
|
|
24
|
-
submitterRandomId: string;
|
|
25
|
-
/**
|
|
26
|
-
* can be used while debugging
|
|
27
|
-
*/
|
|
18
|
+
submitterId: string;
|
|
28
19
|
considered: boolean;
|
|
29
|
-
rank:
|
|
20
|
+
rank: number;
|
|
30
21
|
reason: string;
|
|
31
22
|
shouldTrigger: boolean;
|
|
32
23
|
}
|
|
33
24
|
|
|
34
25
|
export abstract class AbstractDistributedCoordinator {
|
|
35
26
|
public abstract fireDistributedTaskRequest(
|
|
36
|
-
|
|
27
|
+
infoBasis: IDistributedTaskRequest
|
|
37
28
|
): Promise<IDistributedTaskRequestResult>;
|
|
29
|
+
|
|
38
30
|
public abstract updateDistributedTaskRequest(
|
|
39
|
-
|
|
31
|
+
infoBasis: IDistributedTaskRequest
|
|
40
32
|
): Promise<void>;
|
|
33
|
+
|
|
34
|
+
public abstract start(): Promise<void>;
|
|
35
|
+
public abstract stop(): Promise<void>;
|
|
41
36
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as plugins from './taskbuffer.plugins.js';
|
|
2
2
|
import { Task } from './taskbuffer.classes.task.js';
|
|
3
|
-
import { AbstractDistributedCoordinator } from './taskbuffer.classes.distributedcoordinator.js';
|
|
3
|
+
import { AbstractDistributedCoordinator, type IDistributedTaskRequestResult } from './taskbuffer.classes.distributedcoordinator.js';
|
|
4
4
|
|
|
5
5
|
export interface ICronJob {
|
|
6
6
|
cronString: string;
|
|
7
|
-
|
|
7
|
+
taskName: string;
|
|
8
8
|
job: any;
|
|
9
9
|
}
|
|
10
10
|
|
|
@@ -16,54 +16,34 @@ export class TaskManager {
|
|
|
16
16
|
public randomId = plugins.isounique.uni();
|
|
17
17
|
public taskMap = new plugins.lik.ObjectMap<Task>();
|
|
18
18
|
private cronJobManager = new plugins.smarttime.CronManager();
|
|
19
|
-
|
|
20
19
|
public options: ITaskManagerConstructorOptions = {
|
|
21
20
|
distributedCoordinator: null,
|
|
22
21
|
};
|
|
23
22
|
|
|
24
|
-
constructor(
|
|
25
|
-
this.options = Object.assign(this.options,
|
|
23
|
+
constructor(options: ITaskManagerConstructorOptions = {}) {
|
|
24
|
+
this.options = Object.assign(this.options, options);
|
|
26
25
|
}
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
* @param taskNameArg
|
|
31
|
-
*/
|
|
32
|
-
public getTaskByName(taskNameArg: string): Task {
|
|
33
|
-
return this.taskMap.findSync((itemArg) => {
|
|
34
|
-
return itemArg.name === taskNameArg;
|
|
35
|
-
});
|
|
27
|
+
public getTaskByName(taskName: string): Task {
|
|
28
|
+
return this.taskMap.findSync((task) => task.name === taskName);
|
|
36
29
|
}
|
|
37
30
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
*/
|
|
42
|
-
public addTask(taskArg: Task): void {
|
|
43
|
-
if (!taskArg.name) {
|
|
44
|
-
throw new Error('taskArg needs a name to be added to taskManager');
|
|
31
|
+
public addTask(task: Task): void {
|
|
32
|
+
if (!task.name) {
|
|
33
|
+
throw new Error('Task must have a name to be added to taskManager');
|
|
45
34
|
}
|
|
46
|
-
this.taskMap.add(
|
|
35
|
+
this.taskMap.add(task);
|
|
47
36
|
}
|
|
48
37
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
* @param cronStringArg
|
|
53
|
-
*/
|
|
54
|
-
public addAndScheduleTask(taskArg: Task, cronStringArg: string) {
|
|
55
|
-
this.addTask(taskArg);
|
|
56
|
-
this.scheduleTaskByName(taskArg.name, cronStringArg);
|
|
38
|
+
public addAndScheduleTask(task: Task, cronString: string) {
|
|
39
|
+
this.addTask(task);
|
|
40
|
+
this.scheduleTaskByName(task.name, cronString);
|
|
57
41
|
}
|
|
58
42
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
* @param taskNameArg
|
|
62
|
-
*/
|
|
63
|
-
public triggerTaskByName(taskNameArg: string): Promise<any> {
|
|
64
|
-
const taskToTrigger = this.getTaskByName(taskNameArg);
|
|
43
|
+
public async triggerTaskByName(taskName: string): Promise<any> {
|
|
44
|
+
const taskToTrigger = this.getTaskByName(taskName);
|
|
65
45
|
if (!taskToTrigger) {
|
|
66
|
-
throw new Error(`
|
|
46
|
+
throw new Error(`No task with the name ${taskName} found.`);
|
|
67
47
|
}
|
|
68
48
|
return taskToTrigger.trigger();
|
|
69
49
|
}
|
|
@@ -72,96 +52,86 @@ export class TaskManager {
|
|
|
72
52
|
return task.trigger();
|
|
73
53
|
}
|
|
74
54
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
55
|
+
public scheduleTaskByName(taskName: string, cronString: string) {
|
|
56
|
+
const taskToSchedule = this.getTaskByName(taskName);
|
|
57
|
+
if (!taskToSchedule) {
|
|
58
|
+
throw new Error(`No task with the name ${taskName} found.`);
|
|
59
|
+
}
|
|
60
|
+
this.handleTaskScheduling(taskToSchedule, cronString);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private handleTaskScheduling(task: Task, cronString: string) {
|
|
81
64
|
const cronJob = this.cronJobManager.addCronjob(
|
|
82
|
-
|
|
83
|
-
async (
|
|
84
|
-
|
|
85
|
-
console.log(
|
|
86
|
-
`task >>${taskToSchedule.name}<< is ${
|
|
87
|
-
taskToSchedule.buffered
|
|
88
|
-
? `buffered with max ${taskToSchedule.bufferMax} buffered calls`
|
|
89
|
-
: `unbuffered`
|
|
90
|
-
}`
|
|
91
|
-
);
|
|
65
|
+
cronString,
|
|
66
|
+
async (triggerTime: number) => {
|
|
67
|
+
this.logTaskState(task);
|
|
92
68
|
if (this.options.distributedCoordinator) {
|
|
93
|
-
|
|
94
|
-
const announcementResult =
|
|
95
|
-
await this.options.distributedCoordinator.fireDistributedTaskRequest({
|
|
96
|
-
submitterRandomId: this.randomId,
|
|
97
|
-
status: 'requesting',
|
|
98
|
-
taskExecutionParallel: 1,
|
|
99
|
-
taskExecutionTime: triggerTimeArg,
|
|
100
|
-
taskExecutionTimeout: taskToSchedule.timeout,
|
|
101
|
-
taskName: taskToSchedule.name,
|
|
102
|
-
taskVersion: taskToSchedule.version,
|
|
103
|
-
});
|
|
104
|
-
|
|
69
|
+
const announcementResult = await this.performDistributedConsultation(task, triggerTime);
|
|
105
70
|
if (!announcementResult.shouldTrigger) {
|
|
106
|
-
console.log('
|
|
71
|
+
console.log('Distributed coordinator result: NOT EXECUTING');
|
|
107
72
|
return;
|
|
108
73
|
} else {
|
|
109
|
-
console.log('
|
|
74
|
+
console.log('Distributed coordinator result: CHOSEN AND EXECUTING');
|
|
110
75
|
}
|
|
111
76
|
}
|
|
112
|
-
await
|
|
77
|
+
await task.trigger();
|
|
113
78
|
}
|
|
114
79
|
);
|
|
115
|
-
|
|
80
|
+
task.cronJob = cronJob;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
private logTaskState(task: Task) {
|
|
84
|
+
console.log(`Taskbuffer schedule triggered task >>${task.name}<<`);
|
|
85
|
+
const bufferState = task.buffered
|
|
86
|
+
? `buffered with max ${task.bufferMax} buffered calls`
|
|
87
|
+
: `unbuffered`;
|
|
88
|
+
console.log(`Task >>${task.name}<< is ${bufferState}`);
|
|
116
89
|
}
|
|
117
90
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
91
|
+
private async performDistributedConsultation(task: Task, triggerTime: number): Promise<IDistributedTaskRequestResult> {
|
|
92
|
+
console.log('Found a distributed coordinator, performing consultation.');
|
|
93
|
+
return this.options.distributedCoordinator.fireDistributedTaskRequest({
|
|
94
|
+
submitterId: this.randomId,
|
|
95
|
+
status: 'requesting',
|
|
96
|
+
taskExecutionParallel: 1,
|
|
97
|
+
taskExecutionTime: triggerTime,
|
|
98
|
+
taskExecutionTimeout: task.timeout,
|
|
99
|
+
taskName: task.name,
|
|
100
|
+
taskVersion: task.version,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public descheduleTaskByName(taskName: string) {
|
|
105
|
+
const task = this.getTaskByName(taskName);
|
|
106
|
+
if (task && task.cronJob) {
|
|
107
|
+
this.cronJobManager.removeCronjob(task.cronJob);
|
|
108
|
+
task.cronJob = null;
|
|
127
109
|
}
|
|
128
110
|
if (this.cronJobManager.cronjobs.isEmpty) {
|
|
129
111
|
this.cronJobManager.stop();
|
|
130
112
|
}
|
|
131
113
|
}
|
|
132
114
|
|
|
133
|
-
/**
|
|
134
|
-
* deschedules a task
|
|
135
|
-
* @param task
|
|
136
|
-
*/
|
|
137
115
|
public async descheduleTask(task: Task) {
|
|
138
116
|
await this.descheduleTaskByName(task.name);
|
|
139
117
|
}
|
|
140
118
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
*/
|
|
145
|
-
public getScheduleForTaskName(taskNameArg: string): string | null {
|
|
146
|
-
const task = this.getTaskByName(taskNameArg);
|
|
147
|
-
if (!task || !task.cronJob) {
|
|
148
|
-
return null;
|
|
119
|
+
public getScheduleForTaskName(taskName: string): string | null {
|
|
120
|
+
const task = this.getTaskByName(taskName);
|
|
121
|
+
return task && task.cronJob ? task.cronJob.cronExpression : null;
|
|
149
122
|
}
|
|
150
|
-
return task.cronJob.cronExpression;
|
|
151
|
-
}
|
|
152
123
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
public start() {
|
|
124
|
+
public async start() {
|
|
125
|
+
if (this.options.distributedCoordinator) {
|
|
126
|
+
await this.options.distributedCoordinator.start();
|
|
127
|
+
}
|
|
158
128
|
this.cronJobManager.start();
|
|
159
129
|
}
|
|
160
130
|
|
|
161
|
-
|
|
162
|
-
* stops the taskmanager
|
|
163
|
-
*/
|
|
164
|
-
public stop() {
|
|
131
|
+
public async stop() {
|
|
165
132
|
this.cronJobManager.stop();
|
|
133
|
+
if (this.options.distributedCoordinator) {
|
|
134
|
+
await this.options.distributedCoordinator.stop();
|
|
135
|
+
}
|
|
166
136
|
}
|
|
167
137
|
}
|