@chevre/domain 26.0.0-alpha.2 → 26.0.0-alpha.21
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/lib/chevre/eventEmitter/task.d.ts +8 -23
- package/lib/chevre/eventEmitter/task.js +2 -2
- package/lib/chevre/repo/adminAsyncAction.d.ts +2 -2
- package/lib/chevre/repo/adminScheduledTask.d.ts +1 -1
- package/lib/chevre/repo/adminTask.d.ts +31 -8
- package/lib/chevre/repo/adminTask.js +41 -26
- package/lib/chevre/repo/aggregateScheduledTask.d.ts +32 -0
- package/lib/chevre/repo/aggregateScheduledTask.js +136 -0
- package/lib/chevre/repo/asyncAction.d.ts +2 -2
- package/lib/chevre/repo/mongoose/schemas/setting.d.ts +1 -0
- package/lib/chevre/repo/mongoose/schemas/task.d.ts +2 -5
- package/lib/chevre/repo/mongoose/schemas/task.js +87 -96
- package/lib/chevre/repo/orderInTransaction.d.ts +0 -3
- package/lib/chevre/repo/orderInTransaction.js +30 -22
- package/lib/chevre/repo/scheduledTask.d.ts +5 -2
- package/lib/chevre/repo/scheduledTask.js +3 -25
- package/lib/chevre/repo/task.d.ts +25 -172
- package/lib/chevre/repo/task.js +19 -475
- package/lib/chevre/repo/taskDelayed.d.ts +74 -0
- package/lib/chevre/repo/taskDelayed.js +195 -0
- package/lib/chevre/repo/taskRunning.d.ts +35 -0
- package/lib/chevre/repo/taskRunning.js +89 -0
- package/lib/chevre/repository.d.ts +10 -0
- package/lib/chevre/repository.js +24 -2
- package/lib/chevre/service/aggregation/system.d.ts +10 -2
- package/lib/chevre/service/aggregation/system.js +42 -0
- package/lib/chevre/service/assetTransaction/reserve/start/factory/createStartParams.js +5 -25
- package/lib/chevre/service/asyncAction.d.ts +2 -2
- package/lib/chevre/service/asyncAction.js +1 -4
- package/lib/chevre/service/asyncActionHandler/onOperationFailed.d.ts +2 -2
- package/lib/chevre/service/asyncActionHandler/onOperationFailed.js +0 -2
- package/lib/chevre/service/asyncActionHandler.d.ts +4 -4
- package/lib/chevre/service/asyncActionHandler.js +11 -13
- package/lib/chevre/service/offer/eventServiceByCOA/authorize/factory.js +1 -1
- package/lib/chevre/service/offer/eventServiceByCOA/findAcceptAction.d.ts +0 -4
- package/lib/chevre/service/offer/eventServiceByCOA/findAcceptAction.js +19 -19
- package/lib/chevre/service/order/confirmPayTransaction.js +4 -1
- package/lib/chevre/service/order/onOrderStatusChanged/onOrderInTransit.js +4 -4
- package/lib/chevre/service/order/onOrderStatusChanged/onOrderPaymentDue.js +2 -2
- package/lib/chevre/service/order/onOrderStatusChanged/onOrderProcessing/createSendEmailMessageTaskIfNotExist.js +2 -2
- package/lib/chevre/service/order/onOrderStatusChanged/onOrderProcessing/factory.d.ts +2 -2
- package/lib/chevre/service/order/onOrderStatusChanged/onOrderProcessing/factory.js +1 -1
- package/lib/chevre/service/order/onOrderStatusChanged/onOrderProcessing/processOrder.js +2 -2
- package/lib/chevre/service/order/onOrderStatusChanged/onOrderProcessing.js +1 -1
- package/lib/chevre/service/payment/any/findAcceptAction.d.ts +0 -4
- package/lib/chevre/service/payment/any/findAcceptAction.js +19 -19
- package/lib/chevre/service/payment/any/findAuthorizeAction.d.ts +0 -4
- package/lib/chevre/service/payment/any/findAuthorizeAction.js +19 -19
- package/lib/chevre/service/payment/any/findCheckAction.d.ts +0 -4
- package/lib/chevre/service/payment/any/findCheckAction.js +19 -19
- package/lib/chevre/service/payment/any/publishPaymentUrl.d.ts +0 -2
- package/lib/chevre/service/payment/any/publishPaymentUrl.js +2 -2
- package/lib/chevre/service/project.d.ts +0 -3
- package/lib/chevre/service/project.js +0 -1
- package/lib/chevre/service/reserve/potentialActions/onReservationConfirmed.js +2 -2
- package/lib/chevre/service/scheduledTask.d.ts +1 -4
- package/lib/chevre/service/scheduledTask.js +3 -10
- package/lib/chevre/service/scheduledTaskHandler/onOperationFailed.js +1 -2
- package/lib/chevre/service/scheduledTaskHandler.js +0 -13
- package/lib/chevre/service/task/acceptCOAOffer.js +1 -14
- package/lib/chevre/service/task/authorizePayment.js +1 -7
- package/lib/chevre/service/task/checkMovieTicket.js +1 -7
- package/lib/chevre/service/task/confirmReserveTransaction.js +3 -1
- package/lib/chevre/service/task/importEventCapacitiesFromCOA.js +4 -1
- package/lib/chevre/service/task/importEventsFromCOA.js +4 -1
- package/lib/chevre/service/task/importOffersFromCOA.js +5 -5
- package/lib/chevre/service/task/publishPaymentUrl.js +2 -13
- package/lib/chevre/service/task/syncResourcesFromCOA.js +1 -5
- package/lib/chevre/service/task/voidReserveTransaction.js +5 -8
- package/lib/chevre/service/task.d.ts +3 -22
- package/lib/chevre/service/task.js +8 -40
- package/lib/chevre/service/taskHandler/onOperationFailed.d.ts +3 -2
- package/lib/chevre/service/taskHandler/onOperationFailed.js +5 -16
- package/lib/chevre/service/taskHandler.d.ts +1 -2
- package/lib/chevre/service/taskHandler.js +7 -53
- package/lib/chevre/service/transaction/placeOrder/exportTasks/factory.d.ts +8 -4
- package/lib/chevre/service/transaction/placeOrder/exportTasks/factory.js +55 -103
- package/lib/chevre/service/transaction/placeOrder/exportTasksById.d.ts +2 -0
- package/lib/chevre/service/transaction/placeOrder/exportTasksById.js +14 -10
- package/lib/chevre/service/transaction/returnOrder/exportTasks/factory.d.ts +13 -3
- package/lib/chevre/service/transaction/returnOrder/exportTasks/factory.js +48 -51
- package/lib/chevre/service/transaction/returnOrder.d.ts +2 -0
- package/lib/chevre/service/transaction/returnOrder.js +15 -13
- package/lib/chevre/service/transaction.d.ts +2 -0
- package/lib/chevre/service/transaction.js +0 -2
- package/lib/chevre/taskSettings.d.ts +4 -4
- package/package.json +2 -2
package/lib/chevre/repo/task.js
CHANGED
|
@@ -1,45 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.TaskRepo = void 0;
|
|
7
|
-
const moment_1 = __importDefault(require("moment"));
|
|
8
4
|
const errorHandler_1 = require("../errorHandler");
|
|
9
5
|
const task_1 = require("../eventEmitter/task");
|
|
10
6
|
const factory_1 = require("../factory");
|
|
11
|
-
const settings_1 = require("../settings");
|
|
12
7
|
const task_2 = require("./mongoose/schemas/task");
|
|
13
|
-
const executableTaskProjection = {
|
|
14
|
-
_id: 0,
|
|
15
|
-
id: { $toString: '$_id' },
|
|
16
|
-
// 必要最低限にprojection(2024-04-23~)
|
|
17
|
-
data: 1,
|
|
18
|
-
name: 1,
|
|
19
|
-
status: 1,
|
|
20
|
-
numberOfTried: 1,
|
|
21
|
-
project: 1,
|
|
22
|
-
remainingNumberOfTries: 1,
|
|
23
|
-
runsAt: 1,
|
|
24
|
-
expires: 1
|
|
25
|
-
};
|
|
26
|
-
const AVAILABLE_PROJECT_FIELDS = [
|
|
27
|
-
'alternateName',
|
|
28
|
-
'identifier',
|
|
29
|
-
'description',
|
|
30
|
-
'project',
|
|
31
|
-
'name',
|
|
32
|
-
'status',
|
|
33
|
-
'runsAt',
|
|
34
|
-
'remainingNumberOfTries',
|
|
35
|
-
'lastTriedAt',
|
|
36
|
-
'numberOfTried',
|
|
37
|
-
'executionResults',
|
|
38
|
-
'executor',
|
|
39
|
-
'data',
|
|
40
|
-
'dateAborted',
|
|
41
|
-
'expires'
|
|
42
|
-
];
|
|
43
8
|
/**
|
|
44
9
|
* タスクリポジトリ
|
|
45
10
|
*/
|
|
@@ -48,34 +13,8 @@ class TaskRepo {
|
|
|
48
13
|
constructor(connection) {
|
|
49
14
|
this.taskModel = connection.model(task_2.modelName, (0, task_2.createSchema)());
|
|
50
15
|
}
|
|
51
|
-
async runImmediately(params,
|
|
52
|
-
// support customr function(2025-05-25~)
|
|
53
|
-
next) {
|
|
54
|
-
const { expires } = params;
|
|
55
|
-
if (!(expires instanceof Date)) {
|
|
56
|
-
throw new factory_1.factory.errors.Argument('expires', 'must be Date');
|
|
57
|
-
}
|
|
58
|
-
const savingTask = {
|
|
59
|
-
...params,
|
|
60
|
-
status: factory_1.factory.taskStatus.Ready,
|
|
61
|
-
numberOfTried: 0,
|
|
62
|
-
executionResults: []
|
|
63
|
-
};
|
|
64
|
-
const result = await this.taskModel.insertMany(savingTask, { rawResult: true });
|
|
65
|
-
const id = result.insertedIds?.[0]?.toHexString();
|
|
66
|
-
if (typeof id !== 'string') {
|
|
67
|
-
throw new factory_1.factory.errors.Internal('task not saved');
|
|
68
|
-
}
|
|
69
|
-
task_1.taskEventEmitter.emitTaskStatusChanged({
|
|
70
|
-
id,
|
|
71
|
-
status: factory_1.factory.taskStatus.Ready,
|
|
72
|
-
expires // emit expires(2025-03-31~)
|
|
73
|
-
}, next);
|
|
74
|
-
return { id };
|
|
75
|
-
}
|
|
76
16
|
async saveMany(taskAttributes) {
|
|
77
17
|
const emitImmediately = true; // always true(2026-07-30~)
|
|
78
|
-
// const emitImmediately = options?.emitImmediately === true;
|
|
79
18
|
if (taskAttributes.length > 0) {
|
|
80
19
|
const creatingTasks = taskAttributes.map(({ identifier, ...creatingTask }) => creatingTask); // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
81
20
|
const result = await this.taskModel.insertMany(creatingTasks, { ordered: false, rawResult: true });
|
|
@@ -93,14 +32,7 @@ class TaskRepo {
|
|
|
93
32
|
status: factory_1.factory.taskStatus.Ready
|
|
94
33
|
});
|
|
95
34
|
});
|
|
96
|
-
// taskAttributes.forEach((savedTask) => {
|
|
97
|
-
// taskEventEmitter.emitTaskStatusChanged({
|
|
98
|
-
// name: savedTask.name,
|
|
99
|
-
// status: factory.taskStatus.Ready
|
|
100
|
-
// });
|
|
101
|
-
// });
|
|
102
35
|
}
|
|
103
|
-
// return result.ops;
|
|
104
36
|
return savedTasks;
|
|
105
37
|
}
|
|
106
38
|
else {
|
|
@@ -129,20 +61,33 @@ class TaskRepo {
|
|
|
129
61
|
const { id, status } = doc;
|
|
130
62
|
return { id, status };
|
|
131
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* イベント予約集計タスクの冗長な作成を避けるためのメソッド
|
|
66
|
+
*/
|
|
67
|
+
async findReadyAggregateEventTask(params) {
|
|
68
|
+
return this.taskModel.findOne({
|
|
69
|
+
'project.id': { $eq: params.project.id },
|
|
70
|
+
name: { $eq: factory_1.factory.taskName.AggregateScreeningEvent },
|
|
71
|
+
status: { $eq: factory_1.factory.taskStatus.Ready },
|
|
72
|
+
'data.id': { $exists: true, $eq: params.reservationFor.id }
|
|
73
|
+
}, { _id: 1 })
|
|
74
|
+
.exec();
|
|
75
|
+
}
|
|
132
76
|
/**
|
|
133
77
|
* タスク識別子から冪等作成する
|
|
134
78
|
* reimplement createIfNotExistByIdentifier(2025-03-28~)
|
|
79
|
+
* reimplement runTaskByIdentifier(2026-08-03~)
|
|
135
80
|
*/
|
|
136
|
-
async
|
|
81
|
+
async runTaskByIdentifier(params) {
|
|
137
82
|
const emitImmediately = true; // always true(2026-07-30~)
|
|
138
|
-
if (typeof params.
|
|
139
|
-
throw new factory_1.factory.errors.ArgumentNull('
|
|
83
|
+
if (typeof params.identifier !== 'string' || params.identifier.length === 0) {
|
|
84
|
+
throw new factory_1.factory.errors.ArgumentNull('identifier');
|
|
140
85
|
}
|
|
141
86
|
let createdTask;
|
|
142
87
|
const filterQuery = {
|
|
143
88
|
'project.id': { $eq: params.project.id },
|
|
144
89
|
name: { $eq: params.name },
|
|
145
|
-
|
|
90
|
+
identifier: { $exists: true, $eq: params.identifier }
|
|
146
91
|
};
|
|
147
92
|
const projection = {
|
|
148
93
|
_id: 0,
|
|
@@ -160,7 +105,7 @@ class TaskRepo {
|
|
|
160
105
|
catch (error) {
|
|
161
106
|
let throwsError = true;
|
|
162
107
|
if (await (0, errorHandler_1.isMongoDuplicateError)(error)) {
|
|
163
|
-
// すでに
|
|
108
|
+
// すでにidentifierが存在する場合ok
|
|
164
109
|
throwsError = false;
|
|
165
110
|
createdTask = await this.taskModel.findOne(filterQuery, projection)
|
|
166
111
|
.lean()
|
|
@@ -180,297 +125,8 @@ class TaskRepo {
|
|
|
180
125
|
}
|
|
181
126
|
}
|
|
182
127
|
else {
|
|
183
|
-
throw new factory_1.factory.errors.Internal(`falied in creating a task unexpectedly. ${params.
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
// /**
|
|
187
|
-
// * 取引削除タスク冪等作成
|
|
188
|
-
// */
|
|
189
|
-
// public async createDeleteTransactionTaskIfNotExist(
|
|
190
|
-
// // resolve uniqueness of identifier(2025-03-27~)
|
|
191
|
-
// params: Pick<
|
|
192
|
-
// factory.task.IAttributes<factory.taskName.DeleteTransaction>,
|
|
193
|
-
// 'data' | 'executionResults' | 'name' | 'numberOfTried' | 'project' | 'remainingNumberOfTries' | 'runsAt' | 'status'
|
|
194
|
-
// >,
|
|
195
|
-
// options: IOptionOnCreate
|
|
196
|
-
// ): Promise<void> {
|
|
197
|
-
// if (params.data.object.specifyingMethod !== factory.action.update.deleteAction.ObjectAsTransactionSpecifyingMethod.Id) {
|
|
198
|
-
// throw new factory.errors.NotImplemented(`only ${factory.action.update.deleteAction.ObjectAsTransactionSpecifyingMethod.Id} implemented`);
|
|
199
|
-
// }
|
|
200
|
-
// const createdTask = await this.taskModel.findOneAndUpdate(
|
|
201
|
-
// {
|
|
202
|
-
// 'project.id': { $eq: params.project.id },
|
|
203
|
-
// name: { $eq: params.name },
|
|
204
|
-
// 'data.object.id': { $exists: true, $eq: params.data.object.id }
|
|
205
|
-
// },
|
|
206
|
-
// { $setOnInsert: params },
|
|
207
|
-
// { new: true, upsert: true }
|
|
208
|
-
// )
|
|
209
|
-
// .select({ _id: 1 })
|
|
210
|
-
// .exec();
|
|
211
|
-
// if (options.emitImmediately) {
|
|
212
|
-
// taskEventEmitter.emitTaskStatusChanged({
|
|
213
|
-
// id: createdTask.id,
|
|
214
|
-
// name: params.name,
|
|
215
|
-
// status: factory.taskStatus.Ready
|
|
216
|
-
// });
|
|
217
|
-
// }
|
|
218
|
-
// }
|
|
219
|
-
async createOnAssetTransactionStatusChangedTaskIfNotExist(params) {
|
|
220
|
-
const emitImmediately = true; // always true(2026-07-30~)
|
|
221
|
-
const createdTask = await this.taskModel.findOneAndUpdate({
|
|
222
|
-
'project.id': { $eq: params.project.id },
|
|
223
|
-
name: { $eq: params.name },
|
|
224
|
-
'data.object.transactionNumber': {
|
|
225
|
-
$exists: true,
|
|
226
|
-
$eq: String(params.data.object.transactionNumber)
|
|
227
|
-
},
|
|
228
|
-
'data.purpose.orderNumber': {
|
|
229
|
-
$exists: true,
|
|
230
|
-
$eq: String(params.data.purpose.orderNumber)
|
|
231
|
-
}
|
|
232
|
-
}, { $setOnInsert: params }, { new: true, upsert: true })
|
|
233
|
-
.select({ _id: 1 })
|
|
234
|
-
.exec();
|
|
235
|
-
if (emitImmediately) {
|
|
236
|
-
task_1.taskEventEmitter.emitTaskStatusChanged({
|
|
237
|
-
id: createdTask.id,
|
|
238
|
-
name: params.name,
|
|
239
|
-
status: factory_1.factory.taskStatus.Ready
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
/**
|
|
244
|
-
* Ready -> remainingNumberOfTriesが1減る
|
|
245
|
-
* Running -> findOneするだけ
|
|
246
|
-
*/
|
|
247
|
-
async executeOneById(params) {
|
|
248
|
-
const now = new Date();
|
|
249
|
-
let doc;
|
|
250
|
-
if (params.status === factory_1.factory.taskStatus.Running) {
|
|
251
|
-
doc = await this.taskModel.findOne({
|
|
252
|
-
_id: { $eq: params.id },
|
|
253
|
-
status: { $eq: params.status },
|
|
254
|
-
runsAt: { $lt: now },
|
|
255
|
-
...(params.expires instanceof Date) ? { expires: { $gt: now } } : undefined
|
|
256
|
-
}, executableTaskProjection)
|
|
257
|
-
.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
258
|
-
.lean()
|
|
259
|
-
.exec();
|
|
260
|
-
}
|
|
261
|
-
else {
|
|
262
|
-
doc = await this.taskModel.findOneAndUpdate({
|
|
263
|
-
_id: { $eq: params.id },
|
|
264
|
-
status: { $eq: params.status },
|
|
265
|
-
runsAt: { $lt: now },
|
|
266
|
-
...(params.expires instanceof Date) ? { expires: { $gt: now } } : undefined
|
|
267
|
-
}, {
|
|
268
|
-
$set: {
|
|
269
|
-
status: factory_1.factory.taskStatus.Running, // 実行中に変更
|
|
270
|
-
lastTriedAt: now,
|
|
271
|
-
executor: params.executor
|
|
272
|
-
},
|
|
273
|
-
$inc: {
|
|
274
|
-
remainingNumberOfTries: -1, // 残りトライ可能回数減らす
|
|
275
|
-
numberOfTried: 1 // トライ回数増やす
|
|
276
|
-
}
|
|
277
|
-
}, { new: true, projection: executableTaskProjection })
|
|
278
|
-
.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
279
|
-
.lean() // lean(2024-09-26~)
|
|
280
|
-
.exec();
|
|
281
|
-
}
|
|
282
|
-
if (doc === null) {
|
|
283
|
-
return null;
|
|
284
|
-
}
|
|
285
|
-
return doc;
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* Readyのタスクをname指定でひとつRunningに変更する
|
|
289
|
-
*/
|
|
290
|
-
async executeOneIfExists(params) {
|
|
291
|
-
if (!(params.runsAt.$lt instanceof Date)) {
|
|
292
|
-
throw new factory_1.factory.errors.Argument('runsAt.$lt', 'must be Date');
|
|
293
|
-
}
|
|
294
|
-
const nameEq = params.name?.$eq;
|
|
295
|
-
// const nameNin = params.name?.$nin;
|
|
296
|
-
const doc = await this.taskModel.findOneAndUpdate({
|
|
297
|
-
status: { $eq: factory_1.factory.taskStatus.Ready },
|
|
298
|
-
runsAt: { $lt: params.runsAt.$lt },
|
|
299
|
-
...(typeof nameEq === 'string')
|
|
300
|
-
? {
|
|
301
|
-
name: {
|
|
302
|
-
...(typeof nameEq === 'string') ? { $eq: nameEq } : undefined
|
|
303
|
-
// ...(Array.isArray(nameNin)) ? { $nin: nameNin } : undefined
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
: undefined
|
|
307
|
-
}, {
|
|
308
|
-
$set: {
|
|
309
|
-
status: factory_1.factory.taskStatus.Running, // 実行中に変更
|
|
310
|
-
lastTriedAt: new Date(),
|
|
311
|
-
executor: params.executor
|
|
312
|
-
},
|
|
313
|
-
$inc: {
|
|
314
|
-
remainingNumberOfTries: -1, // 残りトライ可能回数減らす
|
|
315
|
-
numberOfTried: 1 // トライ回数増やす
|
|
316
|
-
}
|
|
317
|
-
}, {
|
|
318
|
-
new: true,
|
|
319
|
-
projection: executableTaskProjection,
|
|
320
|
-
...(typeof params.sort.numberOfTried === 'number' || typeof params.sort.runsAt === 'number')
|
|
321
|
-
? { sort: params.sort }
|
|
322
|
-
: undefined
|
|
323
|
-
})
|
|
324
|
-
.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
325
|
-
.lean() // lean(2024-09-26~)
|
|
326
|
-
.exec();
|
|
327
|
-
if (doc === null) {
|
|
328
|
-
return null;
|
|
329
|
-
}
|
|
330
|
-
return doc;
|
|
331
|
-
}
|
|
332
|
-
/**
|
|
333
|
-
* add(2025-03-16~)
|
|
334
|
-
*/
|
|
335
|
-
async countPotentiallyRunning(params) {
|
|
336
|
-
const { runsAt, limit, name } = params;
|
|
337
|
-
const nameEq = name?.$eq;
|
|
338
|
-
// const nameNin = name?.$nin;
|
|
339
|
-
const nameIn = name?.$in;
|
|
340
|
-
if (!(runsAt.$lt instanceof Date)) {
|
|
341
|
-
throw new factory_1.factory.errors.Argument('runsAt.$lt', 'must be Date');
|
|
342
|
-
}
|
|
343
|
-
const query = this.taskModel.countDocuments({
|
|
344
|
-
status: { $eq: factory_1.factory.taskStatus.Ready },
|
|
345
|
-
runsAt: { $lt: params.runsAt.$lt },
|
|
346
|
-
...(typeof nameEq === 'string' || Array.isArray(nameIn))
|
|
347
|
-
? {
|
|
348
|
-
name: {
|
|
349
|
-
...(typeof nameEq === 'string') ? { $eq: nameEq } : undefined,
|
|
350
|
-
// ...(Array.isArray(nameNin)) ? { $nin: nameNin } : undefined,
|
|
351
|
-
...(Array.isArray(nameIn)) ? { $in: nameIn } : undefined
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
: undefined
|
|
355
|
-
});
|
|
356
|
-
if (typeof limit === 'number' && limit >= 0) {
|
|
357
|
-
query.limit(limit);
|
|
358
|
-
}
|
|
359
|
-
const count = await query.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
360
|
-
.exec();
|
|
361
|
-
return { count };
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* 実行日時を一定期間過ぎたReadyタスクについて、Runningスタータスに変更した上で、Runningイベントを発生させる
|
|
365
|
-
*/
|
|
366
|
-
async emitRunningIfExists(params) {
|
|
367
|
-
if (!(params.runsAt.$lt instanceof Date)) {
|
|
368
|
-
throw new factory_1.factory.errors.Argument('runsAt.$lt', 'must be Date');
|
|
369
|
-
}
|
|
370
|
-
const projection = {
|
|
371
|
-
_id: 0,
|
|
372
|
-
id: { $toString: '$_id' },
|
|
373
|
-
name: 1
|
|
374
|
-
};
|
|
375
|
-
const nameEq = params.name?.$eq;
|
|
376
|
-
// const nameNin = params.name?.$nin;
|
|
377
|
-
// const nameIn = params.name?.$in;
|
|
378
|
-
const { nameFilterBeforeRunsAt } = params;
|
|
379
|
-
const filter = {
|
|
380
|
-
status: { $eq: factory_1.factory.taskStatus.Ready },
|
|
381
|
-
...(nameFilterBeforeRunsAt) ? { name: params.name } : undefined,
|
|
382
|
-
runsAt: { $lt: params.runsAt.$lt },
|
|
383
|
-
...(!nameFilterBeforeRunsAt) ? { name: params.name } : undefined
|
|
384
|
-
};
|
|
385
|
-
const doc = await this.taskModel.findOneAndUpdate(filter, {
|
|
386
|
-
$set: {
|
|
387
|
-
status: factory_1.factory.taskStatus.Running, // 実行中に変更
|
|
388
|
-
lastTriedAt: new Date(),
|
|
389
|
-
executor: params.executor
|
|
390
|
-
},
|
|
391
|
-
$inc: {
|
|
392
|
-
remainingNumberOfTries: -1, // 残りトライ可能回数減らす
|
|
393
|
-
numberOfTried: 1 // トライ回数増やす
|
|
394
|
-
}
|
|
395
|
-
}, {
|
|
396
|
-
new: true,
|
|
397
|
-
projection,
|
|
398
|
-
...(typeof params.sort.numberOfTried === 'number' || typeof params.sort.runsAt === 'number')
|
|
399
|
-
? { sort: params.sort }
|
|
400
|
-
: undefined
|
|
401
|
-
})
|
|
402
|
-
.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
403
|
-
.lean()
|
|
404
|
-
.exec();
|
|
405
|
-
if (doc === null) {
|
|
406
|
-
return null;
|
|
407
|
-
}
|
|
408
|
-
let changedTask;
|
|
409
|
-
if (typeof nameEq === 'string') {
|
|
410
|
-
changedTask = {
|
|
411
|
-
id: doc.id,
|
|
412
|
-
status: factory_1.factory.taskStatus.Running,
|
|
413
|
-
name: nameEq
|
|
414
|
-
};
|
|
415
|
-
}
|
|
416
|
-
else {
|
|
417
|
-
changedTask = {
|
|
418
|
-
id: doc.id,
|
|
419
|
-
status: factory_1.factory.taskStatus.Running
|
|
420
|
-
};
|
|
421
|
-
}
|
|
422
|
-
task_1.taskEventEmitter.emitTaskStatusChanged(changedTask);
|
|
423
|
-
return doc;
|
|
424
|
-
}
|
|
425
|
-
/**
|
|
426
|
-
* Readyのままで期限切れのタスクをExpiredに変更する
|
|
427
|
-
*/
|
|
428
|
-
async makeExpiredMany(params) {
|
|
429
|
-
const { expiresLt } = params;
|
|
430
|
-
if (!(expiresLt instanceof Date)) {
|
|
431
|
-
throw new factory_1.factory.errors.Argument('expiresLt', 'must be Date');
|
|
128
|
+
throw new factory_1.factory.errors.Internal(`falied in creating a task unexpectedly. ${params.identifier}`);
|
|
432
129
|
}
|
|
433
|
-
return this.taskModel.updateMany({
|
|
434
|
-
status: { $eq: factory_1.factory.taskStatus.Ready },
|
|
435
|
-
expires: { $exists: true, $lt: expiresLt }
|
|
436
|
-
}, {
|
|
437
|
-
$set: {
|
|
438
|
-
status: factory_1.factory.taskStatus.Expired
|
|
439
|
-
}
|
|
440
|
-
})
|
|
441
|
-
.exec();
|
|
442
|
-
}
|
|
443
|
-
/**
|
|
444
|
-
* Runningのまま一定期間超過し、かつ、remainingNumberOfTries>0のタスクをReadyに変更する
|
|
445
|
-
*/
|
|
446
|
-
async retryMany(params) {
|
|
447
|
-
const lastTriedAtShoudBeLessThan = (0, moment_1.default)()
|
|
448
|
-
.add(-params.intervalInMinutes, 'minutes')
|
|
449
|
-
.toDate();
|
|
450
|
-
const remainingNumberOfTriesGte = params.remainingNumberOfTries.$gte;
|
|
451
|
-
const remainingNumberOfTriesLte = params.remainingNumberOfTries.$lte;
|
|
452
|
-
return this.taskModel.updateMany(
|
|
453
|
-
// name: 'retry'のindexと連動しているので、条件の順序などには注意すること
|
|
454
|
-
// @see schemas/task
|
|
455
|
-
{
|
|
456
|
-
status: { $eq: factory_1.factory.taskStatus.Running },
|
|
457
|
-
lastTriedAt: {
|
|
458
|
-
$type: 'date',
|
|
459
|
-
$lt: lastTriedAtShoudBeLessThan
|
|
460
|
-
},
|
|
461
|
-
...(typeof remainingNumberOfTriesGte === 'number')
|
|
462
|
-
? { remainingNumberOfTries: { $gte: remainingNumberOfTriesGte } }
|
|
463
|
-
: undefined,
|
|
464
|
-
...(typeof remainingNumberOfTriesLte === 'number')
|
|
465
|
-
? { remainingNumberOfTries: { $lte: remainingNumberOfTriesLte } }
|
|
466
|
-
: undefined,
|
|
467
|
-
...(Array.isArray(params.name.$in)) ? { name: { $in: params.name.$in } } : undefined
|
|
468
|
-
}, {
|
|
469
|
-
$set: {
|
|
470
|
-
status: factory_1.factory.taskStatus.Ready // 実行前に変更
|
|
471
|
-
}
|
|
472
|
-
})
|
|
473
|
-
.exec();
|
|
474
130
|
}
|
|
475
131
|
/**
|
|
476
132
|
* 実行中止済タスクを強制的にリトライ
|
|
@@ -490,117 +146,5 @@ class TaskRepo {
|
|
|
490
146
|
})
|
|
491
147
|
.exec();
|
|
492
148
|
}
|
|
493
|
-
async abortMany(params) {
|
|
494
|
-
const lastTriedAtShoudBeLessThan = (0, moment_1.default)()
|
|
495
|
-
.add(-params.intervalInMinutes, 'minutes')
|
|
496
|
-
.toDate();
|
|
497
|
-
return this.taskModel.updateMany({
|
|
498
|
-
status: { $eq: factory_1.factory.taskStatus.Running },
|
|
499
|
-
lastTriedAt: {
|
|
500
|
-
$type: 'date',
|
|
501
|
-
$lt: lastTriedAtShoudBeLessThan
|
|
502
|
-
},
|
|
503
|
-
remainingNumberOfTries: { $eq: 0 },
|
|
504
|
-
...(Array.isArray(params.name.$in)) ? { name: { $in: params.name.$in } } : undefined
|
|
505
|
-
}, {
|
|
506
|
-
$set: {
|
|
507
|
-
status: factory_1.factory.taskStatus.Aborted,
|
|
508
|
-
dateAborted: new Date()
|
|
509
|
-
}
|
|
510
|
-
})
|
|
511
|
-
.exec();
|
|
512
|
-
}
|
|
513
|
-
/**
|
|
514
|
-
* タスクIDから実行結果とステータスを保管する
|
|
515
|
-
* Abortedの場合、dateAbortedもセットする
|
|
516
|
-
*/
|
|
517
|
-
async setExecutionResultAndStatus(params, update,
|
|
518
|
-
// support customr function(2025-05-25~)
|
|
519
|
-
next) {
|
|
520
|
-
const { id, remainingNumberOfTries, name } = params;
|
|
521
|
-
const { status, executionResult } = update;
|
|
522
|
-
await this.taskModel.updateOne({ _id: { $eq: id } }, {
|
|
523
|
-
$set: {
|
|
524
|
-
status,
|
|
525
|
-
...(status === factory_1.factory.taskStatus.Aborted) ? { dateAborted: executionResult.endDate } : undefined // 2025-08-04~
|
|
526
|
-
},
|
|
527
|
-
$push: { executionResults: executionResult }
|
|
528
|
-
})
|
|
529
|
-
.exec();
|
|
530
|
-
// emit event(2025-05-26~)
|
|
531
|
-
if (typeof next === 'function') {
|
|
532
|
-
const changedTask = { id, name, status, remainingNumberOfTries, executionResult };
|
|
533
|
-
task_1.taskEventEmitter.emitTaskStatusChanged(changedTask, next);
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
/**
|
|
537
|
-
* タスクの状態を参照する
|
|
538
|
-
* 非同期アクション移行が完了したら廃止する(2026-07-29~)
|
|
539
|
-
*/
|
|
540
|
-
async findTaskById(params, inclusion) {
|
|
541
|
-
let positiveProjectionFields = AVAILABLE_PROJECT_FIELDS;
|
|
542
|
-
if (Array.isArray(inclusion) && inclusion.length > 0) {
|
|
543
|
-
positiveProjectionFields = inclusion.filter((key) => AVAILABLE_PROJECT_FIELDS.includes(key));
|
|
544
|
-
}
|
|
545
|
-
else {
|
|
546
|
-
// no op
|
|
547
|
-
}
|
|
548
|
-
const projection = {
|
|
549
|
-
_id: 0,
|
|
550
|
-
id: { $toString: '$_id' },
|
|
551
|
-
...Object.fromEntries(positiveProjectionFields.map((key) => ([key, 1])))
|
|
552
|
-
};
|
|
553
|
-
const query = this.taskModel.findOne({
|
|
554
|
-
_id: { $eq: params.id.$eq },
|
|
555
|
-
'project.id': { $eq: params.project.id.$eq },
|
|
556
|
-
name: { $eq: params.name }
|
|
557
|
-
}, projection);
|
|
558
|
-
const doc = await query.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
559
|
-
.lean()
|
|
560
|
-
.exec();
|
|
561
|
-
if (doc === null) {
|
|
562
|
-
return;
|
|
563
|
-
}
|
|
564
|
-
return doc;
|
|
565
|
-
}
|
|
566
|
-
async deleteByProject(params) {
|
|
567
|
-
await this.taskModel.deleteMany({
|
|
568
|
-
'project.id': { $eq: params.project.id }
|
|
569
|
-
})
|
|
570
|
-
.exec();
|
|
571
|
-
}
|
|
572
|
-
/**
|
|
573
|
-
* 不要なタスクを削除する
|
|
574
|
-
*/
|
|
575
|
-
async deleteRunsAtPassedCertainPeriod(params) {
|
|
576
|
-
return this.taskModel.deleteMany({
|
|
577
|
-
runsAt: { $lt: params.runsAt.$lt },
|
|
578
|
-
status: {
|
|
579
|
-
$in: [
|
|
580
|
-
factory_1.factory.taskStatus.Aborted,
|
|
581
|
-
factory_1.factory.taskStatus.Executed,
|
|
582
|
-
factory_1.factory.taskStatus.Expired
|
|
583
|
-
]
|
|
584
|
-
}
|
|
585
|
-
})
|
|
586
|
-
.exec();
|
|
587
|
-
}
|
|
588
|
-
async countDelayedTasks(params) {
|
|
589
|
-
const { limit } = params;
|
|
590
|
-
const runsAtLt = (0, moment_1.default)()
|
|
591
|
-
.add(-params.delayInSeconds, 'seconds')
|
|
592
|
-
.toDate();
|
|
593
|
-
const query = this.taskModel.countDocuments({
|
|
594
|
-
status: { $eq: factory_1.factory.taskStatus.Ready },
|
|
595
|
-
runsAt: { $lt: runsAtLt },
|
|
596
|
-
...(Array.isArray(params.name.$nin)) ? { name: { $nin: params.name.$nin } } : undefined
|
|
597
|
-
});
|
|
598
|
-
if (typeof limit === 'number' && limit >= 0) {
|
|
599
|
-
query.limit(limit);
|
|
600
|
-
}
|
|
601
|
-
const count = await query.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
602
|
-
.exec();
|
|
603
|
-
return { count };
|
|
604
|
-
}
|
|
605
149
|
}
|
|
606
150
|
exports.TaskRepo = TaskRepo;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { Connection, UpdateWriteOpResult } from 'mongoose';
|
|
2
|
+
import { factory } from '../factory';
|
|
3
|
+
/**
|
|
4
|
+
* 遅延タスクリポジトリ
|
|
5
|
+
*/
|
|
6
|
+
export declare class TaskDelayedRepo {
|
|
7
|
+
private readonly taskModel;
|
|
8
|
+
constructor(connection: Connection);
|
|
9
|
+
/**
|
|
10
|
+
* 潜在的に実行されるべきタスクをカウントする
|
|
11
|
+
* add(2025-03-16~)
|
|
12
|
+
*/
|
|
13
|
+
countPotentiallyRunning(params: {
|
|
14
|
+
name?: {
|
|
15
|
+
$eq?: factory.taskName;
|
|
16
|
+
$in?: factory.taskName[];
|
|
17
|
+
};
|
|
18
|
+
runsAt: {
|
|
19
|
+
$lt: Date;
|
|
20
|
+
};
|
|
21
|
+
limit: number;
|
|
22
|
+
}): Promise<{
|
|
23
|
+
count: number;
|
|
24
|
+
}>;
|
|
25
|
+
/**
|
|
26
|
+
* 実行日時を一定期間過ぎたReadyタスクについて、Runningステータスに変更する
|
|
27
|
+
*/
|
|
28
|
+
private runDelayedTask;
|
|
29
|
+
/**
|
|
30
|
+
* 実行日時を一定期間過ぎたReadyタスクについて、Runningステータスに変更した上で、Runningイベントを発生させる
|
|
31
|
+
*/
|
|
32
|
+
runDelayedTaskIfExistsByName(params: {
|
|
33
|
+
/**
|
|
34
|
+
* 必ずタスク名指定で実行する
|
|
35
|
+
*/
|
|
36
|
+
name: {
|
|
37
|
+
$eq: factory.taskName;
|
|
38
|
+
$in?: never;
|
|
39
|
+
} | {
|
|
40
|
+
$eq?: never;
|
|
41
|
+
$in: factory.taskName[];
|
|
42
|
+
};
|
|
43
|
+
runsAt: {
|
|
44
|
+
$lt: Date;
|
|
45
|
+
};
|
|
46
|
+
executor: {
|
|
47
|
+
name: string;
|
|
48
|
+
};
|
|
49
|
+
}): Promise<Pick<factory.task.ITask<factory.taskName>, 'id' | 'name'> | null>;
|
|
50
|
+
/**
|
|
51
|
+
* 実行日時を一定期間過ぎたReadyタスクについて、Runningステータスに変更した上で、Runningイベントを発生させる
|
|
52
|
+
* 2026-08-06~
|
|
53
|
+
*/
|
|
54
|
+
runDelayedTaskIfExists(params: {
|
|
55
|
+
runsAt: {
|
|
56
|
+
$lt: Date;
|
|
57
|
+
};
|
|
58
|
+
executor: {
|
|
59
|
+
name: string;
|
|
60
|
+
};
|
|
61
|
+
}): Promise<Pick<factory.task.ITask<factory.taskName>, 'id' | 'name'> | null>;
|
|
62
|
+
/**
|
|
63
|
+
* Runningのまま一定期間超過し、かつ、remainingNumberOfTries>0のタスクをReadyに変更する
|
|
64
|
+
*/
|
|
65
|
+
retryTasks(params: {
|
|
66
|
+
intervalInMinutes: number;
|
|
67
|
+
}): Promise<UpdateWriteOpResult>;
|
|
68
|
+
/**
|
|
69
|
+
* $lte:0をReadyにする -> Readyにすれば自動的にAbortedになる
|
|
70
|
+
*/
|
|
71
|
+
retryAbortingTasks(params: {
|
|
72
|
+
intervalInMinutes: number;
|
|
73
|
+
}): Promise<UpdateWriteOpResult>;
|
|
74
|
+
}
|