@pikku/schedule 0.11.1 → 0.12.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/CHANGELOG.md +8 -0
- package/dist/in-memory-scheduler-service.d.ts +35 -0
- package/dist/in-memory-scheduler-service.js +117 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +5 -1
- package/package.json +4 -4
- package/src/in-memory-scheduler-service.test.ts +47 -0
- package/src/in-memory-scheduler-service.ts +165 -0
- package/src/index.ts +6 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/pikku-task-scheduler.d.ts +0 -12
- package/dist/pikku-task-scheduler.js +0 -49
- package/src/pikku-task-scheduler.ts +0 -77
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## 0.12.0
|
|
2
|
+
|
|
3
|
+
### New Features
|
|
4
|
+
|
|
5
|
+
- `InMemorySchedulerService` replacing `PikkuTaskScheduler` with full `SchedulerService` interface
|
|
6
|
+
- Recurring cron task support via `node-cron`
|
|
7
|
+
- `setServices()`, `start()`, `stop()` lifecycle methods
|
|
8
|
+
|
|
1
9
|
## 0.11.0
|
|
2
10
|
|
|
3
11
|
## 0.11.1
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { CoreUserSession, SchedulerService, SchedulerRuntimeHandlers, ScheduledTaskInfo, ScheduledTaskSummary } from '@pikku/core';
|
|
2
|
+
/**
|
|
3
|
+
* In-memory SchedulerService implementation.
|
|
4
|
+
* Uses CronJob for recurring tasks and setTimeout for delayed RPCs.
|
|
5
|
+
*/
|
|
6
|
+
export declare class InMemorySchedulerService extends SchedulerService {
|
|
7
|
+
private cronJobs;
|
|
8
|
+
private delayedTasks;
|
|
9
|
+
private idCounter;
|
|
10
|
+
private handlers?;
|
|
11
|
+
/**
|
|
12
|
+
* Set services needed for processing recurring tasks.
|
|
13
|
+
* Must be called before start() since the scheduler is typically
|
|
14
|
+
* created before singletonServices are available.
|
|
15
|
+
*/
|
|
16
|
+
setServices(handlers: SchedulerRuntimeHandlers): void;
|
|
17
|
+
init(): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Schedule a one-off delayed RPC call via setTimeout
|
|
20
|
+
*/
|
|
21
|
+
scheduleRPC(delay: number | string, rpcName: string, data?: any, session?: CoreUserSession): Promise<string>;
|
|
22
|
+
unschedule(taskId: string): Promise<boolean>;
|
|
23
|
+
getTask(taskId: string): Promise<ScheduledTaskInfo | null>;
|
|
24
|
+
getAllTasks(): Promise<ScheduledTaskSummary[]>;
|
|
25
|
+
close(): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Start recurring scheduled tasks.
|
|
28
|
+
*/
|
|
29
|
+
start(): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Stop all recurring CronJobs.
|
|
32
|
+
*/
|
|
33
|
+
stop(): Promise<void>;
|
|
34
|
+
private startCronJob;
|
|
35
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { CronJob } from 'cron';
|
|
2
|
+
import { SchedulerService, parseDurationString, } from '@pikku/core';
|
|
3
|
+
import { getScheduledTasks } from '@pikku/core/scheduler';
|
|
4
|
+
/**
|
|
5
|
+
* In-memory SchedulerService implementation.
|
|
6
|
+
* Uses CronJob for recurring tasks and setTimeout for delayed RPCs.
|
|
7
|
+
*/
|
|
8
|
+
export class InMemorySchedulerService extends SchedulerService {
|
|
9
|
+
cronJobs = new Map();
|
|
10
|
+
delayedTasks = new Map();
|
|
11
|
+
idCounter = 0;
|
|
12
|
+
handlers;
|
|
13
|
+
/**
|
|
14
|
+
* Set services needed for processing recurring tasks.
|
|
15
|
+
* Must be called before start() since the scheduler is typically
|
|
16
|
+
* created before singletonServices are available.
|
|
17
|
+
*/
|
|
18
|
+
setServices(handlers) {
|
|
19
|
+
this.handlers = handlers;
|
|
20
|
+
}
|
|
21
|
+
async init() { }
|
|
22
|
+
/**
|
|
23
|
+
* Schedule a one-off delayed RPC call via setTimeout
|
|
24
|
+
*/
|
|
25
|
+
async scheduleRPC(delay, rpcName, data, session) {
|
|
26
|
+
if (!this.handlers) {
|
|
27
|
+
throw new Error('InMemorySchedulerService requires setServices() before scheduling RPCs');
|
|
28
|
+
}
|
|
29
|
+
const delayMs = typeof delay === 'string' ? parseDurationString(delay) : delay;
|
|
30
|
+
const taskId = `inmem-${++this.idCounter}-${Date.now()}`;
|
|
31
|
+
const scheduledFor = new Date(Date.now() + delayMs);
|
|
32
|
+
const timer = setTimeout(async () => {
|
|
33
|
+
this.delayedTasks.delete(taskId);
|
|
34
|
+
try {
|
|
35
|
+
await this.handlers.invokeRPC(rpcName, data, session);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
this.handlers.logger.error(`Failed to execute delayed RPC '${rpcName}': ${err}`);
|
|
39
|
+
}
|
|
40
|
+
}, delayMs);
|
|
41
|
+
this.delayedTasks.set(taskId, {
|
|
42
|
+
taskId,
|
|
43
|
+
rpcName,
|
|
44
|
+
data,
|
|
45
|
+
session,
|
|
46
|
+
scheduledFor,
|
|
47
|
+
timer,
|
|
48
|
+
});
|
|
49
|
+
return taskId;
|
|
50
|
+
}
|
|
51
|
+
async unschedule(taskId) {
|
|
52
|
+
const task = this.delayedTasks.get(taskId);
|
|
53
|
+
if (task) {
|
|
54
|
+
clearTimeout(task.timer);
|
|
55
|
+
this.delayedTasks.delete(taskId);
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
async getTask(taskId) {
|
|
61
|
+
const task = this.delayedTasks.get(taskId);
|
|
62
|
+
if (!task)
|
|
63
|
+
return null;
|
|
64
|
+
return {
|
|
65
|
+
taskId: task.taskId,
|
|
66
|
+
rpcName: task.rpcName,
|
|
67
|
+
scheduledFor: task.scheduledFor,
|
|
68
|
+
data: task.data,
|
|
69
|
+
session: task.session,
|
|
70
|
+
status: 'scheduled',
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
async getAllTasks() {
|
|
74
|
+
return Array.from(this.delayedTasks.values()).map((t) => ({
|
|
75
|
+
taskId: t.taskId,
|
|
76
|
+
rpcName: t.rpcName,
|
|
77
|
+
scheduledFor: t.scheduledFor,
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
async close() {
|
|
81
|
+
await this.stop();
|
|
82
|
+
// Clear delayed tasks
|
|
83
|
+
for (const [, task] of this.delayedTasks) {
|
|
84
|
+
clearTimeout(task.timer);
|
|
85
|
+
}
|
|
86
|
+
this.delayedTasks.clear();
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Start recurring scheduled tasks.
|
|
90
|
+
*/
|
|
91
|
+
async start() {
|
|
92
|
+
if (!this.handlers) {
|
|
93
|
+
throw new Error('InMemorySchedulerService requires setServices() before start()');
|
|
94
|
+
}
|
|
95
|
+
const scheduledTasks = getScheduledTasks();
|
|
96
|
+
for (const [, task] of scheduledTasks) {
|
|
97
|
+
this.startCronJob(task.name, task.schedule);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Stop all recurring CronJobs.
|
|
102
|
+
*/
|
|
103
|
+
async stop() {
|
|
104
|
+
for (const [, job] of this.cronJobs) {
|
|
105
|
+
job.stop();
|
|
106
|
+
}
|
|
107
|
+
this.cronJobs.clear();
|
|
108
|
+
}
|
|
109
|
+
startCronJob(name, schedule) {
|
|
110
|
+
const job = new CronJob(schedule, async () => {
|
|
111
|
+
this.handlers.logger.info(`Running scheduled task: ${name}`);
|
|
112
|
+
await this.handlers.runScheduledTask(name);
|
|
113
|
+
this.handlers.logger.debug(`Completed scheduled task: ${name}`);
|
|
114
|
+
}, null, true);
|
|
115
|
+
this.cronJobs.set(name, job);
|
|
116
|
+
}
|
|
117
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { InMemorySchedulerService } from './in-memory-scheduler-service.js';
|
|
2
|
+
/**
|
|
3
|
+
* @deprecated Use InMemorySchedulerService instead
|
|
4
|
+
*/
|
|
5
|
+
export { InMemorySchedulerService as PikkuTaskScheduler } from './in-memory-scheduler-service.js';
|
package/dist/index.js
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { InMemorySchedulerService } from './in-memory-scheduler-service.js';
|
|
2
|
+
/**
|
|
3
|
+
* @deprecated Use InMemorySchedulerService instead
|
|
4
|
+
*/
|
|
5
|
+
export { InMemorySchedulerService as PikkuTaskScheduler } from './in-memory-scheduler-service.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pikku/schedule",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"author": "yasser.fadl@gmail.com",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -16,17 +16,17 @@
|
|
|
16
16
|
"test:coverage": "bash run-tests.sh --coverage"
|
|
17
17
|
},
|
|
18
18
|
"peerDependencies": {
|
|
19
|
-
"@pikku/core": "^0.
|
|
19
|
+
"@pikku/core": "^0.12.0"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@types/node": "^24.10.
|
|
22
|
+
"@types/node": "^24.10.12",
|
|
23
23
|
"typescript": "^5.9"
|
|
24
24
|
},
|
|
25
25
|
"engines": {
|
|
26
26
|
"node": ">=18"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"cron": "^4.
|
|
29
|
+
"cron": "^4.4.0",
|
|
30
30
|
"cron-schedule": "^5.0.4"
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { describe, test } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
|
|
4
|
+
import { InMemorySchedulerService } from './in-memory-scheduler-service.js'
|
|
5
|
+
|
|
6
|
+
describe('InMemorySchedulerService scheduleRPC', () => {
|
|
7
|
+
test('throws when setServices has not been called', async () => {
|
|
8
|
+
const scheduler = new InMemorySchedulerService()
|
|
9
|
+
await assert.rejects(() => scheduler.scheduleRPC(0, 'testRpc', {}), {
|
|
10
|
+
message:
|
|
11
|
+
'InMemorySchedulerService requires setServices() before scheduling RPCs',
|
|
12
|
+
})
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
test('uses empty wire context and does not create wire services', async () => {
|
|
16
|
+
const scheduler = new InMemorySchedulerService()
|
|
17
|
+
const session = { userId: 'user-1' }
|
|
18
|
+
|
|
19
|
+
const logger = {
|
|
20
|
+
info: () => {},
|
|
21
|
+
warn: () => {},
|
|
22
|
+
debug: () => {},
|
|
23
|
+
error: () => {},
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let invokeCalls = 0
|
|
27
|
+
let capturedSession: any
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
scheduler.setServices({
|
|
31
|
+
logger,
|
|
32
|
+
invokeRPC: async (_rpcName: string, _data: any, sessionArg?: any) => {
|
|
33
|
+
invokeCalls += 1
|
|
34
|
+
capturedSession = sessionArg
|
|
35
|
+
},
|
|
36
|
+
runScheduledTask: async () => {},
|
|
37
|
+
} as any)
|
|
38
|
+
await scheduler.scheduleRPC(0, 'testRpc', { ok: true }, session as any)
|
|
39
|
+
await new Promise((resolve) => setTimeout(resolve, 10))
|
|
40
|
+
} finally {
|
|
41
|
+
await scheduler.close()
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
assert.equal(invokeCalls, 1)
|
|
45
|
+
assert.equal(capturedSession, session)
|
|
46
|
+
})
|
|
47
|
+
})
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { CronJob } from 'cron'
|
|
2
|
+
import {
|
|
3
|
+
CoreUserSession,
|
|
4
|
+
SchedulerService,
|
|
5
|
+
SchedulerRuntimeHandlers,
|
|
6
|
+
ScheduledTaskInfo,
|
|
7
|
+
ScheduledTaskSummary,
|
|
8
|
+
parseDurationString,
|
|
9
|
+
} from '@pikku/core'
|
|
10
|
+
import { getScheduledTasks } from '@pikku/core/scheduler'
|
|
11
|
+
|
|
12
|
+
interface DelayedTask {
|
|
13
|
+
taskId: string
|
|
14
|
+
rpcName: string
|
|
15
|
+
data?: any
|
|
16
|
+
session?: CoreUserSession
|
|
17
|
+
scheduledFor: Date
|
|
18
|
+
timer: ReturnType<typeof setTimeout>
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* In-memory SchedulerService implementation.
|
|
23
|
+
* Uses CronJob for recurring tasks and setTimeout for delayed RPCs.
|
|
24
|
+
*/
|
|
25
|
+
export class InMemorySchedulerService extends SchedulerService {
|
|
26
|
+
private cronJobs = new Map<string, CronJob>()
|
|
27
|
+
private delayedTasks = new Map<string, DelayedTask>()
|
|
28
|
+
private idCounter = 0
|
|
29
|
+
private handlers?: SchedulerRuntimeHandlers
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Set services needed for processing recurring tasks.
|
|
33
|
+
* Must be called before start() since the scheduler is typically
|
|
34
|
+
* created before singletonServices are available.
|
|
35
|
+
*/
|
|
36
|
+
setServices(handlers: SchedulerRuntimeHandlers): void {
|
|
37
|
+
this.handlers = handlers
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async init(): Promise<void> {}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Schedule a one-off delayed RPC call via setTimeout
|
|
44
|
+
*/
|
|
45
|
+
async scheduleRPC(
|
|
46
|
+
delay: number | string,
|
|
47
|
+
rpcName: string,
|
|
48
|
+
data?: any,
|
|
49
|
+
session?: CoreUserSession
|
|
50
|
+
): Promise<string> {
|
|
51
|
+
if (!this.handlers) {
|
|
52
|
+
throw new Error(
|
|
53
|
+
'InMemorySchedulerService requires setServices() before scheduling RPCs'
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const delayMs =
|
|
58
|
+
typeof delay === 'string' ? parseDurationString(delay) : delay
|
|
59
|
+
const taskId = `inmem-${++this.idCounter}-${Date.now()}`
|
|
60
|
+
const scheduledFor = new Date(Date.now() + delayMs)
|
|
61
|
+
|
|
62
|
+
const timer = setTimeout(async () => {
|
|
63
|
+
this.delayedTasks.delete(taskId)
|
|
64
|
+
try {
|
|
65
|
+
await this.handlers!.invokeRPC(rpcName, data, session)
|
|
66
|
+
} catch (err: unknown) {
|
|
67
|
+
this.handlers!.logger.error(
|
|
68
|
+
`Failed to execute delayed RPC '${rpcName}': ${err}`
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
}, delayMs)
|
|
72
|
+
|
|
73
|
+
this.delayedTasks.set(taskId, {
|
|
74
|
+
taskId,
|
|
75
|
+
rpcName,
|
|
76
|
+
data,
|
|
77
|
+
session,
|
|
78
|
+
scheduledFor,
|
|
79
|
+
timer,
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
return taskId
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async unschedule(taskId: string): Promise<boolean> {
|
|
86
|
+
const task = this.delayedTasks.get(taskId)
|
|
87
|
+
if (task) {
|
|
88
|
+
clearTimeout(task.timer)
|
|
89
|
+
this.delayedTasks.delete(taskId)
|
|
90
|
+
return true
|
|
91
|
+
}
|
|
92
|
+
return false
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async getTask(taskId: string): Promise<ScheduledTaskInfo | null> {
|
|
96
|
+
const task = this.delayedTasks.get(taskId)
|
|
97
|
+
if (!task) return null
|
|
98
|
+
return {
|
|
99
|
+
taskId: task.taskId,
|
|
100
|
+
rpcName: task.rpcName,
|
|
101
|
+
scheduledFor: task.scheduledFor,
|
|
102
|
+
data: task.data,
|
|
103
|
+
session: task.session,
|
|
104
|
+
status: 'scheduled',
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async getAllTasks(): Promise<ScheduledTaskSummary[]> {
|
|
109
|
+
return Array.from(this.delayedTasks.values()).map((t) => ({
|
|
110
|
+
taskId: t.taskId,
|
|
111
|
+
rpcName: t.rpcName,
|
|
112
|
+
scheduledFor: t.scheduledFor,
|
|
113
|
+
}))
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async close(): Promise<void> {
|
|
117
|
+
await this.stop()
|
|
118
|
+
// Clear delayed tasks
|
|
119
|
+
for (const [, task] of this.delayedTasks) {
|
|
120
|
+
clearTimeout(task.timer)
|
|
121
|
+
}
|
|
122
|
+
this.delayedTasks.clear()
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Start recurring scheduled tasks.
|
|
127
|
+
*/
|
|
128
|
+
async start(): Promise<void> {
|
|
129
|
+
if (!this.handlers) {
|
|
130
|
+
throw new Error(
|
|
131
|
+
'InMemorySchedulerService requires setServices() before start()'
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const scheduledTasks = getScheduledTasks()
|
|
136
|
+
|
|
137
|
+
for (const [, task] of scheduledTasks) {
|
|
138
|
+
this.startCronJob(task.name, task.schedule)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Stop all recurring CronJobs.
|
|
144
|
+
*/
|
|
145
|
+
async stop(): Promise<void> {
|
|
146
|
+
for (const [, job] of this.cronJobs) {
|
|
147
|
+
job.stop()
|
|
148
|
+
}
|
|
149
|
+
this.cronJobs.clear()
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private startCronJob(name: string, schedule: string) {
|
|
153
|
+
const job = new CronJob(
|
|
154
|
+
schedule,
|
|
155
|
+
async () => {
|
|
156
|
+
this.handlers!.logger.info(`Running scheduled task: ${name}`)
|
|
157
|
+
await this.handlers!.runScheduledTask(name)
|
|
158
|
+
this.handlers!.logger.debug(`Completed scheduled task: ${name}`)
|
|
159
|
+
},
|
|
160
|
+
null,
|
|
161
|
+
true
|
|
162
|
+
)
|
|
163
|
+
this.cronJobs.set(name, job)
|
|
164
|
+
}
|
|
165
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1 +1,6 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { InMemorySchedulerService } from './in-memory-scheduler-service.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @deprecated Use InMemorySchedulerService instead
|
|
5
|
+
*/
|
|
6
|
+
export { InMemorySchedulerService as PikkuTaskScheduler } from './in-memory-scheduler-service.js'
|
package/tsconfig.tsbuildinfo
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["./src/
|
|
1
|
+
{"root":["./src/in-memory-scheduler-service.ts","./src/index.ts"],"version":"5.9.3"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { CoreServices, CoreSingletonServices, CoreUserSession, CreateWireServices } from '@pikku/core';
|
|
2
|
-
export declare class PikkuTaskScheduler<TaskName extends string> {
|
|
3
|
-
private singletonServices;
|
|
4
|
-
private createWireServices?;
|
|
5
|
-
private jobs;
|
|
6
|
-
constructor(singletonServices: CoreSingletonServices, createWireServices?: CreateWireServices<CoreSingletonServices, CoreServices, CoreUserSession> | undefined);
|
|
7
|
-
startAll(): void;
|
|
8
|
-
stopAll(): void;
|
|
9
|
-
start(names: TaskName[]): void;
|
|
10
|
-
stop(names: TaskName[]): void;
|
|
11
|
-
private startJobSchedule;
|
|
12
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { CronJob } from 'cron';
|
|
2
|
-
import { runScheduledTask, getScheduledTasks, } from '@pikku/core/scheduler';
|
|
3
|
-
export class PikkuTaskScheduler {
|
|
4
|
-
singletonServices;
|
|
5
|
-
createWireServices;
|
|
6
|
-
jobs = new Map();
|
|
7
|
-
constructor(singletonServices, createWireServices) {
|
|
8
|
-
this.singletonServices = singletonServices;
|
|
9
|
-
this.createWireServices = createWireServices;
|
|
10
|
-
}
|
|
11
|
-
startAll() {
|
|
12
|
-
const scheduledTasks = getScheduledTasks();
|
|
13
|
-
scheduledTasks.forEach((task) => this.startJobSchedule(task));
|
|
14
|
-
}
|
|
15
|
-
stopAll() {
|
|
16
|
-
this.jobs.forEach((job) => job.stop());
|
|
17
|
-
this.jobs.clear();
|
|
18
|
-
}
|
|
19
|
-
start(names) {
|
|
20
|
-
const scheduledTasks = getScheduledTasks();
|
|
21
|
-
for (const name of names) {
|
|
22
|
-
const task = scheduledTasks.get(name);
|
|
23
|
-
if (task) {
|
|
24
|
-
this.startJobSchedule(task);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
stop(names) {
|
|
29
|
-
for (const name of names) {
|
|
30
|
-
const job = this.jobs.get(name);
|
|
31
|
-
if (job) {
|
|
32
|
-
job.stop();
|
|
33
|
-
this.jobs.delete(name);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
startJobSchedule(task) {
|
|
38
|
-
const job = new CronJob(task.schedule, async () => {
|
|
39
|
-
this.singletonServices.logger.info(`Running scheduled task: ${task.name}`);
|
|
40
|
-
await runScheduledTask({
|
|
41
|
-
singletonServices: this.singletonServices,
|
|
42
|
-
createWireServices: this.createWireServices,
|
|
43
|
-
name: task.name,
|
|
44
|
-
});
|
|
45
|
-
this.singletonServices.logger.debug(`Completed scheduled task: ${task.name}`);
|
|
46
|
-
}, null, true);
|
|
47
|
-
this.jobs.set(task.name, job);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { CronJob } from 'cron'
|
|
2
|
-
import {
|
|
3
|
-
CoreServices,
|
|
4
|
-
CoreSingletonServices,
|
|
5
|
-
CoreUserSession,
|
|
6
|
-
CreateWireServices,
|
|
7
|
-
} from '@pikku/core'
|
|
8
|
-
import {
|
|
9
|
-
runScheduledTask,
|
|
10
|
-
CoreScheduledTask,
|
|
11
|
-
getScheduledTasks,
|
|
12
|
-
} from '@pikku/core/scheduler'
|
|
13
|
-
|
|
14
|
-
export class PikkuTaskScheduler<TaskName extends string> {
|
|
15
|
-
private jobs = new Map<string, CronJob>()
|
|
16
|
-
|
|
17
|
-
constructor(
|
|
18
|
-
private singletonServices: CoreSingletonServices,
|
|
19
|
-
private createWireServices?: CreateWireServices<
|
|
20
|
-
CoreSingletonServices,
|
|
21
|
-
CoreServices,
|
|
22
|
-
CoreUserSession
|
|
23
|
-
>
|
|
24
|
-
) {}
|
|
25
|
-
|
|
26
|
-
public startAll() {
|
|
27
|
-
const scheduledTasks = getScheduledTasks()
|
|
28
|
-
scheduledTasks.forEach((task) => this.startJobSchedule(task))
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
public stopAll() {
|
|
32
|
-
this.jobs.forEach((job) => job.stop())
|
|
33
|
-
this.jobs.clear()
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
public start(names: TaskName[]) {
|
|
37
|
-
const scheduledTasks = getScheduledTasks()
|
|
38
|
-
for (const name of names) {
|
|
39
|
-
const task = scheduledTasks.get(name)
|
|
40
|
-
if (task) {
|
|
41
|
-
this.startJobSchedule(task)
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
public stop(names: TaskName[]) {
|
|
47
|
-
for (const name of names) {
|
|
48
|
-
const job = this.jobs.get(name)
|
|
49
|
-
if (job) {
|
|
50
|
-
job.stop()
|
|
51
|
-
this.jobs.delete(name)
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
private startJobSchedule(task: CoreScheduledTask) {
|
|
57
|
-
const job = new CronJob(
|
|
58
|
-
task.schedule,
|
|
59
|
-
async () => {
|
|
60
|
-
this.singletonServices.logger.info(
|
|
61
|
-
`Running scheduled task: ${task.name}`
|
|
62
|
-
)
|
|
63
|
-
await runScheduledTask({
|
|
64
|
-
singletonServices: this.singletonServices,
|
|
65
|
-
createWireServices: this.createWireServices as any,
|
|
66
|
-
name: task.name,
|
|
67
|
-
})
|
|
68
|
-
this.singletonServices.logger.debug(
|
|
69
|
-
`Completed scheduled task: ${task.name}`
|
|
70
|
-
)
|
|
71
|
-
},
|
|
72
|
-
null,
|
|
73
|
-
true
|
|
74
|
-
)
|
|
75
|
-
this.jobs.set(task.name, job)
|
|
76
|
-
}
|
|
77
|
-
}
|