@pisell/core 1.0.46 → 1.0.47
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/es/app/index.d.ts +1 -1
- package/es/cmd/const.d.ts +5 -5
- package/es/hooks/useStore/index.d.ts +1 -1
- package/es/indexDB/index.js +28 -24
- package/es/locales/type.d.ts +3 -3
- package/es/logger/index.js +3 -2
- package/es/models/index.d.ts +4 -4
- package/es/pubsub/index.d.ts +1 -1
- package/es/request/cache.d.ts +1 -1
- package/es/request/pisell2Request.d.ts +1 -1
- package/es/routes/index.d.ts +2 -2
- package/es/socket/types.d.ts +1 -1
- package/es/tasks/type.d.ts +4 -4
- package/es/variables/index.d.ts +3 -3
- package/lib/app/index.d.ts +1 -1
- package/lib/aws/index.js +3 -0
- package/lib/cmd/const.d.ts +5 -5
- package/lib/cmd/const.js +5 -5
- package/lib/cmd/index.js +2 -0
- package/lib/cookie/index.js +2 -4
- package/lib/data/index.js +3 -0
- package/lib/hooks/useStore/index.d.ts +1 -1
- package/lib/indexDB/index.js +18 -17
- package/lib/locales/index.js +95 -94
- package/lib/locales/type.d.ts +3 -3
- package/lib/logger/index.js +4 -2
- package/lib/models/index.d.ts +4 -4
- package/lib/pubsub/index.d.ts +1 -1
- package/lib/pubsub/index.js +1 -3
- package/lib/request/cache.d.ts +1 -1
- package/lib/request/pisell2Request.d.ts +1 -1
- package/lib/routes/index.d.ts +2 -2
- package/lib/routes/index.js +3 -1
- package/lib/socket/components/SocketMonitorPage.js +6 -12
- package/lib/socket/heartbeat.js +10 -5
- package/lib/socket/index.js +1 -3
- package/lib/socket/monitor.js +26 -24
- package/lib/socket/reconnect.js +10 -3
- package/lib/socket/socket.js +12 -10
- package/lib/socket/types.d.ts +1 -1
- package/lib/storage/index.js +25 -24
- package/lib/tasks/index.js +333 -329
- package/lib/tasks/type.d.ts +4 -4
- package/lib/variables/index.d.ts +3 -3
- package/package.json +1 -1
- package/es/app/app.d.ts +0 -99
- package/es/applicationManager/application.d.ts +0 -197
- package/es/applicationManager/index.d.ts +0 -19
- package/es/index.d.ts +0 -7
- package/es/logger/index.d.ts +0 -135
- package/es/menuManager/index.d.ts +0 -28
- package/es/request/config.d.ts +0 -3
- package/es/request/index.d.ts +0 -24
- package/es/request/type.d.ts +0 -57
- package/es/tasks/index.d.ts +0 -127
- package/es/utils/adaptiveThrottle/index.d.ts +0 -36
- package/lib/app/app.d.ts +0 -99
- package/lib/applicationManager/application.d.ts +0 -197
- package/lib/applicationManager/index.d.ts +0 -19
- package/lib/index.d.ts +0 -7
- package/lib/logger/index.d.ts +0 -135
- package/lib/menuManager/index.d.ts +0 -28
- package/lib/request/config.d.ts +0 -3
- package/lib/request/index.d.ts +0 -24
- package/lib/request/type.d.ts +0 -57
- package/lib/tasks/index.d.ts +0 -127
- package/lib/utils/adaptiveThrottle/index.d.ts +0 -36
package/lib/tasks/index.js
CHANGED
|
@@ -35,333 +35,20 @@ module.exports = __toCommonJS(tasks_exports);
|
|
|
35
35
|
var import_dayjs = __toESM(require("dayjs"));
|
|
36
36
|
var import_utils = require("@pisell/utils");
|
|
37
37
|
var import_useTasks = __toESM(require("./useTasks"));
|
|
38
|
-
var TasksManager = class {
|
|
38
|
+
var TasksManager = class _TasksManager {
|
|
39
|
+
static instance;
|
|
40
|
+
taskFunctions;
|
|
41
|
+
tasks = {
|
|
42
|
+
// 内置模块, 定时任务专用
|
|
43
|
+
scheduledTasks: {}
|
|
44
|
+
};
|
|
45
|
+
app;
|
|
46
|
+
db;
|
|
47
|
+
useTasks = import_useTasks.default;
|
|
48
|
+
watchTaskCallback = () => {
|
|
49
|
+
};
|
|
50
|
+
timerIds = [];
|
|
39
51
|
constructor(app) {
|
|
40
|
-
this.tasks = {
|
|
41
|
-
// 内置模块, 定时任务专用
|
|
42
|
-
scheduledTasks: {}
|
|
43
|
-
};
|
|
44
|
-
this.useTasks = import_useTasks.default;
|
|
45
|
-
this.watchTaskCallback = () => {
|
|
46
|
-
};
|
|
47
|
-
this.timerIds = [];
|
|
48
|
-
// 将任务队列状态同步到 local
|
|
49
|
-
this.saveTaskQueueToLocal = async (state) => {
|
|
50
|
-
var _a;
|
|
51
|
-
console.log("saveTaskQueueToLocal", state);
|
|
52
|
-
let tasksData = await this.db.get("tasks", "tasks");
|
|
53
|
-
const newData = { id: "tasks", ...state };
|
|
54
|
-
if (!tasksData) {
|
|
55
|
-
await this.db.add("tasks", newData);
|
|
56
|
-
} else {
|
|
57
|
-
await this.db.update("tasks", newData);
|
|
58
|
-
}
|
|
59
|
-
(_a = this.watchTaskCallback) == null ? void 0 : _a.call(this, this.tasks);
|
|
60
|
-
};
|
|
61
|
-
// 从 local 加载任务队列状态
|
|
62
|
-
this.loadTaskQueueFromLocal = async () => {
|
|
63
|
-
var _a, _b;
|
|
64
|
-
try {
|
|
65
|
-
const tasks = await this.db.get("tasks", "tasks");
|
|
66
|
-
for (let module2 in tasks) {
|
|
67
|
-
for (let queueId in tasks[module2]) {
|
|
68
|
-
for (let task of ((_b = (_a = tasks == null ? void 0 : tasks[module2]) == null ? void 0 : _a[queueId]) == null ? void 0 : _b.tasks) || []) {
|
|
69
|
-
if (task.destroy) {
|
|
70
|
-
delete tasks[module2][queueId].tasks;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
return tasks;
|
|
76
|
-
} catch (err) {
|
|
77
|
-
console.log("loadTaskQueueFromLocal", err);
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
/**
|
|
82
|
-
* @title: 执行任务
|
|
83
|
-
* @description:
|
|
84
|
-
* @param {Task} task
|
|
85
|
-
* @return {*}
|
|
86
|
-
* @Author: zhiwei.Wang
|
|
87
|
-
* @Date: 2024-09-26 13:53
|
|
88
|
-
*/
|
|
89
|
-
this.runTask = async (task) => {
|
|
90
|
-
const beforeAction = this.getTaskFunction(task.beforeAction || "");
|
|
91
|
-
const afterAction = this.getTaskFunction(task.afterAction || "");
|
|
92
|
-
const action = this.getTaskFunction(task.action || "");
|
|
93
|
-
let beforeActionRes;
|
|
94
|
-
let afterActionRes;
|
|
95
|
-
let actionRes = { status: "success" };
|
|
96
|
-
try {
|
|
97
|
-
if (beforeAction) {
|
|
98
|
-
beforeActionRes = await beforeAction({ task });
|
|
99
|
-
}
|
|
100
|
-
if (action) {
|
|
101
|
-
actionRes = await action({ task, beforeActionRes });
|
|
102
|
-
}
|
|
103
|
-
if (afterAction) {
|
|
104
|
-
afterActionRes = await afterAction({ task, actionRes, afterActionRes });
|
|
105
|
-
}
|
|
106
|
-
} catch (error) {
|
|
107
|
-
this.app.logger.addLog({
|
|
108
|
-
type: "info",
|
|
109
|
-
title: `任务执行失败-${task.id}`,
|
|
110
|
-
metadata: { error, taskPayload: task == null ? void 0 : task.payload }
|
|
111
|
-
});
|
|
112
|
-
actionRes = { status: "failure" };
|
|
113
|
-
}
|
|
114
|
-
console.log("Tasks--->", `任务执行成功: ${task.id}`);
|
|
115
|
-
return actionRes;
|
|
116
|
-
};
|
|
117
|
-
/**
|
|
118
|
-
* @title: 清除任务定时器
|
|
119
|
-
*/
|
|
120
|
-
this.clearTaskTimer = (params) => {
|
|
121
|
-
const { timerId, taskId } = params;
|
|
122
|
-
const _timerIds = [];
|
|
123
|
-
const needClearTimerIds = [];
|
|
124
|
-
this.timerIds.forEach((id) => {
|
|
125
|
-
const taskIdRult = taskId ? (id == null ? void 0 : id.taskId) === taskId : true;
|
|
126
|
-
const timerIdRult = timerId ? (id == null ? void 0 : id.timerId) === timerId : true;
|
|
127
|
-
if (taskIdRult && timerIdRult) {
|
|
128
|
-
needClearTimerIds.push(id);
|
|
129
|
-
} else {
|
|
130
|
-
_timerIds.push(id);
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
if (needClearTimerIds.length) {
|
|
134
|
-
for (let id of needClearTimerIds) {
|
|
135
|
-
clearTimeout(id.timerId);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
this.timerIds = [..._timerIds || []];
|
|
139
|
-
};
|
|
140
|
-
/**
|
|
141
|
-
* @title: 计算下一次执行时间
|
|
142
|
-
* @description: 根据定时任务配置计算下一次执行时间
|
|
143
|
-
* @param {Task} task
|
|
144
|
-
* @return {string | null} 下一次执行时间
|
|
145
|
-
*/
|
|
146
|
-
this.calculateNextExecuteTime = (task) => {
|
|
147
|
-
if (!task.scheduled) {
|
|
148
|
-
return null;
|
|
149
|
-
}
|
|
150
|
-
const { scheduled, scheduledResult } = task;
|
|
151
|
-
const now = (0, import_dayjs.default)();
|
|
152
|
-
if (scheduled.endAt && now.isAfter((0, import_dayjs.default)(scheduled.endAt))) {
|
|
153
|
-
return null;
|
|
154
|
-
}
|
|
155
|
-
if (Array.isArray(scheduled.executeAt)) {
|
|
156
|
-
const futureTime = scheduled.executeAt.map((time) => (0, import_dayjs.default)(time)).filter((time) => time.isAfter(now)).sort((a, b) => a.valueOf() - b.valueOf())[0];
|
|
157
|
-
if (futureTime) {
|
|
158
|
-
return futureTime.format("YYYY-MM-DD HH:mm:ss");
|
|
159
|
-
}
|
|
160
|
-
if (!scheduled.repeat) {
|
|
161
|
-
return null;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
if (scheduled.repeat && (scheduledResult == null ? void 0 : scheduledResult.nextExecuteTime)) {
|
|
165
|
-
const lastExecuteTime = (0, import_dayjs.default)(scheduledResult.nextExecuteTime);
|
|
166
|
-
const interval = scheduled.repeatInterval || 1;
|
|
167
|
-
let nextTime = lastExecuteTime;
|
|
168
|
-
switch (scheduled.repeatType) {
|
|
169
|
-
case "daily":
|
|
170
|
-
nextTime = lastExecuteTime.add(interval, "day");
|
|
171
|
-
break;
|
|
172
|
-
case "weekly":
|
|
173
|
-
nextTime = lastExecuteTime.add(interval, "week");
|
|
174
|
-
break;
|
|
175
|
-
case "monthly":
|
|
176
|
-
nextTime = lastExecuteTime.add(interval, "month");
|
|
177
|
-
break;
|
|
178
|
-
case "yearly":
|
|
179
|
-
nextTime = lastExecuteTime.add(interval, "year");
|
|
180
|
-
break;
|
|
181
|
-
default:
|
|
182
|
-
nextTime = lastExecuteTime.add(interval, "day");
|
|
183
|
-
}
|
|
184
|
-
if (scheduled.endAt && nextTime.isAfter((0, import_dayjs.default)(scheduled.endAt))) {
|
|
185
|
-
return null;
|
|
186
|
-
}
|
|
187
|
-
return nextTime.format("YYYY-MM-DD HH:mm:ss");
|
|
188
|
-
}
|
|
189
|
-
const executeTime = Array.isArray(scheduled.executeAt) ? scheduled.executeAt[0] : scheduled.executeAt;
|
|
190
|
-
return (0, import_dayjs.default)(executeTime).format("YYYY-MM-DD HH:mm:ss");
|
|
191
|
-
};
|
|
192
|
-
/**
|
|
193
|
-
* @title: 启动定时任务
|
|
194
|
-
* @description: 在特定时间点执行任务(仅在 scheduledTasks 模块中生效)
|
|
195
|
-
* @param {Task} task
|
|
196
|
-
* @return {*}
|
|
197
|
-
*/
|
|
198
|
-
this.startScheduledTask = (task) => {
|
|
199
|
-
var _a;
|
|
200
|
-
if (!task.scheduled) {
|
|
201
|
-
console.log("Tasks--->", "不是定时任务");
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
if (task.module !== "scheduledTasks") {
|
|
205
|
-
console.warn("Tasks--->", `定时任务只在 scheduledTasks 模块中生效,任务 ${task.id} 将作为普通任务执行`);
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
const nextExecuteTime = this.calculateNextExecuteTime(task);
|
|
209
|
-
if (!nextExecuteTime) {
|
|
210
|
-
console.log("Tasks--->", "定时任务已完成或无下次执行时间", task);
|
|
211
|
-
this.deleteTask({
|
|
212
|
-
module: task.module,
|
|
213
|
-
queueId: task.queueId,
|
|
214
|
-
taskId: task.id
|
|
215
|
-
});
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
const now = (0, import_dayjs.default)();
|
|
219
|
-
const executeTime = (0, import_dayjs.default)(nextExecuteTime);
|
|
220
|
-
const delay = executeTime.diff(now);
|
|
221
|
-
if (delay < 0) {
|
|
222
|
-
console.log("Tasks--->", "执行时间已过,跳过此次执行");
|
|
223
|
-
if (task.scheduled.repeat) {
|
|
224
|
-
const _task = { ...task };
|
|
225
|
-
_task.scheduledResult = {
|
|
226
|
-
count: ((_a = _task.scheduledResult) == null ? void 0 : _a.count) || 0,
|
|
227
|
-
nextExecuteTime
|
|
228
|
-
};
|
|
229
|
-
const newTask = this.updateTask({
|
|
230
|
-
module: task.module,
|
|
231
|
-
queueId: task.queueId,
|
|
232
|
-
taskId: task.id,
|
|
233
|
-
other: _task
|
|
234
|
-
});
|
|
235
|
-
if (newTask) {
|
|
236
|
-
this.startScheduledTask(newTask);
|
|
237
|
-
}
|
|
238
|
-
} else {
|
|
239
|
-
this.deleteTask({
|
|
240
|
-
module: task.module,
|
|
241
|
-
queueId: task.queueId,
|
|
242
|
-
taskId: task.id
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
console.log("Tasks--->", `定时任务将在 ${nextExecuteTime} 执行 (${delay}ms 后)`, task);
|
|
248
|
-
const timerId = setTimeout(async () => {
|
|
249
|
-
var _a2, _b;
|
|
250
|
-
try {
|
|
251
|
-
await this.runTask(task);
|
|
252
|
-
console.log("Tasks--->", "定时任务执行完成", task);
|
|
253
|
-
let _task = { ...task };
|
|
254
|
-
_task.scheduledResult = {
|
|
255
|
-
count: (((_a2 = _task.scheduledResult) == null ? void 0 : _a2.count) || 0) + 1,
|
|
256
|
-
timerId,
|
|
257
|
-
nextExecuteTime
|
|
258
|
-
};
|
|
259
|
-
if ((_b = task.scheduled) == null ? void 0 : _b.repeat) {
|
|
260
|
-
const newTask = this.updateTask({
|
|
261
|
-
module: task.module,
|
|
262
|
-
queueId: task.queueId,
|
|
263
|
-
taskId: task.id,
|
|
264
|
-
other: _task
|
|
265
|
-
});
|
|
266
|
-
if (newTask) {
|
|
267
|
-
this.startScheduledTask(newTask);
|
|
268
|
-
}
|
|
269
|
-
} else {
|
|
270
|
-
this.deleteTask({
|
|
271
|
-
module: task.module,
|
|
272
|
-
queueId: task.queueId,
|
|
273
|
-
taskId: task.id
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
|
-
} catch (error) {
|
|
277
|
-
this.clearTaskTimer({ timerId });
|
|
278
|
-
console.error("定时任务执行异常", error);
|
|
279
|
-
}
|
|
280
|
-
}, delay);
|
|
281
|
-
this.timerIds.push({ taskId: task.id, timerId });
|
|
282
|
-
};
|
|
283
|
-
/**
|
|
284
|
-
* @title: 启动轮询
|
|
285
|
-
* @description: 根据轮询间隔定期执行任务
|
|
286
|
-
* @param {Task} task
|
|
287
|
-
* @return {*}
|
|
288
|
-
*/
|
|
289
|
-
this.startPolling = (task) => {
|
|
290
|
-
if (!task.polling || !task.polling.interval) {
|
|
291
|
-
console.log("不是轮询任务");
|
|
292
|
-
return;
|
|
293
|
-
}
|
|
294
|
-
const timerId = setTimeout(async () => {
|
|
295
|
-
var _a;
|
|
296
|
-
try {
|
|
297
|
-
await this.runTask(task);
|
|
298
|
-
console.log("轮询任务", task);
|
|
299
|
-
let _task = { ...task };
|
|
300
|
-
_task.pollingResult = {
|
|
301
|
-
count: (((_a = _task.pollingResult) == null ? void 0 : _a.count) || 0) + 1,
|
|
302
|
-
timerId
|
|
303
|
-
};
|
|
304
|
-
const newTask = this.updateTask({
|
|
305
|
-
module: task.module,
|
|
306
|
-
queueId: task.queueId,
|
|
307
|
-
taskId: task.id,
|
|
308
|
-
other: _task
|
|
309
|
-
});
|
|
310
|
-
if (!newTask) {
|
|
311
|
-
return;
|
|
312
|
-
}
|
|
313
|
-
this.startPolling(newTask);
|
|
314
|
-
} catch (error) {
|
|
315
|
-
this.clearTaskTimer({ timerId });
|
|
316
|
-
console.error("轮询任务异常", error);
|
|
317
|
-
}
|
|
318
|
-
}, task.polling.interval);
|
|
319
|
-
this.timerIds.push({ taskId: task.id, timerId });
|
|
320
|
-
};
|
|
321
|
-
/**
|
|
322
|
-
* @title: 创建任务数据
|
|
323
|
-
* @description:
|
|
324
|
-
* @param {Partial} payload
|
|
325
|
-
* @return {*}
|
|
326
|
-
* @Author: zhiwei.Wang
|
|
327
|
-
* @Date: 2024-09-26 13:54
|
|
328
|
-
*/
|
|
329
|
-
this.createTaskData = (payload) => {
|
|
330
|
-
return {
|
|
331
|
-
id: (0, import_utils.getUniqueId)("task_"),
|
|
332
|
-
create_at: (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss"),
|
|
333
|
-
type: "local",
|
|
334
|
-
retries: 0,
|
|
335
|
-
maxRetries: 3,
|
|
336
|
-
status: "pending",
|
|
337
|
-
// 执行函数
|
|
338
|
-
action: "",
|
|
339
|
-
// 执行参数
|
|
340
|
-
payload: {},
|
|
341
|
-
// 执行前的钩子
|
|
342
|
-
beforeAction: "",
|
|
343
|
-
// 执行前的参数
|
|
344
|
-
beforePayload: {},
|
|
345
|
-
// 执行后的钩子
|
|
346
|
-
afterAction: "",
|
|
347
|
-
// 执行后的参数
|
|
348
|
-
afterPayload: {},
|
|
349
|
-
destroy: true,
|
|
350
|
-
...payload
|
|
351
|
-
};
|
|
352
|
-
};
|
|
353
|
-
this.getTaskQueue = (payload) => {
|
|
354
|
-
var _a, _b;
|
|
355
|
-
const { queueId, module: module2 } = payload;
|
|
356
|
-
return (_b = (_a = this.tasks[module2]) == null ? void 0 : _a[queueId]) == null ? void 0 : _b.tasks;
|
|
357
|
-
};
|
|
358
|
-
this.timeout = (ms) => {
|
|
359
|
-
return new Promise((resolve) => {
|
|
360
|
-
setTimeout(() => {
|
|
361
|
-
resolve(true);
|
|
362
|
-
}, ms || 5e3);
|
|
363
|
-
});
|
|
364
|
-
};
|
|
365
52
|
if (!app) {
|
|
366
53
|
throw new Error("app is required");
|
|
367
54
|
}
|
|
@@ -375,10 +62,10 @@ var TasksManager = class {
|
|
|
375
62
|
}
|
|
376
63
|
// 单例模式
|
|
377
64
|
static getInstance(app) {
|
|
378
|
-
if (!
|
|
379
|
-
|
|
65
|
+
if (!_TasksManager.instance && app) {
|
|
66
|
+
_TasksManager.instance = new _TasksManager(app);
|
|
380
67
|
}
|
|
381
|
-
return
|
|
68
|
+
return _TasksManager.instance;
|
|
382
69
|
}
|
|
383
70
|
// 注册任务函数
|
|
384
71
|
addTaskFunction(name, fun) {
|
|
@@ -408,6 +95,323 @@ var TasksManager = class {
|
|
|
408
95
|
console.log("initTasks", tasks);
|
|
409
96
|
}
|
|
410
97
|
}
|
|
98
|
+
// 将任务队列状态同步到 local
|
|
99
|
+
saveTaskQueueToLocal = async (state) => {
|
|
100
|
+
var _a;
|
|
101
|
+
console.log("saveTaskQueueToLocal", state);
|
|
102
|
+
let tasksData = await this.db.get("tasks", "tasks");
|
|
103
|
+
const newData = { id: "tasks", ...state };
|
|
104
|
+
if (!tasksData) {
|
|
105
|
+
await this.db.add("tasks", newData);
|
|
106
|
+
} else {
|
|
107
|
+
await this.db.update("tasks", newData);
|
|
108
|
+
}
|
|
109
|
+
(_a = this.watchTaskCallback) == null ? void 0 : _a.call(this, this.tasks);
|
|
110
|
+
};
|
|
111
|
+
// 从 local 加载任务队列状态
|
|
112
|
+
loadTaskQueueFromLocal = async () => {
|
|
113
|
+
var _a, _b;
|
|
114
|
+
try {
|
|
115
|
+
const tasks = await this.db.get("tasks", "tasks");
|
|
116
|
+
for (let module2 in tasks) {
|
|
117
|
+
for (let queueId in tasks[module2]) {
|
|
118
|
+
for (let task of ((_b = (_a = tasks == null ? void 0 : tasks[module2]) == null ? void 0 : _a[queueId]) == null ? void 0 : _b.tasks) || []) {
|
|
119
|
+
if (task.destroy) {
|
|
120
|
+
delete tasks[module2][queueId].tasks;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return tasks;
|
|
126
|
+
} catch (err) {
|
|
127
|
+
console.log("loadTaskQueueFromLocal", err);
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* @title: 执行任务
|
|
133
|
+
* @description:
|
|
134
|
+
* @param {Task} task
|
|
135
|
+
* @return {*}
|
|
136
|
+
* @Author: zhiwei.Wang
|
|
137
|
+
* @Date: 2024-09-26 13:53
|
|
138
|
+
*/
|
|
139
|
+
runTask = async (task) => {
|
|
140
|
+
const beforeAction = this.getTaskFunction(task.beforeAction || "");
|
|
141
|
+
const afterAction = this.getTaskFunction(task.afterAction || "");
|
|
142
|
+
const action = this.getTaskFunction(task.action || "");
|
|
143
|
+
let beforeActionRes;
|
|
144
|
+
let afterActionRes;
|
|
145
|
+
let actionRes = { status: "success" };
|
|
146
|
+
try {
|
|
147
|
+
if (beforeAction) {
|
|
148
|
+
beforeActionRes = await beforeAction({ task });
|
|
149
|
+
}
|
|
150
|
+
if (action) {
|
|
151
|
+
actionRes = await action({ task, beforeActionRes });
|
|
152
|
+
}
|
|
153
|
+
if (afterAction) {
|
|
154
|
+
afterActionRes = await afterAction({ task, actionRes, afterActionRes });
|
|
155
|
+
}
|
|
156
|
+
} catch (error) {
|
|
157
|
+
this.app.logger.addLog({
|
|
158
|
+
type: "info",
|
|
159
|
+
title: `任务执行失败-${task.id}`,
|
|
160
|
+
metadata: { error, taskPayload: task == null ? void 0 : task.payload }
|
|
161
|
+
});
|
|
162
|
+
actionRes = { status: "failure" };
|
|
163
|
+
}
|
|
164
|
+
console.log("Tasks--->", `任务执行成功: ${task.id}`);
|
|
165
|
+
return actionRes;
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* @title: 清除任务定时器
|
|
169
|
+
*/
|
|
170
|
+
clearTaskTimer = (params) => {
|
|
171
|
+
const { timerId, taskId } = params;
|
|
172
|
+
const _timerIds = [];
|
|
173
|
+
const needClearTimerIds = [];
|
|
174
|
+
this.timerIds.forEach((id) => {
|
|
175
|
+
const taskIdRult = taskId ? (id == null ? void 0 : id.taskId) === taskId : true;
|
|
176
|
+
const timerIdRult = timerId ? (id == null ? void 0 : id.timerId) === timerId : true;
|
|
177
|
+
if (taskIdRult && timerIdRult) {
|
|
178
|
+
needClearTimerIds.push(id);
|
|
179
|
+
} else {
|
|
180
|
+
_timerIds.push(id);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
if (needClearTimerIds.length) {
|
|
184
|
+
for (let id of needClearTimerIds) {
|
|
185
|
+
clearTimeout(id.timerId);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
this.timerIds = [..._timerIds || []];
|
|
189
|
+
};
|
|
190
|
+
/**
|
|
191
|
+
* @title: 计算下一次执行时间
|
|
192
|
+
* @description: 根据定时任务配置计算下一次执行时间
|
|
193
|
+
* @param {Task} task
|
|
194
|
+
* @return {string | null} 下一次执行时间
|
|
195
|
+
*/
|
|
196
|
+
calculateNextExecuteTime = (task) => {
|
|
197
|
+
if (!task.scheduled) {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
const { scheduled, scheduledResult } = task;
|
|
201
|
+
const now = (0, import_dayjs.default)();
|
|
202
|
+
if (scheduled.endAt && now.isAfter((0, import_dayjs.default)(scheduled.endAt))) {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
if (Array.isArray(scheduled.executeAt)) {
|
|
206
|
+
const futureTime = scheduled.executeAt.map((time) => (0, import_dayjs.default)(time)).filter((time) => time.isAfter(now)).sort((a, b) => a.valueOf() - b.valueOf())[0];
|
|
207
|
+
if (futureTime) {
|
|
208
|
+
return futureTime.format("YYYY-MM-DD HH:mm:ss");
|
|
209
|
+
}
|
|
210
|
+
if (!scheduled.repeat) {
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (scheduled.repeat && (scheduledResult == null ? void 0 : scheduledResult.nextExecuteTime)) {
|
|
215
|
+
const lastExecuteTime = (0, import_dayjs.default)(scheduledResult.nextExecuteTime);
|
|
216
|
+
const interval = scheduled.repeatInterval || 1;
|
|
217
|
+
let nextTime = lastExecuteTime;
|
|
218
|
+
switch (scheduled.repeatType) {
|
|
219
|
+
case "daily":
|
|
220
|
+
nextTime = lastExecuteTime.add(interval, "day");
|
|
221
|
+
break;
|
|
222
|
+
case "weekly":
|
|
223
|
+
nextTime = lastExecuteTime.add(interval, "week");
|
|
224
|
+
break;
|
|
225
|
+
case "monthly":
|
|
226
|
+
nextTime = lastExecuteTime.add(interval, "month");
|
|
227
|
+
break;
|
|
228
|
+
case "yearly":
|
|
229
|
+
nextTime = lastExecuteTime.add(interval, "year");
|
|
230
|
+
break;
|
|
231
|
+
default:
|
|
232
|
+
nextTime = lastExecuteTime.add(interval, "day");
|
|
233
|
+
}
|
|
234
|
+
if (scheduled.endAt && nextTime.isAfter((0, import_dayjs.default)(scheduled.endAt))) {
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
return nextTime.format("YYYY-MM-DD HH:mm:ss");
|
|
238
|
+
}
|
|
239
|
+
const executeTime = Array.isArray(scheduled.executeAt) ? scheduled.executeAt[0] : scheduled.executeAt;
|
|
240
|
+
return (0, import_dayjs.default)(executeTime).format("YYYY-MM-DD HH:mm:ss");
|
|
241
|
+
};
|
|
242
|
+
/**
|
|
243
|
+
* @title: 启动定时任务
|
|
244
|
+
* @description: 在特定时间点执行任务(仅在 scheduledTasks 模块中生效)
|
|
245
|
+
* @param {Task} task
|
|
246
|
+
* @return {*}
|
|
247
|
+
*/
|
|
248
|
+
startScheduledTask = (task) => {
|
|
249
|
+
var _a;
|
|
250
|
+
if (!task.scheduled) {
|
|
251
|
+
console.log("Tasks--->", "不是定时任务");
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
if (task.module !== "scheduledTasks") {
|
|
255
|
+
console.warn("Tasks--->", `定时任务只在 scheduledTasks 模块中生效,任务 ${task.id} 将作为普通任务执行`);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
const nextExecuteTime = this.calculateNextExecuteTime(task);
|
|
259
|
+
if (!nextExecuteTime) {
|
|
260
|
+
console.log("Tasks--->", "定时任务已完成或无下次执行时间", task);
|
|
261
|
+
this.deleteTask({
|
|
262
|
+
module: task.module,
|
|
263
|
+
queueId: task.queueId,
|
|
264
|
+
taskId: task.id
|
|
265
|
+
});
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
const now = (0, import_dayjs.default)();
|
|
269
|
+
const executeTime = (0, import_dayjs.default)(nextExecuteTime);
|
|
270
|
+
const delay = executeTime.diff(now);
|
|
271
|
+
if (delay < 0) {
|
|
272
|
+
console.log("Tasks--->", "执行时间已过,跳过此次执行");
|
|
273
|
+
if (task.scheduled.repeat) {
|
|
274
|
+
const _task = { ...task };
|
|
275
|
+
_task.scheduledResult = {
|
|
276
|
+
count: ((_a = _task.scheduledResult) == null ? void 0 : _a.count) || 0,
|
|
277
|
+
nextExecuteTime
|
|
278
|
+
};
|
|
279
|
+
const newTask = this.updateTask({
|
|
280
|
+
module: task.module,
|
|
281
|
+
queueId: task.queueId,
|
|
282
|
+
taskId: task.id,
|
|
283
|
+
other: _task
|
|
284
|
+
});
|
|
285
|
+
if (newTask) {
|
|
286
|
+
this.startScheduledTask(newTask);
|
|
287
|
+
}
|
|
288
|
+
} else {
|
|
289
|
+
this.deleteTask({
|
|
290
|
+
module: task.module,
|
|
291
|
+
queueId: task.queueId,
|
|
292
|
+
taskId: task.id
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
console.log("Tasks--->", `定时任务将在 ${nextExecuteTime} 执行 (${delay}ms 后)`, task);
|
|
298
|
+
const timerId = setTimeout(async () => {
|
|
299
|
+
var _a2, _b;
|
|
300
|
+
try {
|
|
301
|
+
await this.runTask(task);
|
|
302
|
+
console.log("Tasks--->", "定时任务执行完成", task);
|
|
303
|
+
let _task = { ...task };
|
|
304
|
+
_task.scheduledResult = {
|
|
305
|
+
count: (((_a2 = _task.scheduledResult) == null ? void 0 : _a2.count) || 0) + 1,
|
|
306
|
+
timerId,
|
|
307
|
+
nextExecuteTime
|
|
308
|
+
};
|
|
309
|
+
if ((_b = task.scheduled) == null ? void 0 : _b.repeat) {
|
|
310
|
+
const newTask = this.updateTask({
|
|
311
|
+
module: task.module,
|
|
312
|
+
queueId: task.queueId,
|
|
313
|
+
taskId: task.id,
|
|
314
|
+
other: _task
|
|
315
|
+
});
|
|
316
|
+
if (newTask) {
|
|
317
|
+
this.startScheduledTask(newTask);
|
|
318
|
+
}
|
|
319
|
+
} else {
|
|
320
|
+
this.deleteTask({
|
|
321
|
+
module: task.module,
|
|
322
|
+
queueId: task.queueId,
|
|
323
|
+
taskId: task.id
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
} catch (error) {
|
|
327
|
+
this.clearTaskTimer({ timerId });
|
|
328
|
+
console.error("定时任务执行异常", error);
|
|
329
|
+
}
|
|
330
|
+
}, delay);
|
|
331
|
+
this.timerIds.push({ taskId: task.id, timerId });
|
|
332
|
+
};
|
|
333
|
+
/**
|
|
334
|
+
* @title: 启动轮询
|
|
335
|
+
* @description: 根据轮询间隔定期执行任务
|
|
336
|
+
* @param {Task} task
|
|
337
|
+
* @return {*}
|
|
338
|
+
*/
|
|
339
|
+
startPolling = (task) => {
|
|
340
|
+
if (!task.polling || !task.polling.interval) {
|
|
341
|
+
console.log("不是轮询任务");
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
const timerId = setTimeout(async () => {
|
|
345
|
+
var _a;
|
|
346
|
+
try {
|
|
347
|
+
await this.runTask(task);
|
|
348
|
+
console.log("轮询任务", task);
|
|
349
|
+
let _task = { ...task };
|
|
350
|
+
_task.pollingResult = {
|
|
351
|
+
count: (((_a = _task.pollingResult) == null ? void 0 : _a.count) || 0) + 1,
|
|
352
|
+
timerId
|
|
353
|
+
};
|
|
354
|
+
const newTask = this.updateTask({
|
|
355
|
+
module: task.module,
|
|
356
|
+
queueId: task.queueId,
|
|
357
|
+
taskId: task.id,
|
|
358
|
+
other: _task
|
|
359
|
+
});
|
|
360
|
+
if (!newTask) {
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
this.startPolling(newTask);
|
|
364
|
+
} catch (error) {
|
|
365
|
+
this.clearTaskTimer({ timerId });
|
|
366
|
+
console.error("轮询任务异常", error);
|
|
367
|
+
}
|
|
368
|
+
}, task.polling.interval);
|
|
369
|
+
this.timerIds.push({ taskId: task.id, timerId });
|
|
370
|
+
};
|
|
371
|
+
/**
|
|
372
|
+
* @title: 创建任务数据
|
|
373
|
+
* @description:
|
|
374
|
+
* @param {Partial} payload
|
|
375
|
+
* @return {*}
|
|
376
|
+
* @Author: zhiwei.Wang
|
|
377
|
+
* @Date: 2024-09-26 13:54
|
|
378
|
+
*/
|
|
379
|
+
createTaskData = (payload) => {
|
|
380
|
+
return {
|
|
381
|
+
id: (0, import_utils.getUniqueId)("task_"),
|
|
382
|
+
create_at: (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss"),
|
|
383
|
+
type: "local",
|
|
384
|
+
retries: 0,
|
|
385
|
+
maxRetries: 3,
|
|
386
|
+
status: "pending",
|
|
387
|
+
// 执行函数
|
|
388
|
+
action: "",
|
|
389
|
+
// 执行参数
|
|
390
|
+
payload: {},
|
|
391
|
+
// 执行前的钩子
|
|
392
|
+
beforeAction: "",
|
|
393
|
+
// 执行前的参数
|
|
394
|
+
beforePayload: {},
|
|
395
|
+
// 执行后的钩子
|
|
396
|
+
afterAction: "",
|
|
397
|
+
// 执行后的参数
|
|
398
|
+
afterPayload: {},
|
|
399
|
+
destroy: true,
|
|
400
|
+
...payload
|
|
401
|
+
};
|
|
402
|
+
};
|
|
403
|
+
getTaskQueue = (payload) => {
|
|
404
|
+
var _a, _b;
|
|
405
|
+
const { queueId, module: module2 } = payload;
|
|
406
|
+
return (_b = (_a = this.tasks[module2]) == null ? void 0 : _a[queueId]) == null ? void 0 : _b.tasks;
|
|
407
|
+
};
|
|
408
|
+
timeout = (ms) => {
|
|
409
|
+
return new Promise((resolve) => {
|
|
410
|
+
setTimeout(() => {
|
|
411
|
+
resolve(true);
|
|
412
|
+
}, ms || 5e3);
|
|
413
|
+
});
|
|
414
|
+
};
|
|
411
415
|
/**
|
|
412
416
|
* @title: 执行任务队列
|
|
413
417
|
* @description:
|
package/lib/tasks/type.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type TaskRunStatus = "pending" | "in-progress" | "success" | "failure";
|
|
1
|
+
export declare type TaskRunStatus = "pending" | "in-progress" | "success" | "failure";
|
|
2
2
|
export interface Task {
|
|
3
3
|
id?: string;
|
|
4
4
|
type?: "local" | "cloud";
|
|
@@ -37,9 +37,9 @@ export interface Task {
|
|
|
37
37
|
export interface TaskConfig {
|
|
38
38
|
tasks: Task[];
|
|
39
39
|
}
|
|
40
|
-
type TaskModuleName = string;
|
|
41
|
-
type TaskQueueName = string;
|
|
42
|
-
type TaskStatus = "uncompleted" | "completed";
|
|
40
|
+
declare type TaskModuleName = string;
|
|
41
|
+
declare type TaskQueueName = string;
|
|
42
|
+
declare type TaskStatus = "uncompleted" | "completed";
|
|
43
43
|
export interface TaskQueue {
|
|
44
44
|
status: TaskStatus;
|
|
45
45
|
tasks: Task[];
|
package/lib/variables/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export type VariableMap = Record<string, string>;
|
|
1
|
+
export declare type VariableMap = Record<string, string>;
|
|
2
2
|
declare const _default: {
|
|
3
|
-
setConfig: (newConfig: Partial<import("
|
|
4
|
-
getConfig: () => import("
|
|
3
|
+
setConfig: (newConfig: Partial<import("./type").VariablesConfig>) => void;
|
|
4
|
+
getConfig: () => import("./type").VariablesConfig;
|
|
5
5
|
};
|
|
6
6
|
export default _default;
|