@chevre/domain 25.2.0-alpha.47 → 25.2.0-alpha.49
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/repo/asyncAction.d.ts +31 -12
- package/lib/chevre/repo/asyncAction.js +63 -28
- package/lib/chevre/repo/mongoose/schemas/asyncAction.d.ts +11 -0
- package/lib/chevre/repo/mongoose/schemas/asyncAction.js +159 -0
- package/lib/chevre/service/asyncAction.d.ts +6 -2
- package/lib/chevre/service/asyncAction.js +2 -4
- package/lib/chevre/service/asyncActionHandler/onOperationFailed.d.ts +2 -4
- package/lib/chevre/service/asyncActionHandler/onOperationFailed.js +1 -1
- package/lib/chevre/service/asyncActionHandler.d.ts +3 -3
- package/lib/chevre/service/asyncActionHandler.js +6 -7
- package/lib/chevre/service/offer/eventServiceByCOA/findAcceptAction.d.ts +4 -0
- package/lib/chevre/service/offer/eventServiceByCOA/findAcceptAction.js +22 -9
- package/package.json +1 -1
|
@@ -1,45 +1,63 @@
|
|
|
1
1
|
import type { Connection, UpdateWriteOpResult } from 'mongoose';
|
|
2
2
|
import { factory } from '../factory';
|
|
3
|
-
import { IModel } from './mongoose/schemas/
|
|
3
|
+
import { IModel, IDocType } from './mongoose/schemas/asyncAction';
|
|
4
4
|
import type { IExecutableTask } from '../taskSettings';
|
|
5
|
+
type ISavingTask = Pick<factory.task.IAttributes<factory.taskName>, 'alternateName' | 'data' | 'description' | 'executionResults' | 'expires' | 'identifier' | 'name' | 'project' | 'runsAt' | 'status'> & {
|
|
6
|
+
expires: Date;
|
|
7
|
+
};
|
|
8
|
+
export type IExecutableAsyncAction = Pick<IExecutableTask<factory.taskName>, 'data' | 'expires' | 'id' | 'name' | 'project' | 'runsAt' | 'status'>;
|
|
9
|
+
type IKeyOfProjection = keyof factory.task.ITask<factory.taskName>;
|
|
5
10
|
/**
|
|
6
|
-
*
|
|
11
|
+
* 非同期アクションリポジトリ
|
|
7
12
|
*/
|
|
8
13
|
export declare class AsyncActionRepo {
|
|
9
|
-
readonly
|
|
14
|
+
readonly asyncActionModel: IModel;
|
|
10
15
|
constructor(connection: Connection);
|
|
11
16
|
/**
|
|
12
17
|
* Readyタスクをひとつ追加する
|
|
13
18
|
*/
|
|
14
|
-
addReadyAsyncAction(params: Pick<
|
|
19
|
+
addReadyAsyncAction(params: Pick<ISavingTask, 'data' | 'expires' | 'name' | 'project' | 'runsAt'> & {
|
|
15
20
|
alternateName?: never;
|
|
16
21
|
identifier?: never;
|
|
17
|
-
expires: Date;
|
|
18
22
|
}): Promise<{
|
|
19
23
|
id: string;
|
|
20
24
|
}>;
|
|
21
25
|
/**
|
|
22
|
-
* Ready ->
|
|
26
|
+
* Ready -> Running
|
|
23
27
|
*/
|
|
24
28
|
executeAsyncActionById(params: {
|
|
25
29
|
id: string;
|
|
26
|
-
status: factory.taskStatus.Ready;
|
|
27
30
|
executor: {
|
|
28
31
|
name: string;
|
|
29
32
|
};
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
}): Promise<IExecutableAsyncAction | null>;
|
|
34
|
+
/**
|
|
35
|
+
* 非同期アクションの状態を参照する
|
|
36
|
+
*/
|
|
37
|
+
findAsyncActionById(params: {
|
|
38
|
+
id: {
|
|
39
|
+
$eq: string;
|
|
40
|
+
};
|
|
41
|
+
project: {
|
|
42
|
+
id: {
|
|
43
|
+
$eq: string;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
name: factory.taskName;
|
|
47
|
+
}, inclusion: IKeyOfProjection[]): Promise<(IDocType & {
|
|
48
|
+
id: string;
|
|
49
|
+
} | undefined)>;
|
|
32
50
|
/**
|
|
33
51
|
* Readyのままで期限切れのタスクをExpiredに変更する
|
|
34
52
|
*/
|
|
35
53
|
makeExpiredMany(params: {
|
|
36
54
|
expiresLt: Date;
|
|
37
55
|
}): Promise<UpdateWriteOpResult>;
|
|
56
|
+
/**
|
|
57
|
+
* taskNameに関わらず、Runningのまま放置された非同期アクションをAbortedに変更する
|
|
58
|
+
*/
|
|
38
59
|
abortMany(params: {
|
|
39
60
|
intervalInMinutes: number;
|
|
40
|
-
name: {
|
|
41
|
-
$in?: factory.taskName[];
|
|
42
|
-
};
|
|
43
61
|
}): Promise<UpdateWriteOpResult>;
|
|
44
62
|
/**
|
|
45
63
|
* タスクIDから実行結果とステータスを保管する
|
|
@@ -63,3 +81,4 @@ export declare class AsyncActionRepo {
|
|
|
63
81
|
};
|
|
64
82
|
}): Promise<import("mongodb").DeleteResult>;
|
|
65
83
|
}
|
|
84
|
+
export {};
|
|
@@ -7,7 +7,7 @@ exports.AsyncActionRepo = void 0;
|
|
|
7
7
|
const moment_1 = __importDefault(require("moment"));
|
|
8
8
|
const factory_1 = require("../factory");
|
|
9
9
|
const settings_1 = require("../settings");
|
|
10
|
-
const
|
|
10
|
+
const asyncAction_1 = require("./mongoose/schemas/asyncAction");
|
|
11
11
|
const executableTaskProjection = {
|
|
12
12
|
_id: 0,
|
|
13
13
|
id: { $toString: '$_id' },
|
|
@@ -15,38 +15,47 @@ const executableTaskProjection = {
|
|
|
15
15
|
data: 1,
|
|
16
16
|
name: 1,
|
|
17
17
|
status: 1,
|
|
18
|
-
numberOfTried: 1,
|
|
19
18
|
project: 1,
|
|
20
|
-
remainingNumberOfTries: 1,
|
|
21
19
|
runsAt: 1,
|
|
22
20
|
expires: 1
|
|
23
21
|
};
|
|
22
|
+
const AVAILABLE_PROJECT_FIELDS = [
|
|
23
|
+
'alternateName',
|
|
24
|
+
'identifier',
|
|
25
|
+
'description',
|
|
26
|
+
'project',
|
|
27
|
+
'name',
|
|
28
|
+
'status',
|
|
29
|
+
'runsAt',
|
|
30
|
+
'lastTriedAt',
|
|
31
|
+
'executionResults',
|
|
32
|
+
'executor',
|
|
33
|
+
'data',
|
|
34
|
+
'dateAborted',
|
|
35
|
+
'expires'
|
|
36
|
+
];
|
|
24
37
|
/**
|
|
25
|
-
*
|
|
38
|
+
* 非同期アクションリポジトリ
|
|
26
39
|
*/
|
|
27
40
|
class AsyncActionRepo {
|
|
28
|
-
|
|
41
|
+
asyncActionModel;
|
|
29
42
|
constructor(connection) {
|
|
30
|
-
this.
|
|
43
|
+
this.asyncActionModel = connection.model(asyncAction_1.modelName, (0, asyncAction_1.createSchema)());
|
|
31
44
|
}
|
|
32
45
|
/**
|
|
33
46
|
* Readyタスクをひとつ追加する
|
|
34
47
|
*/
|
|
35
|
-
async addReadyAsyncAction(
|
|
36
|
-
// resolve uniqueness of identifier(2025-03-27~)
|
|
37
|
-
params) {
|
|
48
|
+
async addReadyAsyncAction(params) {
|
|
38
49
|
const { expires } = params;
|
|
39
50
|
if (!(expires instanceof Date)) {
|
|
40
51
|
throw new factory_1.factory.errors.Argument('expires', 'must be Date');
|
|
41
52
|
}
|
|
42
53
|
const savingTask = {
|
|
43
54
|
...params,
|
|
44
|
-
remainingNumberOfTries: 1, // リトライはありえないので、1で固定
|
|
45
55
|
status: factory_1.factory.taskStatus.Ready,
|
|
46
|
-
numberOfTried: 0,
|
|
47
56
|
executionResults: []
|
|
48
57
|
};
|
|
49
|
-
const result = await this.
|
|
58
|
+
const result = await this.asyncActionModel.insertMany(savingTask, { rawResult: true });
|
|
50
59
|
const id = result.insertedIds?.[0]?.toHexString();
|
|
51
60
|
if (typeof id !== 'string') {
|
|
52
61
|
throw new factory_1.factory.errors.Internal('task not saved');
|
|
@@ -54,25 +63,21 @@ class AsyncActionRepo {
|
|
|
54
63
|
return { id };
|
|
55
64
|
}
|
|
56
65
|
/**
|
|
57
|
-
* Ready ->
|
|
66
|
+
* Ready -> Running
|
|
58
67
|
*/
|
|
59
68
|
async executeAsyncActionById(params) {
|
|
60
69
|
const now = new Date();
|
|
61
|
-
const doc = await this.
|
|
70
|
+
const doc = await this.asyncActionModel.findOneAndUpdate({
|
|
62
71
|
_id: { $eq: params.id },
|
|
63
|
-
status: { $eq:
|
|
72
|
+
status: { $eq: factory_1.factory.taskStatus.Ready }, // Readyのものしか実行しない
|
|
64
73
|
runsAt: { $lt: now },
|
|
65
|
-
|
|
74
|
+
expires: { $exists: true, $gt: now }, // ワンタイムタスクなのでexpiresは必ず存在する
|
|
66
75
|
}, {
|
|
67
76
|
$set: {
|
|
68
77
|
status: factory_1.factory.taskStatus.Running, // 実行中に変更
|
|
69
78
|
lastTriedAt: now,
|
|
70
79
|
executor: params.executor
|
|
71
80
|
},
|
|
72
|
-
$inc: {
|
|
73
|
-
remainingNumberOfTries: -1, // 残りトライ可能回数減らす
|
|
74
|
-
numberOfTried: 1 // トライ回数増やす
|
|
75
|
-
}
|
|
76
81
|
}, { new: true, projection: executableTaskProjection })
|
|
77
82
|
.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
78
83
|
.lean() // lean(2024-09-26~)
|
|
@@ -82,6 +87,35 @@ class AsyncActionRepo {
|
|
|
82
87
|
}
|
|
83
88
|
return doc;
|
|
84
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* 非同期アクションの状態を参照する
|
|
92
|
+
*/
|
|
93
|
+
async findAsyncActionById(params, inclusion) {
|
|
94
|
+
let positiveProjectionFields = AVAILABLE_PROJECT_FIELDS;
|
|
95
|
+
if (Array.isArray(inclusion) && inclusion.length > 0) {
|
|
96
|
+
positiveProjectionFields = inclusion.filter((key) => AVAILABLE_PROJECT_FIELDS.includes(key));
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
// no op
|
|
100
|
+
}
|
|
101
|
+
const projection = {
|
|
102
|
+
_id: 0,
|
|
103
|
+
id: { $toString: '$_id' },
|
|
104
|
+
...Object.fromEntries(positiveProjectionFields.map((key) => ([key, 1])))
|
|
105
|
+
};
|
|
106
|
+
const query = this.asyncActionModel.findOne({
|
|
107
|
+
_id: { $eq: params.id.$eq },
|
|
108
|
+
'project.id': { $eq: params.project.id.$eq },
|
|
109
|
+
name: { $eq: params.name }
|
|
110
|
+
}, projection);
|
|
111
|
+
const doc = await query.setOptions({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
|
|
112
|
+
.lean()
|
|
113
|
+
.exec();
|
|
114
|
+
if (doc === null) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
return doc;
|
|
118
|
+
}
|
|
85
119
|
/**
|
|
86
120
|
* Readyのままで期限切れのタスクをExpiredに変更する
|
|
87
121
|
*/
|
|
@@ -90,7 +124,7 @@ class AsyncActionRepo {
|
|
|
90
124
|
if (!(expiresLt instanceof Date)) {
|
|
91
125
|
throw new factory_1.factory.errors.Argument('expiresLt', 'must be Date');
|
|
92
126
|
}
|
|
93
|
-
return this.
|
|
127
|
+
return this.asyncActionModel.updateMany({
|
|
94
128
|
status: { $eq: factory_1.factory.taskStatus.Ready },
|
|
95
129
|
expires: { $exists: true, $lt: expiresLt }
|
|
96
130
|
}, {
|
|
@@ -100,18 +134,19 @@ class AsyncActionRepo {
|
|
|
100
134
|
})
|
|
101
135
|
.exec();
|
|
102
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* taskNameに関わらず、Runningのまま放置された非同期アクションをAbortedに変更する
|
|
139
|
+
*/
|
|
103
140
|
async abortMany(params) {
|
|
104
141
|
const lastTriedAtShoudBeLessThan = (0, moment_1.default)()
|
|
105
142
|
.add(-params.intervalInMinutes, 'minutes')
|
|
106
143
|
.toDate();
|
|
107
|
-
return this.
|
|
144
|
+
return this.asyncActionModel.updateMany({
|
|
108
145
|
status: { $eq: factory_1.factory.taskStatus.Running },
|
|
109
146
|
lastTriedAt: {
|
|
110
|
-
$
|
|
147
|
+
$exists: true,
|
|
111
148
|
$lt: lastTriedAtShoudBeLessThan
|
|
112
|
-
}
|
|
113
|
-
remainingNumberOfTries: { $eq: 0 },
|
|
114
|
-
...(Array.isArray(params.name.$in)) ? { name: { $in: params.name.$in } } : undefined
|
|
149
|
+
}
|
|
115
150
|
}, {
|
|
116
151
|
$set: {
|
|
117
152
|
status: factory_1.factory.taskStatus.Aborted,
|
|
@@ -127,7 +162,7 @@ class AsyncActionRepo {
|
|
|
127
162
|
async setExecutionResultAndStatus(params, update) {
|
|
128
163
|
const { id } = params;
|
|
129
164
|
const { status, executionResult } = update;
|
|
130
|
-
await this.
|
|
165
|
+
await this.asyncActionModel.updateOne({ _id: { $eq: id } }, {
|
|
131
166
|
$set: {
|
|
132
167
|
status,
|
|
133
168
|
...(status === factory_1.factory.taskStatus.Aborted) ? { dateAborted: executionResult.endDate } : undefined // 2025-08-04~
|
|
@@ -140,7 +175,7 @@ class AsyncActionRepo {
|
|
|
140
175
|
* 不要なタスクを削除する
|
|
141
176
|
*/
|
|
142
177
|
async deleteRunsAtPassedCertainPeriod(params) {
|
|
143
|
-
return this.
|
|
178
|
+
return this.asyncActionModel.deleteMany({
|
|
144
179
|
runsAt: { $lt: params.runsAt.$lt },
|
|
145
180
|
status: {
|
|
146
181
|
$in: [
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IndexDefinition, IndexOptions, Model, Schema, SchemaDefinition } from 'mongoose';
|
|
2
|
+
import { IVirtuals } from '../virtuals';
|
|
3
|
+
import { factory } from '../../../factory';
|
|
4
|
+
type IDocType = Pick<factory.task.ITask<factory.taskName>, 'alternateName' | 'data' | 'dateAborted' | 'description' | 'executionResults' | 'executor' | 'expires' | 'identifier' | 'lastTriedAt' | 'name' | 'project' | 'runsAt' | 'status'>;
|
|
5
|
+
type IModel = Model<IDocType, Record<string, never>, Record<string, never>, IVirtuals>;
|
|
6
|
+
type ISchemaDefinition = SchemaDefinition<IDocType>;
|
|
7
|
+
type ISchema = Schema<IDocType, IModel, Record<string, never>, Record<string, never>, IVirtuals, Record<string, never>, ISchemaDefinition, IDocType>;
|
|
8
|
+
declare const modelName = "AsyncAction";
|
|
9
|
+
declare const indexes: [d: IndexDefinition, o: IndexOptions][];
|
|
10
|
+
declare function createSchema(): ISchema;
|
|
11
|
+
export { createSchema, IDocType, IModel, indexes, modelName };
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.modelName = exports.indexes = void 0;
|
|
4
|
+
exports.createSchema = createSchema;
|
|
5
|
+
const mongoose_1 = require("mongoose");
|
|
6
|
+
const writeConcern_1 = require("../writeConcern");
|
|
7
|
+
const settings_1 = require("../../../settings");
|
|
8
|
+
const modelName = 'AsyncAction';
|
|
9
|
+
exports.modelName = modelName;
|
|
10
|
+
const schemaDefinition = {
|
|
11
|
+
alternateName: String, // add(2025-03-28~)
|
|
12
|
+
identifier: String,
|
|
13
|
+
description: String, // add(2025-03-30~)
|
|
14
|
+
project: { type: mongoose_1.SchemaTypes.Mixed, required: true },
|
|
15
|
+
name: { type: String, required: true },
|
|
16
|
+
status: { type: String, required: true },
|
|
17
|
+
runsAt: { type: Date, required: true },
|
|
18
|
+
expires: { type: Date, required: true },
|
|
19
|
+
lastTriedAt: Date,
|
|
20
|
+
executionResults: [mongoose_1.SchemaTypes.Mixed],
|
|
21
|
+
executor: mongoose_1.SchemaTypes.Mixed,
|
|
22
|
+
data: mongoose_1.SchemaTypes.Mixed,
|
|
23
|
+
dateAborted: Date,
|
|
24
|
+
// remainingNumberOfTries: { type: Number, required: true }, // ワンタイム前提につき不要
|
|
25
|
+
// numberOfTried: { type: Number, required: true }, // ワンタイム前提につき不要
|
|
26
|
+
};
|
|
27
|
+
const schemaOptions = {
|
|
28
|
+
autoIndex: settings_1.MONGO_AUTO_INDEX,
|
|
29
|
+
autoCreate: false,
|
|
30
|
+
collection: 'asyncActions',
|
|
31
|
+
id: true,
|
|
32
|
+
read: 'primary',
|
|
33
|
+
writeConcern: writeConcern_1.writeConcern,
|
|
34
|
+
strict: true,
|
|
35
|
+
strictQuery: false,
|
|
36
|
+
timestamps: false,
|
|
37
|
+
versionKey: false,
|
|
38
|
+
toJSON: {
|
|
39
|
+
getters: false,
|
|
40
|
+
virtuals: false,
|
|
41
|
+
minimize: false,
|
|
42
|
+
versionKey: false
|
|
43
|
+
},
|
|
44
|
+
toObject: {
|
|
45
|
+
getters: false,
|
|
46
|
+
virtuals: true,
|
|
47
|
+
minimize: false,
|
|
48
|
+
versionKey: false
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const indexes = [
|
|
52
|
+
[
|
|
53
|
+
{ 'project.id': 1, runsAt: -1 },
|
|
54
|
+
{ name: 'projectId' }
|
|
55
|
+
],
|
|
56
|
+
[
|
|
57
|
+
{ name: 1, runsAt: -1 },
|
|
58
|
+
{ name: 'asyncActionName' }
|
|
59
|
+
],
|
|
60
|
+
[
|
|
61
|
+
{ status: 1, runsAt: -1 },
|
|
62
|
+
{ name: 'status' }
|
|
63
|
+
],
|
|
64
|
+
[
|
|
65
|
+
{ runsAt: -1 },
|
|
66
|
+
{ name: 'runsAt' }
|
|
67
|
+
],
|
|
68
|
+
[
|
|
69
|
+
{ identifier: 1, runsAt: -1 },
|
|
70
|
+
{
|
|
71
|
+
name: 'identifier',
|
|
72
|
+
partialFilterExpression: {
|
|
73
|
+
identifier: { $exists: true }
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
],
|
|
77
|
+
[
|
|
78
|
+
{ dateAborted: 1, runsAt: -1 },
|
|
79
|
+
{
|
|
80
|
+
name: 'dateAborted',
|
|
81
|
+
partialFilterExpression: {
|
|
82
|
+
dateAborted: { $exists: true }
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
[
|
|
87
|
+
{ lastTriedAt: 1, runsAt: -1 },
|
|
88
|
+
{
|
|
89
|
+
name: 'lastTriedAt',
|
|
90
|
+
partialFilterExpression: {
|
|
91
|
+
lastTriedAt: { $exists: true }
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
],
|
|
95
|
+
[
|
|
96
|
+
{ expires: 1, runsAt: -1 },
|
|
97
|
+
{
|
|
98
|
+
name: 'expires',
|
|
99
|
+
partialFilterExpression: {
|
|
100
|
+
expires: { $exists: true }
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
],
|
|
104
|
+
[
|
|
105
|
+
{ status: 1, lastTriedAt: 1 },
|
|
106
|
+
{
|
|
107
|
+
name: 'abortMany',
|
|
108
|
+
partialFilterExpression: {
|
|
109
|
+
lastTriedAt: { $exists: true }
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
],
|
|
113
|
+
[
|
|
114
|
+
{ status: 1, expires: 1 },
|
|
115
|
+
{
|
|
116
|
+
name: 'makeExpiredMany',
|
|
117
|
+
partialFilterExpression: {
|
|
118
|
+
expires: { $exists: true }
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
],
|
|
122
|
+
[
|
|
123
|
+
// add unique index(2025-03-28~)
|
|
124
|
+
{ alternateName: 1 },
|
|
125
|
+
{
|
|
126
|
+
unique: true,
|
|
127
|
+
name: 'uniqueAlternateName',
|
|
128
|
+
partialFilterExpression: {
|
|
129
|
+
alternateName: { $exists: true }
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
],
|
|
133
|
+
[
|
|
134
|
+
{ identifier: 1 },
|
|
135
|
+
{
|
|
136
|
+
unique: true,
|
|
137
|
+
name: 'uniqueIdentifier',
|
|
138
|
+
partialFilterExpression: {
|
|
139
|
+
identifier: { $exists: true }
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
]
|
|
143
|
+
];
|
|
144
|
+
exports.indexes = indexes;
|
|
145
|
+
/**
|
|
146
|
+
* 非同期アクションスキーマ
|
|
147
|
+
*/
|
|
148
|
+
let schema;
|
|
149
|
+
function createSchema() {
|
|
150
|
+
if (schema === undefined) {
|
|
151
|
+
schema = new mongoose_1.Schema(schemaDefinition, schemaOptions);
|
|
152
|
+
if (settings_1.MONGO_AUTO_INDEX) {
|
|
153
|
+
indexes.forEach((indexParams) => {
|
|
154
|
+
schema?.index(...indexParams);
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return schema;
|
|
159
|
+
}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import type { IExecuteSettings as IMinimumExecuteSettings, INextFunction
|
|
1
|
+
import type { IExecuteSettings as IMinimumExecuteSettings, INextFunction } from '../eventEmitter/task';
|
|
2
2
|
type IExecuteSettings = IMinimumExecuteSettings;
|
|
3
3
|
type IOperation<T> = (settings: IExecuteSettings) => Promise<T>;
|
|
4
|
-
declare function executeAsyncActionById(params:
|
|
4
|
+
declare function executeAsyncActionById(params: {
|
|
5
|
+
/**
|
|
6
|
+
* タスクID
|
|
7
|
+
*/
|
|
8
|
+
id: string;
|
|
5
9
|
executor: {
|
|
6
10
|
/**
|
|
7
11
|
* タスク実行者名称
|
|
@@ -13,14 +13,12 @@ const debug = (0, debug_1.default)('chevre-domain:service:task');
|
|
|
13
13
|
function executeAsyncActionById(params, next) {
|
|
14
14
|
return async (settings) => {
|
|
15
15
|
const asyncActionRepo = new (await import('../repo/asyncAction.js')).AsyncActionRepo(settings.connection);
|
|
16
|
-
const { id,
|
|
16
|
+
const { id, executor } = params;
|
|
17
17
|
let task = null;
|
|
18
18
|
try {
|
|
19
19
|
task = await asyncActionRepo.executeAsyncActionById({
|
|
20
20
|
id,
|
|
21
|
-
|
|
22
|
-
executor: { name: executor.name },
|
|
23
|
-
...(expires instanceof Date) ? { expires } : undefined
|
|
21
|
+
executor: { name: executor.name }
|
|
24
22
|
});
|
|
25
23
|
}
|
|
26
24
|
catch (error) {
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import type { IExecutedTask } from '../../eventEmitter/task';
|
|
2
|
-
import { factory } from '../../factory';
|
|
3
2
|
import type { SettingRepo } from '../../repo/setting';
|
|
4
|
-
import type { AsyncActionRepo } from '../../repo/asyncAction';
|
|
5
|
-
import type { IExecutableTask } from '../../taskSettings';
|
|
3
|
+
import type { AsyncActionRepo, IExecutableAsyncAction } from '../../repo/asyncAction';
|
|
6
4
|
/**
|
|
7
5
|
* タスク実行失敗時処理
|
|
8
6
|
*/
|
|
9
7
|
declare function onOperationFailed(params: {
|
|
10
|
-
task:
|
|
8
|
+
task: IExecutableAsyncAction;
|
|
11
9
|
now: Date;
|
|
12
10
|
error: any;
|
|
13
11
|
}): (repos: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { INextFunction } from '../eventEmitter/task';
|
|
2
|
-
import {
|
|
3
|
-
import type {
|
|
2
|
+
import type { ICallResult, ICallableTaskOperation, IExecutableTaskKeys, IOperationExecute } from '../taskSettings';
|
|
3
|
+
import type { IExecutableAsyncAction } from '../repo/asyncAction';
|
|
4
4
|
export declare const taskLoader: {
|
|
5
5
|
load: (taskName: string) => Promise<{
|
|
6
6
|
call: ICallableTaskOperation;
|
|
@@ -9,5 +9,5 @@ export declare const taskLoader: {
|
|
|
9
9
|
/**
|
|
10
10
|
* 非同期アクションを実行する
|
|
11
11
|
*/
|
|
12
|
-
declare function executeAsyncAction(task:
|
|
12
|
+
declare function executeAsyncAction(task: IExecutableAsyncAction, next?: INextFunction): IOperationExecute<void>;
|
|
13
13
|
export { ICallableTaskOperation, ICallResult, IExecutableTaskKeys, IOperationExecute, executeAsyncAction };
|
|
@@ -34,16 +34,15 @@ function executeAsyncAction(task, next) {
|
|
|
34
34
|
throw new factory_1.factory.errors.Internal(`task expired [expires:${task.expires}]`);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
+
// remainingNumberOfTriesは存在しないので検証不要
|
|
37
38
|
// remainingNumberOfTries<0ならcallを実行しない(2025-08-04~)
|
|
38
|
-
// リトライを繰り返した後、不明の原因でRunningのまま残ってしまったタスクがリトライされたケース
|
|
39
|
-
const { remainingNumberOfTries } = task;
|
|
40
|
-
const isCallable = remainingNumberOfTries >= 0;
|
|
41
|
-
if (!isCallable) {
|
|
42
|
-
throw new factory_1.factory.errors.Internal(`task remainingNumberOfTries < 0 [remainingNumberOfTries:${remainingNumberOfTries}]`);
|
|
43
|
-
}
|
|
44
39
|
// タスク名の関数が定義されていなければ、TypeErrorとなる
|
|
45
40
|
const { call } = await exports.taskLoader.load(task.name); // testが書きづらいのでtaskLoader経由で呼ぶ
|
|
46
|
-
const callResult = await call(
|
|
41
|
+
const callResult = await call({
|
|
42
|
+
...task,
|
|
43
|
+
numberOfTried: 1, // ひとまず固定でok(2026-07-26~)
|
|
44
|
+
remainingNumberOfTries: 0 // ひとまず固定でok(2026-07-26~)
|
|
45
|
+
})(settings, options);
|
|
47
46
|
const result = {
|
|
48
47
|
executedAt: now,
|
|
49
48
|
endDate: new Date(),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { factory } from '../../../factory';
|
|
2
2
|
import type { AcceptCOAOfferActionRepo } from '../../../repo/action/acceptCOAOffer';
|
|
3
|
+
import type { AsyncActionRepo } from '../../../repo/asyncAction';
|
|
3
4
|
import type { TaskRepo } from '../../../repo/task';
|
|
4
5
|
interface IFindAcceptActionResult {
|
|
5
6
|
/**
|
|
@@ -34,8 +35,11 @@ declare function findAcceptAction(params: {
|
|
|
34
35
|
*/
|
|
35
36
|
id: string;
|
|
36
37
|
};
|
|
38
|
+
}, options: {
|
|
39
|
+
useAsyncAction: boolean;
|
|
37
40
|
}): (repos: {
|
|
38
41
|
action: AcceptCOAOfferActionRepo;
|
|
42
|
+
asyncAction: AsyncActionRepo;
|
|
39
43
|
task: TaskRepo;
|
|
40
44
|
}) => Promise<IFindAcceptActionResult>;
|
|
41
45
|
export { findAcceptAction };
|
|
@@ -2,16 +2,29 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.findAcceptAction = findAcceptAction;
|
|
4
4
|
const factory_1 = require("../../../factory");
|
|
5
|
-
function findAcceptAction(params) {
|
|
5
|
+
function findAcceptAction(params, options) {
|
|
6
6
|
return async (repos) => {
|
|
7
|
-
//
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
// 非同期アクションに対応(2026-07-27~)
|
|
8
|
+
const { useAsyncAction } = options;
|
|
9
|
+
let task;
|
|
10
|
+
if (useAsyncAction) {
|
|
11
|
+
// まず非同期アクションを参照
|
|
12
|
+
task = await repos.asyncAction.findAsyncActionById({
|
|
13
|
+
id: { $eq: params.sameAs.id },
|
|
14
|
+
project: { id: { $eq: params.project.id } },
|
|
15
|
+
name: factory_1.factory.taskName.AcceptCOAOffer
|
|
16
|
+
}, ['status', 'executionResults']);
|
|
17
|
+
}
|
|
18
|
+
// 非同期アクションが存在しなければタスクを参照
|
|
19
|
+
if (task === undefined) {
|
|
20
|
+
task = (await repos.task.projectFields({
|
|
21
|
+
limit: 1,
|
|
22
|
+
page: 1,
|
|
23
|
+
id: { $eq: params.sameAs.id },
|
|
24
|
+
project: { id: { $eq: params.project.id } },
|
|
25
|
+
name: factory_1.factory.taskName.AcceptCOAOffer
|
|
26
|
+
}, ['status', 'executionResults'])).shift();
|
|
27
|
+
}
|
|
15
28
|
if (task === undefined) {
|
|
16
29
|
throw new factory_1.factory.errors.NotFound(factory_1.factory.taskName.AcceptCOAOffer);
|
|
17
30
|
}
|
package/package.json
CHANGED