@chevre/domain 26.0.0-alpha.13 → 26.0.0-alpha.15
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 +5 -4
- package/lib/chevre/eventEmitter/task.js +2 -2
- package/lib/chevre/repo/adminTask.d.ts +12 -0
- package/lib/chevre/repo/adminTask.js +24 -0
- package/lib/chevre/repo/assetTransaction.d.ts +1 -1
- package/lib/chevre/repo/mongoose/schemas/task.js +4 -0
- package/lib/chevre/repo/scheduledTask.js +0 -21
- package/lib/chevre/repo/task.d.ts +1 -77
- package/lib/chevre/repo/task.js +3 -384
- package/lib/chevre/repo/taskDelayed.d.ts +67 -0
- package/lib/chevre/repo/taskDelayed.js +148 -0
- package/lib/chevre/repo/transaction.d.ts +9 -9
- package/lib/chevre/repository.d.ts +5 -10
- package/lib/chevre/repository.js +11 -22
- package/lib/chevre/service/asyncAction.d.ts +2 -2
- package/lib/chevre/service/asyncAction.js +2 -2
- package/lib/chevre/service/asyncActionHandler.d.ts +4 -4
- package/lib/chevre/service/asyncActionHandler.js +11 -13
- package/lib/chevre/service/order/confirmPayTransaction.js +4 -1
- package/lib/chevre/service/order/onOrderStatusChanged/onOrderInTransit.js +2 -2
- package/lib/chevre/service/order/onOrderStatusChanged/onOrderPaymentDue.js +1 -1
- package/lib/chevre/service/order/onOrderStatusChanged/onOrderProcessing/createSendEmailMessageTaskIfNotExist.js +1 -1
- package/lib/chevre/service/order/onOrderStatusChanged/onOrderProcessing/factory.d.ts +1 -1
- package/lib/chevre/service/order/onOrderStatusChanged/onOrderProcessing/factory.js +1 -1
- package/lib/chevre/service/order/onOrderStatusChanged/onOrderProcessing/processOrder.js +1 -1
- 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 +1 -1
- package/lib/chevre/service/scheduledTask.js +1 -1
- 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/publishPaymentUrl.js +1 -10
- 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 -3
- package/lib/chevre/service/task.js +3 -3
- package/lib/chevre/service/taskHandler/onOperationFailed.d.ts +1 -2
- package/lib/chevre/service/taskHandler/onOperationFailed.js +8 -7
- package/lib/chevre/service/taskHandler.d.ts +1 -2
- package/lib/chevre/service/taskHandler.js +6 -5
- package/lib/chevre/taskSettings.d.ts +4 -2
- package/package.json +1 -1
- package/lib/chevre/repo/asyncActionLegacy.d.ts +0 -23
- package/lib/chevre/repo/asyncActionLegacy.js +0 -59
- package/lib/chevre/repo/scheduledTaskLegacy.d.ts +0 -39
- package/lib/chevre/repo/scheduledTaskLegacy.js +0 -96
package/lib/chevre/repo/task.js
CHANGED
|
@@ -33,7 +33,6 @@ class TaskRepo {
|
|
|
33
33
|
}
|
|
34
34
|
async saveMany(taskAttributes) {
|
|
35
35
|
const emitImmediately = true; // always true(2026-07-30~)
|
|
36
|
-
// const emitImmediately = options?.emitImmediately === true;
|
|
37
36
|
if (taskAttributes.length > 0) {
|
|
38
37
|
const creatingTasks = taskAttributes.map(({ identifier, ...creatingTask }) => creatingTask); // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
39
38
|
const result = await this.taskModel.insertMany(creatingTasks, { ordered: false, rawResult: true });
|
|
@@ -51,14 +50,7 @@ class TaskRepo {
|
|
|
51
50
|
status: factory_1.factory.taskStatus.Ready
|
|
52
51
|
});
|
|
53
52
|
});
|
|
54
|
-
// taskAttributes.forEach((savedTask) => {
|
|
55
|
-
// taskEventEmitter.emitTaskStatusChanged({
|
|
56
|
-
// name: savedTask.name,
|
|
57
|
-
// status: factory.taskStatus.Ready
|
|
58
|
-
// });
|
|
59
|
-
// });
|
|
60
53
|
}
|
|
61
|
-
// return result.ops;
|
|
62
54
|
return savedTasks;
|
|
63
55
|
}
|
|
64
56
|
else {
|
|
@@ -109,12 +101,6 @@ class TaskRepo {
|
|
|
109
101
|
if (typeof params.identifier !== 'string' || params.identifier.length === 0) {
|
|
110
102
|
throw new factory_1.factory.errors.ArgumentNull('identifier');
|
|
111
103
|
}
|
|
112
|
-
if (typeof params.alternateName !== 'string' || params.alternateName.length === 0) {
|
|
113
|
-
throw new factory_1.factory.errors.ArgumentNull('alternateName');
|
|
114
|
-
}
|
|
115
|
-
if (params.identifier !== params.alternateName) {
|
|
116
|
-
throw new factory_1.factory.errors.Argument('identifier,alternateName not matched');
|
|
117
|
-
}
|
|
118
104
|
let createdTask;
|
|
119
105
|
const filterQuery = {
|
|
120
106
|
'project.id': { $eq: params.project.id },
|
|
@@ -160,63 +146,6 @@ class TaskRepo {
|
|
|
160
146
|
throw new factory_1.factory.errors.Internal(`falied in creating a task unexpectedly. ${params.identifier}`);
|
|
161
147
|
}
|
|
162
148
|
}
|
|
163
|
-
// /**
|
|
164
|
-
// * 取引削除タスク冪等作成
|
|
165
|
-
// */
|
|
166
|
-
// public async createDeleteTransactionTaskIfNotExist(
|
|
167
|
-
// // resolve uniqueness of identifier(2025-03-27~)
|
|
168
|
-
// params: Pick<
|
|
169
|
-
// factory.task.IAttributes<factory.taskName.DeleteTransaction>,
|
|
170
|
-
// 'data' | 'executionResults' | 'name' | 'numberOfTried' | 'project' | 'remainingNumberOfTries' | 'runsAt' | 'status'
|
|
171
|
-
// >,
|
|
172
|
-
// options: IOptionOnCreate
|
|
173
|
-
// ): Promise<void> {
|
|
174
|
-
// if (params.data.object.specifyingMethod !== factory.action.update.deleteAction.ObjectAsTransactionSpecifyingMethod.Id) {
|
|
175
|
-
// throw new factory.errors.NotImplemented(`only ${factory.action.update.deleteAction.ObjectAsTransactionSpecifyingMethod.Id} implemented`);
|
|
176
|
-
// }
|
|
177
|
-
// const createdTask = await this.taskModel.findOneAndUpdate(
|
|
178
|
-
// {
|
|
179
|
-
// 'project.id': { $eq: params.project.id },
|
|
180
|
-
// name: { $eq: params.name },
|
|
181
|
-
// 'data.object.id': { $exists: true, $eq: params.data.object.id }
|
|
182
|
-
// },
|
|
183
|
-
// { $setOnInsert: params },
|
|
184
|
-
// { new: true, upsert: true }
|
|
185
|
-
// )
|
|
186
|
-
// .select({ _id: 1 })
|
|
187
|
-
// .exec();
|
|
188
|
-
// if (options.emitImmediately) {
|
|
189
|
-
// taskEventEmitter.emitTaskStatusChanged({
|
|
190
|
-
// id: createdTask.id,
|
|
191
|
-
// name: params.name,
|
|
192
|
-
// status: factory.taskStatus.Ready
|
|
193
|
-
// });
|
|
194
|
-
// }
|
|
195
|
-
// }
|
|
196
|
-
async createOnAssetTransactionStatusChangedTaskIfNotExist(params) {
|
|
197
|
-
const emitImmediately = true; // always true(2026-07-30~)
|
|
198
|
-
const createdTask = await this.taskModel.findOneAndUpdate({
|
|
199
|
-
'project.id': { $eq: params.project.id },
|
|
200
|
-
name: { $eq: params.name },
|
|
201
|
-
'data.object.transactionNumber': {
|
|
202
|
-
$exists: true,
|
|
203
|
-
$eq: String(params.data.object.transactionNumber)
|
|
204
|
-
},
|
|
205
|
-
'data.purpose.orderNumber': {
|
|
206
|
-
$exists: true,
|
|
207
|
-
$eq: String(params.data.purpose.orderNumber)
|
|
208
|
-
}
|
|
209
|
-
}, { $setOnInsert: params }, { new: true, upsert: true })
|
|
210
|
-
.select({ _id: 1 })
|
|
211
|
-
.exec();
|
|
212
|
-
if (emitImmediately) {
|
|
213
|
-
task_1.taskEventEmitter.emitTaskStatusChanged({
|
|
214
|
-
id: createdTask.id,
|
|
215
|
-
name: params.name,
|
|
216
|
-
status: factory_1.factory.taskStatus.Ready
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
149
|
/**
|
|
221
150
|
* Ready -> remainingNumberOfTriesが1減る
|
|
222
151
|
* Running -> findOneするだけ
|
|
@@ -261,229 +190,6 @@ class TaskRepo {
|
|
|
261
190
|
}
|
|
262
191
|
return doc;
|
|
263
192
|
}
|
|
264
|
-
// 不要なので廃止(2026-08-04~)
|
|
265
|
-
// /**
|
|
266
|
-
// * Readyのタスクをname指定でひとつRunningに変更する
|
|
267
|
-
// */
|
|
268
|
-
// public async executeOneIfExists(params: {
|
|
269
|
-
// name: {
|
|
270
|
-
// $eq: factory.taskName;
|
|
271
|
-
// // $nin?: factory.taskName[]; // discontinue(2025-08-07~)
|
|
272
|
-
// };
|
|
273
|
-
// executor: { name: string };
|
|
274
|
-
// runsAt: {
|
|
275
|
-
// $lt: Date;
|
|
276
|
-
// };
|
|
277
|
-
// sort: {
|
|
278
|
-
// numberOfTried?: factory.sortType; // トライ回数の少なさ優先
|
|
279
|
-
// runsAt?: factory.sortType; // 実行予定日時の早さ優先
|
|
280
|
-
// };
|
|
281
|
-
// }): Promise<IExecutableTask<factory.taskName> | null> {
|
|
282
|
-
// if (!(params.runsAt.$lt instanceof Date)) {
|
|
283
|
-
// throw new factory.errors.Argument('runsAt.$lt', 'must be Date');
|
|
284
|
-
// }
|
|
285
|
-
// const nameEq = params.name?.$eq;
|
|
286
|
-
// // const nameNin = params.name?.$nin;
|
|
287
|
-
// const doc = await this.taskModel.findOneAndUpdate(
|
|
288
|
-
// {
|
|
289
|
-
// status: { $eq: factory.taskStatus.Ready },
|
|
290
|
-
// runsAt: { $lt: params.runsAt.$lt },
|
|
291
|
-
// ...(typeof nameEq === 'string')
|
|
292
|
-
// ? {
|
|
293
|
-
// name: {
|
|
294
|
-
// ...(typeof nameEq === 'string') ? { $eq: nameEq } : undefined
|
|
295
|
-
// // ...(Array.isArray(nameNin)) ? { $nin: nameNin } : undefined
|
|
296
|
-
// }
|
|
297
|
-
// }
|
|
298
|
-
// : undefined
|
|
299
|
-
// },
|
|
300
|
-
// {
|
|
301
|
-
// $set: {
|
|
302
|
-
// status: factory.taskStatus.Running, // 実行中に変更
|
|
303
|
-
// lastTriedAt: new Date(),
|
|
304
|
-
// executor: params.executor
|
|
305
|
-
// },
|
|
306
|
-
// $inc: {
|
|
307
|
-
// remainingNumberOfTries: -1, // 残りトライ可能回数減らす
|
|
308
|
-
// numberOfTried: 1 // トライ回数増やす
|
|
309
|
-
// }
|
|
310
|
-
// },
|
|
311
|
-
// {
|
|
312
|
-
// new: true,
|
|
313
|
-
// projection: executableTaskProjection,
|
|
314
|
-
// ...(typeof params.sort.numberOfTried === 'number' || typeof params.sort.runsAt === 'number')
|
|
315
|
-
// ? { sort: params.sort }
|
|
316
|
-
// : undefined
|
|
317
|
-
// }
|
|
318
|
-
// )
|
|
319
|
-
// .setOptions({ maxTimeMS: MONGO_MAX_TIME_MS })
|
|
320
|
-
// .lean<IExecutableTask<factory.taskName>>() // lean(2024-09-26~)
|
|
321
|
-
// .exec();
|
|
322
|
-
// if (doc === null) {
|
|
323
|
-
// return null;
|
|
324
|
-
// }
|
|
325
|
-
// return doc;
|
|
326
|
-
// }
|
|
327
|
-
/**
|
|
328
|
-
* 潜在的に実行されるべきタスクをカウントする
|
|
329
|
-
* add(2025-03-16~)
|
|
330
|
-
*/
|
|
331
|
-
async countPotentiallyRunning(params) {
|
|
332
|
-
const { runsAt, limit, name } = params;
|
|
333
|
-
const nameEq = name?.$eq;
|
|
334
|
-
const nameIn = name?.$in;
|
|
335
|
-
if (!(runsAt.$lt instanceof Date)) {
|
|
336
|
-
throw new factory_1.factory.errors.Argument('runsAt.$lt', 'must be Date');
|
|
337
|
-
}
|
|
338
|
-
const query = this.taskModel.countDocuments({
|
|
339
|
-
status: { $eq: factory_1.factory.taskStatus.Ready },
|
|
340
|
-
runsAt: { $lt: params.runsAt.$lt },
|
|
341
|
-
...(typeof nameEq === 'string' || Array.isArray(nameIn))
|
|
342
|
-
? {
|
|
343
|
-
name: {
|
|
344
|
-
...(typeof nameEq === 'string') ? { $eq: nameEq } : undefined,
|
|
345
|
-
...(Array.isArray(nameIn)) ? { $in: nameIn } : undefined
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
: undefined
|
|
349
|
-
});
|
|
350
|
-
if (typeof limit === 'number' && limit >= 0) {
|
|
351
|
-
query.limit(limit);
|
|
352
|
-
}
|
|
353
|
-
const count = await query.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
354
|
-
.exec();
|
|
355
|
-
return { count };
|
|
356
|
-
}
|
|
357
|
-
/**
|
|
358
|
-
* 実行日時を一定期間過ぎたReadyタスクについて、Runningステータスに変更する
|
|
359
|
-
*/
|
|
360
|
-
async runDelayedTask(params) {
|
|
361
|
-
const { filter } = params;
|
|
362
|
-
const projection = {
|
|
363
|
-
_id: 0,
|
|
364
|
-
id: { $toString: '$_id' },
|
|
365
|
-
name: 1
|
|
366
|
-
};
|
|
367
|
-
return this.taskModel.findOneAndUpdate(filter, {
|
|
368
|
-
$set: {
|
|
369
|
-
status: factory_1.factory.taskStatus.Running, // 実行中に変更
|
|
370
|
-
lastTriedAt: new Date(),
|
|
371
|
-
executor: params.executor
|
|
372
|
-
},
|
|
373
|
-
$inc: {
|
|
374
|
-
remainingNumberOfTries: -1, // 残りトライ可能回数減らす
|
|
375
|
-
numberOfTried: 1 // トライ回数増やす
|
|
376
|
-
}
|
|
377
|
-
}, {
|
|
378
|
-
new: true,
|
|
379
|
-
projection,
|
|
380
|
-
...(typeof params.sort.numberOfTried === 'number' || typeof params.sort.runsAt === 'number')
|
|
381
|
-
? { sort: params.sort }
|
|
382
|
-
: undefined
|
|
383
|
-
})
|
|
384
|
-
.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
385
|
-
.lean()
|
|
386
|
-
.exec();
|
|
387
|
-
}
|
|
388
|
-
/**
|
|
389
|
-
* 実行日時を一定期間過ぎたReadyタスクについて、Runningステータスに変更した上で、Runningイベントを発生させる
|
|
390
|
-
*/
|
|
391
|
-
async emitRunningIfExistsByName(params) {
|
|
392
|
-
if (!(params.runsAt.$lt instanceof Date)) {
|
|
393
|
-
throw new factory_1.factory.errors.Argument('runsAt.$lt', 'must be Date');
|
|
394
|
-
}
|
|
395
|
-
// const projection: ProjectionType<IDocType> = {
|
|
396
|
-
// _id: 0,
|
|
397
|
-
// id: { $toString: '$_id' },
|
|
398
|
-
// name: 1
|
|
399
|
-
// };
|
|
400
|
-
// インデックス'executeOneByNameIfExists'を想定したfilter
|
|
401
|
-
const filter = {
|
|
402
|
-
status: { $eq: factory_1.factory.taskStatus.Ready },
|
|
403
|
-
runsAt: { $lt: params.runsAt.$lt },
|
|
404
|
-
name: params.name
|
|
405
|
-
};
|
|
406
|
-
const doc = await this.runDelayedTask({
|
|
407
|
-
filter,
|
|
408
|
-
sort: params.sort,
|
|
409
|
-
executor: params.executor
|
|
410
|
-
});
|
|
411
|
-
// const doc = await this.taskModel.findOneAndUpdate(
|
|
412
|
-
// filter,
|
|
413
|
-
// {
|
|
414
|
-
// $set: {
|
|
415
|
-
// status: factory.taskStatus.Running, // 実行中に変更
|
|
416
|
-
// lastTriedAt: new Date(),
|
|
417
|
-
// executor: params.executor
|
|
418
|
-
// },
|
|
419
|
-
// $inc: {
|
|
420
|
-
// remainingNumberOfTries: -1, // 残りトライ可能回数減らす
|
|
421
|
-
// numberOfTried: 1 // トライ回数増やす
|
|
422
|
-
// }
|
|
423
|
-
// },
|
|
424
|
-
// {
|
|
425
|
-
// new: true,
|
|
426
|
-
// projection,
|
|
427
|
-
// ...(typeof params.sort.numberOfTried === 'number' || typeof params.sort.runsAt === 'number')
|
|
428
|
-
// ? { sort: params.sort }
|
|
429
|
-
// : undefined
|
|
430
|
-
// }
|
|
431
|
-
// )
|
|
432
|
-
// .setOptions({ maxTimeMS: MONGO_MAX_TIME_MS })
|
|
433
|
-
// .lean<Pick<factory.task.ITask<factory.taskName>, 'id' | 'name'>>()
|
|
434
|
-
// .exec();
|
|
435
|
-
if (doc === null) {
|
|
436
|
-
return null;
|
|
437
|
-
}
|
|
438
|
-
const nameEq = params.name?.$eq;
|
|
439
|
-
let changedTask;
|
|
440
|
-
if (typeof nameEq === 'string') {
|
|
441
|
-
changedTask = {
|
|
442
|
-
id: doc.id,
|
|
443
|
-
status: factory_1.factory.taskStatus.Running,
|
|
444
|
-
name: nameEq
|
|
445
|
-
};
|
|
446
|
-
}
|
|
447
|
-
else {
|
|
448
|
-
changedTask = {
|
|
449
|
-
id: doc.id,
|
|
450
|
-
status: factory_1.factory.taskStatus.Running
|
|
451
|
-
};
|
|
452
|
-
}
|
|
453
|
-
task_1.taskEventEmitter.emitTaskStatusChanged(changedTask);
|
|
454
|
-
return doc;
|
|
455
|
-
}
|
|
456
|
-
/**
|
|
457
|
-
* 実行日時を一定期間過ぎたReadyタスクについて、Runningステータスに変更した上で、Runningイベントを発生させる
|
|
458
|
-
* taskNameで絞らない
|
|
459
|
-
* 2026-08-04~
|
|
460
|
-
*/
|
|
461
|
-
async emitRunningIfExistsNoName(params) {
|
|
462
|
-
if (!(params.runsAt.$lt instanceof Date)) {
|
|
463
|
-
throw new factory_1.factory.errors.Argument('runsAt.$lt', 'must be Date');
|
|
464
|
-
}
|
|
465
|
-
// インデックス'executeOneByNameIfExists'を想定したfilter
|
|
466
|
-
const filter = {
|
|
467
|
-
status: { $eq: factory_1.factory.taskStatus.Ready },
|
|
468
|
-
runsAt: { $lt: params.runsAt.$lt }
|
|
469
|
-
};
|
|
470
|
-
const doc = await this.runDelayedTask({
|
|
471
|
-
filter,
|
|
472
|
-
sort: {
|
|
473
|
-
runsAt: factory_1.factory.sortType.Ascending // ソートはrunsAtのみにしてみる(2026-08-04~)
|
|
474
|
-
},
|
|
475
|
-
executor: params.executor
|
|
476
|
-
});
|
|
477
|
-
if (doc === null) {
|
|
478
|
-
return null;
|
|
479
|
-
}
|
|
480
|
-
const changedTask = {
|
|
481
|
-
id: doc.id,
|
|
482
|
-
status: factory_1.factory.taskStatus.Running
|
|
483
|
-
};
|
|
484
|
-
task_1.taskEventEmitter.emitTaskStatusChanged(changedTask);
|
|
485
|
-
return doc;
|
|
486
|
-
}
|
|
487
193
|
/**
|
|
488
194
|
* Runningのまま一定期間超過し、かつ、remainingNumberOfTries>0のタスクをReadyに変更する
|
|
489
195
|
*/
|
|
@@ -491,8 +197,6 @@ class TaskRepo {
|
|
|
491
197
|
const lastTriedAtShoudBeLessThan = (0, moment_1.default)()
|
|
492
198
|
.add(-params.intervalInMinutes, 'minutes')
|
|
493
199
|
.toDate();
|
|
494
|
-
// const remainingNumberOfTriesGte = params.remainingNumberOfTries.$gte;
|
|
495
|
-
// const remainingNumberOfTriesLte = params.remainingNumberOfTries.$lte;
|
|
496
200
|
return this.taskModel.updateMany(
|
|
497
201
|
// name: 'retry'のindexと連動しているので、条件の順序などには注意すること
|
|
498
202
|
// @see schemas/task
|
|
@@ -502,14 +206,7 @@ class TaskRepo {
|
|
|
502
206
|
$type: 'date',
|
|
503
207
|
$lt: lastTriedAtShoudBeLessThan
|
|
504
208
|
},
|
|
505
|
-
remainingNumberOfTries: { $gte: 1 }
|
|
506
|
-
// ...(typeof remainingNumberOfTriesGte === 'number')
|
|
507
|
-
// ? { remainingNumberOfTries: { $gte: remainingNumberOfTriesGte } }
|
|
508
|
-
// : undefined,
|
|
509
|
-
// ...(typeof remainingNumberOfTriesLte === 'number')
|
|
510
|
-
// ? { remainingNumberOfTries: { $lte: remainingNumberOfTriesLte } }
|
|
511
|
-
// : undefined,
|
|
512
|
-
// ...(Array.isArray(params.name.$in)) ? { name: { $in: params.name.$in } } : undefined
|
|
209
|
+
remainingNumberOfTries: { $gte: 1 }
|
|
513
210
|
}, {
|
|
514
211
|
$set: {
|
|
515
212
|
status: factory_1.factory.taskStatus.Ready // 実行前に変更
|
|
@@ -524,8 +221,6 @@ class TaskRepo {
|
|
|
524
221
|
const lastTriedAtShoudBeLessThan = (0, moment_1.default)()
|
|
525
222
|
.add(-params.intervalInMinutes, 'minutes')
|
|
526
223
|
.toDate();
|
|
527
|
-
// const remainingNumberOfTriesGte = params.remainingNumberOfTries.$gte;
|
|
528
|
-
// const remainingNumberOfTriesLte = params.remainingNumberOfTries.$lte;
|
|
529
224
|
return this.taskModel.updateMany(
|
|
530
225
|
// name: 'retry'のindexと連動しているので、条件の順序などには注意すること
|
|
531
226
|
// @see schemas/task
|
|
@@ -536,12 +231,6 @@ class TaskRepo {
|
|
|
536
231
|
$lt: lastTriedAtShoudBeLessThan
|
|
537
232
|
},
|
|
538
233
|
remainingNumberOfTries: { $lte: 0 },
|
|
539
|
-
// ...(typeof remainingNumberOfTriesGte === 'number')
|
|
540
|
-
// ? { remainingNumberOfTries: { $gte: remainingNumberOfTriesGte } }
|
|
541
|
-
// : undefined,
|
|
542
|
-
// ...(typeof remainingNumberOfTriesLte === 'number')
|
|
543
|
-
// ? { remainingNumberOfTries: { $lte: remainingNumberOfTriesLte } }
|
|
544
|
-
// : undefined,
|
|
545
234
|
...(Array.isArray(params.name.$in)) ? { name: { $in: params.name.$in } } : undefined
|
|
546
235
|
}, {
|
|
547
236
|
$set: {
|
|
@@ -596,10 +285,8 @@ class TaskRepo {
|
|
|
596
285
|
* タスクIDから実行結果とステータスを保管する
|
|
597
286
|
* Abortedの場合、dateAbortedもセットする
|
|
598
287
|
*/
|
|
599
|
-
async setExecutionResultAndStatus(params, update
|
|
600
|
-
|
|
601
|
-
next) {
|
|
602
|
-
const { id, remainingNumberOfTries, name } = params;
|
|
288
|
+
async setExecutionResultAndStatus(params, update) {
|
|
289
|
+
const { id } = params;
|
|
603
290
|
const { status, executionResult } = update;
|
|
604
291
|
await this.taskModel.updateOne({ _id: { $eq: id } }, {
|
|
605
292
|
$set: {
|
|
@@ -609,57 +296,6 @@ class TaskRepo {
|
|
|
609
296
|
$push: { executionResults: executionResult }
|
|
610
297
|
})
|
|
611
298
|
.exec();
|
|
612
|
-
// emit event(2025-05-26~)
|
|
613
|
-
if (typeof next === 'function') {
|
|
614
|
-
const changedTask = { id, name, status, remainingNumberOfTries, executionResult };
|
|
615
|
-
task_1.taskEventEmitter.emitTaskStatusChanged(changedTask, next);
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
// 非同期アクションへ移行したので不要(2026-08-04~)
|
|
619
|
-
// /**
|
|
620
|
-
// * タスクの状態を参照する
|
|
621
|
-
// * 非同期アクション移行が完了したら廃止する(2026-07-29~)
|
|
622
|
-
// */
|
|
623
|
-
// public async findTaskById(
|
|
624
|
-
// params: {
|
|
625
|
-
// id: { $eq: string };
|
|
626
|
-
// project: { id: { $eq: string } };
|
|
627
|
-
// name: factory.taskName
|
|
628
|
-
// },
|
|
629
|
-
// inclusion: IKeyOfProjection[]
|
|
630
|
-
// ): Promise<(IDocType & { id: string } | undefined)> {
|
|
631
|
-
// let positiveProjectionFields: IKeyOfProjection[] = AVAILABLE_PROJECT_FIELDS;
|
|
632
|
-
// if (Array.isArray(inclusion) && inclusion.length > 0) {
|
|
633
|
-
// positiveProjectionFields = inclusion.filter((key) => AVAILABLE_PROJECT_FIELDS.includes(key));
|
|
634
|
-
// } else {
|
|
635
|
-
// // no op
|
|
636
|
-
// }
|
|
637
|
-
// const projection: ProjectionType<IDocType> = {
|
|
638
|
-
// _id: 0,
|
|
639
|
-
// id: { $toString: '$_id' },
|
|
640
|
-
// ...Object.fromEntries<1>(positiveProjectionFields.map((key) => ([key, 1])))
|
|
641
|
-
// };
|
|
642
|
-
// const query = this.taskModel.findOne(
|
|
643
|
-
// {
|
|
644
|
-
// _id: { $eq: params.id.$eq },
|
|
645
|
-
// 'project.id': { $eq: params.project.id.$eq },
|
|
646
|
-
// name: { $eq: params.name }
|
|
647
|
-
// },
|
|
648
|
-
// projection
|
|
649
|
-
// );
|
|
650
|
-
// const doc = await query.setOptions({ maxTimeMS: MONGO_MAX_TIME_MS })
|
|
651
|
-
// .lean<IDocType & { id: string }>()
|
|
652
|
-
// .exec();
|
|
653
|
-
// if (doc === null) {
|
|
654
|
-
// return;
|
|
655
|
-
// }
|
|
656
|
-
// return doc;
|
|
657
|
-
// }
|
|
658
|
-
async deleteByProject(params) {
|
|
659
|
-
await this.taskModel.deleteMany({
|
|
660
|
-
'project.id': { $eq: params.project.id }
|
|
661
|
-
})
|
|
662
|
-
.exec();
|
|
663
299
|
}
|
|
664
300
|
/**
|
|
665
301
|
* 不要なタスクを削除する
|
|
@@ -677,22 +313,5 @@ class TaskRepo {
|
|
|
677
313
|
})
|
|
678
314
|
.exec();
|
|
679
315
|
}
|
|
680
|
-
async countDelayedTasks(params) {
|
|
681
|
-
const { limit } = params;
|
|
682
|
-
const runsAtLt = (0, moment_1.default)()
|
|
683
|
-
.add(-params.delayInSeconds, 'seconds')
|
|
684
|
-
.toDate();
|
|
685
|
-
const query = this.taskModel.countDocuments({
|
|
686
|
-
status: { $eq: factory_1.factory.taskStatus.Ready },
|
|
687
|
-
runsAt: { $lt: runsAtLt },
|
|
688
|
-
...(Array.isArray(params.name.$nin)) ? { name: { $nin: params.name.$nin } } : undefined
|
|
689
|
-
});
|
|
690
|
-
if (typeof limit === 'number' && limit >= 0) {
|
|
691
|
-
query.limit(limit);
|
|
692
|
-
}
|
|
693
|
-
const count = await query.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
694
|
-
.exec();
|
|
695
|
-
return { count };
|
|
696
|
-
}
|
|
697
316
|
}
|
|
698
317
|
exports.TaskRepo = TaskRepo;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { Connection } 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
|
+
emitRunningIfExistsByName(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
|
+
sort: {
|
|
47
|
+
numberOfTried?: factory.sortType;
|
|
48
|
+
runsAt?: factory.sortType;
|
|
49
|
+
};
|
|
50
|
+
executor: {
|
|
51
|
+
name: string;
|
|
52
|
+
};
|
|
53
|
+
}): Promise<Pick<factory.task.ITask<factory.taskName>, 'id' | 'name'> | null>;
|
|
54
|
+
/**
|
|
55
|
+
* 実行日時を一定期間過ぎたReadyタスクについて、Runningステータスに変更した上で、Runningイベントを発生させる
|
|
56
|
+
* taskNameで絞らない
|
|
57
|
+
* 2026-08-04~
|
|
58
|
+
*/
|
|
59
|
+
emitRunningIfExistsNoName(params: {
|
|
60
|
+
runsAt: {
|
|
61
|
+
$lt: Date;
|
|
62
|
+
};
|
|
63
|
+
executor: {
|
|
64
|
+
name: string;
|
|
65
|
+
};
|
|
66
|
+
}): Promise<Pick<factory.task.ITask<factory.taskName>, 'id' | 'name'> | null>;
|
|
67
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TaskDelayedRepo = void 0;
|
|
4
|
+
const task_1 = require("../eventEmitter/task");
|
|
5
|
+
const factory_1 = require("../factory");
|
|
6
|
+
const settings_1 = require("../settings");
|
|
7
|
+
const task_2 = require("./mongoose/schemas/task");
|
|
8
|
+
/**
|
|
9
|
+
* 遅延タスクリポジトリ
|
|
10
|
+
*/
|
|
11
|
+
class TaskDelayedRepo {
|
|
12
|
+
taskModel;
|
|
13
|
+
constructor(connection) {
|
|
14
|
+
this.taskModel = connection.model(task_2.modelName, (0, task_2.createSchema)());
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 潜在的に実行されるべきタスクをカウントする
|
|
18
|
+
* add(2025-03-16~)
|
|
19
|
+
*/
|
|
20
|
+
async countPotentiallyRunning(params) {
|
|
21
|
+
const { runsAt, limit, name } = params;
|
|
22
|
+
const nameEq = name?.$eq;
|
|
23
|
+
const nameIn = name?.$in;
|
|
24
|
+
if (!(runsAt.$lt instanceof Date)) {
|
|
25
|
+
throw new factory_1.factory.errors.Argument('runsAt.$lt', 'must be Date');
|
|
26
|
+
}
|
|
27
|
+
const query = this.taskModel.countDocuments({
|
|
28
|
+
status: { $eq: factory_1.factory.taskStatus.Ready },
|
|
29
|
+
...(typeof nameEq === 'string' || Array.isArray(nameIn))
|
|
30
|
+
? {
|
|
31
|
+
name: {
|
|
32
|
+
...(typeof nameEq === 'string') ? { $eq: nameEq } : undefined,
|
|
33
|
+
...(Array.isArray(nameIn)) ? { $in: nameIn } : undefined
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
: undefined,
|
|
37
|
+
runsAt: { $lt: params.runsAt.$lt }
|
|
38
|
+
});
|
|
39
|
+
if (typeof limit === 'number' && limit >= 0) {
|
|
40
|
+
query.limit(limit);
|
|
41
|
+
}
|
|
42
|
+
const count = await query.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
43
|
+
.exec();
|
|
44
|
+
return { count };
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* 実行日時を一定期間過ぎたReadyタスクについて、Runningステータスに変更する
|
|
48
|
+
*/
|
|
49
|
+
async runDelayedTask(params) {
|
|
50
|
+
const { filter } = params;
|
|
51
|
+
const projection = {
|
|
52
|
+
_id: 0,
|
|
53
|
+
id: { $toString: '$_id' },
|
|
54
|
+
name: 1
|
|
55
|
+
};
|
|
56
|
+
return this.taskModel.findOneAndUpdate(filter, {
|
|
57
|
+
$set: {
|
|
58
|
+
status: factory_1.factory.taskStatus.Running, // 実行中に変更
|
|
59
|
+
lastTriedAt: new Date(),
|
|
60
|
+
executor: params.executor
|
|
61
|
+
},
|
|
62
|
+
$inc: {
|
|
63
|
+
remainingNumberOfTries: -1, // 残りトライ可能回数減らす
|
|
64
|
+
numberOfTried: 1 // トライ回数増やす
|
|
65
|
+
}
|
|
66
|
+
}, {
|
|
67
|
+
new: true,
|
|
68
|
+
projection,
|
|
69
|
+
...(typeof params.sort.numberOfTried === 'number' || typeof params.sort.runsAt === 'number')
|
|
70
|
+
? { sort: params.sort }
|
|
71
|
+
: undefined
|
|
72
|
+
})
|
|
73
|
+
.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
74
|
+
.lean()
|
|
75
|
+
.exec();
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* 実行日時を一定期間過ぎたReadyタスクについて、Runningステータスに変更した上で、Runningイベントを発生させる
|
|
79
|
+
*/
|
|
80
|
+
async emitRunningIfExistsByName(params) {
|
|
81
|
+
if (!(params.runsAt.$lt instanceof Date)) {
|
|
82
|
+
throw new factory_1.factory.errors.Argument('runsAt.$lt', 'must be Date');
|
|
83
|
+
}
|
|
84
|
+
// インデックス'executeOneByNameIfExists'を想定したfilter
|
|
85
|
+
const filter = {
|
|
86
|
+
status: { $eq: factory_1.factory.taskStatus.Ready },
|
|
87
|
+
name: params.name,
|
|
88
|
+
runsAt: { $lt: params.runsAt.$lt }
|
|
89
|
+
};
|
|
90
|
+
const doc = await this.runDelayedTask({
|
|
91
|
+
filter,
|
|
92
|
+
sort: params.sort,
|
|
93
|
+
executor: params.executor
|
|
94
|
+
});
|
|
95
|
+
if (doc === null) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
const nameEq = params.name?.$eq;
|
|
99
|
+
let changedTask;
|
|
100
|
+
if (typeof nameEq === 'string') {
|
|
101
|
+
changedTask = {
|
|
102
|
+
id: doc.id,
|
|
103
|
+
status: factory_1.factory.taskStatus.Running,
|
|
104
|
+
name: nameEq
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
changedTask = {
|
|
109
|
+
id: doc.id,
|
|
110
|
+
status: factory_1.factory.taskStatus.Running
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
task_1.taskEventEmitter.emitTaskStatusChanged(changedTask);
|
|
114
|
+
return doc;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* 実行日時を一定期間過ぎたReadyタスクについて、Runningステータスに変更した上で、Runningイベントを発生させる
|
|
118
|
+
* taskNameで絞らない
|
|
119
|
+
* 2026-08-04~
|
|
120
|
+
*/
|
|
121
|
+
async emitRunningIfExistsNoName(params) {
|
|
122
|
+
if (!(params.runsAt.$lt instanceof Date)) {
|
|
123
|
+
throw new factory_1.factory.errors.Argument('runsAt.$lt', 'must be Date');
|
|
124
|
+
}
|
|
125
|
+
// インデックス'executeOneByNameIfExists'を想定したfilter
|
|
126
|
+
const filter = {
|
|
127
|
+
status: { $eq: factory_1.factory.taskStatus.Ready },
|
|
128
|
+
runsAt: { $lt: params.runsAt.$lt }
|
|
129
|
+
};
|
|
130
|
+
const doc = await this.runDelayedTask({
|
|
131
|
+
filter,
|
|
132
|
+
sort: {
|
|
133
|
+
runsAt: factory_1.factory.sortType.Ascending // ソートはrunsAtのみにしてみる(2026-08-04~)
|
|
134
|
+
},
|
|
135
|
+
executor: params.executor
|
|
136
|
+
});
|
|
137
|
+
if (doc === null) {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
const changedTask = {
|
|
141
|
+
id: doc.id,
|
|
142
|
+
status: factory_1.factory.taskStatus.Running
|
|
143
|
+
};
|
|
144
|
+
task_1.taskEventEmitter.emitTaskStatusChanged(changedTask);
|
|
145
|
+
return doc;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
exports.TaskDelayedRepo = TaskDelayedRepo;
|