badmfck-api-server 2.2.8 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
@@ -24,6 +24,7 @@ export interface MysqlServiceOptions {
|
|
24
24
|
queueLimit?: number;
|
25
25
|
transactionFailReport?: (trx: ITransaction, message: string) => void;
|
26
26
|
transactionFailReportDir?: string;
|
27
|
+
debug?: boolean;
|
27
28
|
migrations?: {
|
28
29
|
dir: string;
|
29
30
|
callback: () => void;
|
@@ -82,6 +83,7 @@ export declare class MysqlService extends BaseService {
|
|
82
83
|
options: MysqlServiceOptions;
|
83
84
|
serviceStarted: boolean;
|
84
85
|
timeoutID: any;
|
86
|
+
debug: boolean;
|
85
87
|
queries: never[];
|
86
88
|
static nextTransactionID: number;
|
87
89
|
transactions: ITransaction[];
|
@@ -50,6 +50,7 @@ class MysqlService extends BaseService_1.BaseService {
|
|
50
50
|
options;
|
51
51
|
serviceStarted = false;
|
52
52
|
timeoutID;
|
53
|
+
debug = false;
|
53
54
|
queries = [];
|
54
55
|
static nextTransactionID = 0;
|
55
56
|
transactions = [];
|
@@ -68,6 +69,8 @@ class MysqlService extends BaseService_1.BaseService {
|
|
68
69
|
this.options.database = decrypt(this.options.database.substring(1)) ?? this.options.database;
|
69
70
|
if (this.options.password.startsWith("_"))
|
70
71
|
this.options.password = decrypt(this.options.password.substring(1)) ?? this.options.password;
|
72
|
+
if (this.options.debug)
|
73
|
+
this.debug = true;
|
71
74
|
setInterval(() => {
|
72
75
|
const now = Date.now();
|
73
76
|
this.transactions = this.transactions.filter(async (i) => {
|
@@ -109,12 +112,10 @@ class MysqlService extends BaseService_1.BaseService {
|
|
109
112
|
async init() {
|
110
113
|
super.init();
|
111
114
|
process.on('SIGINT', async () => {
|
112
|
-
console.log('1. Received SIGINT. Performing cleanup...');
|
113
115
|
await this.finishApp();
|
114
116
|
process.exit(0);
|
115
117
|
});
|
116
118
|
process.on('SIGTERM', async () => {
|
117
|
-
console.log('2. Received SIGTERM. Performing cleanup...');
|
118
119
|
await this.finishApp();
|
119
120
|
process.exit(0);
|
120
121
|
});
|
@@ -136,6 +137,8 @@ class MysqlService extends BaseService_1.BaseService {
|
|
136
137
|
const query = MysqlService.prepareQuery(i.query, i.fields);
|
137
138
|
promises.push(this.execute(query, i.rollbackQuery ?? null, i.transactionID ?? 0));
|
138
139
|
}
|
140
|
+
if (this.debug)
|
141
|
+
console.log("Execute queries: ", data);
|
139
142
|
return await Promise.all(promises);
|
140
143
|
};
|
141
144
|
exports.REQ_MYSQL_TBEGIN.listener = async () => {
|
@@ -143,12 +146,18 @@ class MysqlService extends BaseService_1.BaseService {
|
|
143
146
|
if (!conn)
|
144
147
|
return { code: "NO_POOL", errno: 100000, fatal: true, sql: "", name: "NO_POOL", message: "Mysql pool not created" };
|
145
148
|
const tid = MysqlService.nextTransactionID++;
|
149
|
+
if (this.debug)
|
150
|
+
console.log("Begin transaction with id ", tid);
|
146
151
|
try {
|
147
152
|
await conn.beginTransaction();
|
148
|
-
await conn.query("SET autocommit=0");
|
153
|
+
const res = await conn.query("SET autocommit=0");
|
154
|
+
if (this.debug)
|
155
|
+
console.log("Transaction started, SET autocommit=0 ", tid, res);
|
149
156
|
}
|
150
157
|
catch (e) {
|
151
158
|
try {
|
159
|
+
if (this.debug)
|
160
|
+
console.log("Transaction failed to start ", tid, e);
|
152
161
|
conn.removeAllListeners();
|
153
162
|
await conn.rollback();
|
154
163
|
conn.release();
|
@@ -162,6 +171,8 @@ class MysqlService extends BaseService_1.BaseService {
|
|
162
171
|
conn: conn,
|
163
172
|
queries: []
|
164
173
|
});
|
174
|
+
if (this.debug)
|
175
|
+
console.log("Transactions pool: ", this.transactions);
|
165
176
|
return tid;
|
166
177
|
};
|
167
178
|
exports.REQ_MYSQL_TQUERY.listener = async (data) => {
|
@@ -179,6 +190,8 @@ class MysqlService extends BaseService_1.BaseService {
|
|
179
190
|
let err = null;
|
180
191
|
let rollbackError = null;
|
181
192
|
let sqlData = null;
|
193
|
+
if (this.debug)
|
194
|
+
console.log("Execute query on transaction: ", trx);
|
182
195
|
try {
|
183
196
|
sqlData = await trx.conn.query(query);
|
184
197
|
}
|
@@ -197,6 +210,8 @@ class MysqlService extends BaseService_1.BaseService {
|
|
197
210
|
rollbackError = this.createMysqlQueryError(e);
|
198
211
|
}
|
199
212
|
}
|
213
|
+
if (this.debug)
|
214
|
+
console.log("Query execution status:", err ? err.message : "completed");
|
200
215
|
trx.queries.push({ sql: query, status: err ? err.message : "completed" });
|
201
216
|
return {
|
202
217
|
data: sqlData,
|
@@ -206,7 +221,7 @@ class MysqlService extends BaseService_1.BaseService {
|
|
206
221
|
};
|
207
222
|
exports.REQ_MYSQL_TROLLBACK.listener = async (tid) => {
|
208
223
|
const trx = this.transactions.find(i => i.id === tid);
|
209
|
-
if (!trx)
|
224
|
+
if (!trx) {
|
210
225
|
return {
|
211
226
|
code: "NO_TRX",
|
212
227
|
errno: 100004,
|
@@ -215,11 +230,19 @@ class MysqlService extends BaseService_1.BaseService {
|
|
215
230
|
name: "NO_TRX",
|
216
231
|
message: "Transaction not found"
|
217
232
|
};
|
233
|
+
}
|
234
|
+
if (this.debug)
|
235
|
+
console.log("Rollback transaction:", trx);
|
218
236
|
this.transactions = this.transactions.filter(i => i.id !== tid);
|
237
|
+
if (this.debug)
|
238
|
+
console.log("Transaction pool:", this.transactions);
|
219
239
|
try {
|
220
240
|
await trx.conn.rollback();
|
221
241
|
trx.conn.removeAllListeners();
|
222
242
|
trx.conn.release();
|
243
|
+
trx.conn.end();
|
244
|
+
if (this.debug)
|
245
|
+
console.log("Rollback complete");
|
223
246
|
}
|
224
247
|
catch (e) {
|
225
248
|
(0, LogService_1.logError)("Can't rollback transaction");
|
@@ -229,7 +252,7 @@ class MysqlService extends BaseService_1.BaseService {
|
|
229
252
|
};
|
230
253
|
exports.REQ_MYSQL_TCOMMIT.listener = async (tid) => {
|
231
254
|
const trx = this.transactions.find(i => i.id === tid);
|
232
|
-
if (!trx)
|
255
|
+
if (!trx) {
|
233
256
|
return {
|
234
257
|
code: "NO_TRX",
|
235
258
|
errno: 100004,
|
@@ -238,15 +261,24 @@ class MysqlService extends BaseService_1.BaseService {
|
|
238
261
|
name: "NO_TRX",
|
239
262
|
message: "Transaction not found"
|
240
263
|
};
|
264
|
+
}
|
265
|
+
if (this.debug)
|
266
|
+
console.log("Commit transaction:", trx);
|
241
267
|
this.transactions = this.transactions.filter(i => i.id !== tid);
|
268
|
+
if (this.debug)
|
269
|
+
console.log("Transaction pool:", this.transactions);
|
242
270
|
try {
|
243
271
|
await trx.conn.commit();
|
244
272
|
trx.conn.removeAllListeners();
|
245
273
|
trx.conn.release();
|
274
|
+
if (this.debug)
|
275
|
+
console.log("Commit completed:");
|
246
276
|
}
|
247
277
|
catch (e) {
|
248
278
|
this.storeTransactionAsProblem(trx, "Can't commit transaction");
|
249
279
|
try {
|
280
|
+
if (this.debug)
|
281
|
+
console.log("Commit error, try rollback");
|
250
282
|
trx.conn.removeAllListeners();
|
251
283
|
await trx.conn.rollback();
|
252
284
|
trx.conn.release();
|
@@ -262,6 +294,7 @@ class MysqlService extends BaseService_1.BaseService {
|
|
262
294
|
if (!this.pool)
|
263
295
|
return { error: { code: "NO_POOL", errno: 100000, fatal: true, sql: "", name: "NO_POOL", message: "Mysql pool not created" }, data: null };
|
264
296
|
const conn = await this.pool.getConnection();
|
297
|
+
(0, LogService_1.logCrit)("${MysqlService.js}", "REQ_MYSQL_TRANSACTION deprecated, use REQ_MYSQL_TBEGIN, REQ_MYSQL_TQUERY, REQ_MYSQL_TCOMMIT, REQ_MYSQL_TROLLBACK");
|
265
298
|
if (!conn)
|
266
299
|
return { error: { code: "NO_CONN", errno: 100001, fatal: true, sql: "", name: "NO_CONN", message: "Mysql pool cant get connection" }, data: null };
|
267
300
|
const trx = {
|
@@ -319,6 +352,7 @@ class MysqlService extends BaseService_1.BaseService {
|
|
319
352
|
};
|
320
353
|
}
|
321
354
|
async finishApp() {
|
355
|
+
console.log("Finishing mysql service");
|
322
356
|
for (let i of this.transactions) {
|
323
357
|
try {
|
324
358
|
this.storeTransactionAsProblem(i, "SIGINT");
|
@@ -362,9 +396,13 @@ class MysqlService extends BaseService_1.BaseService {
|
|
362
396
|
this.failReportFileStream = fs_1.default.createWriteStream(file, { flags: 'a' });
|
363
397
|
this.failReportFileStreamName = file;
|
364
398
|
}
|
399
|
+
if (this.debug)
|
400
|
+
console.log("Store transaction fail report: ", file, trx, message);
|
365
401
|
this.failReportFileStream?.write(JSON.stringify({ trx, date, message }) + "\n{'s':'&$5__1AzZa'}\n", err => {
|
366
402
|
if (err)
|
367
403
|
(0, LogService_1.logCrit)("${MysqlService.js}", "Can't write to transaction fail report file");
|
404
|
+
else
|
405
|
+
(0, LogService_1.logInfo)("${MysqlService.js}", "Transaction fail report stored");
|
368
406
|
});
|
369
407
|
this.failReportLastAccessTime = Date.now();
|
370
408
|
}
|
@@ -411,11 +449,14 @@ class MysqlService extends BaseService_1.BaseService {
|
|
411
449
|
this.pool?.on('enqueue', () => {
|
412
450
|
(0, LogService_1.logInfo)("${MysqlService.js}", "MYSQL CONNECTION ENQUEUED");
|
413
451
|
});
|
452
|
+
if (this.debug)
|
453
|
+
console.log("Check mysql connection");
|
414
454
|
return new Promise(async (resolve, reject) => {
|
415
455
|
try {
|
416
456
|
const conn = await this.pool?.getConnection();
|
417
457
|
if (conn) {
|
418
458
|
conn?.release();
|
459
|
+
(0, LogService_1.logInfo)("${MysqlService.js}", "Connected to MYSQL!");
|
419
460
|
resolve(true);
|
420
461
|
}
|
421
462
|
else
|
@@ -567,10 +608,14 @@ class MysqlService extends BaseService_1.BaseService {
|
|
567
608
|
let conn = null;
|
568
609
|
if (transactionID && transactionID > 0) {
|
569
610
|
conn = this.transactions.find(i => i.id === transactionID)?.conn ?? null;
|
611
|
+
if (this.debug)
|
612
|
+
console.log("Execute query on transaction: ", conn);
|
570
613
|
}
|
571
614
|
else {
|
572
615
|
conn = await this.pool.getConnection();
|
573
616
|
}
|
617
|
+
if (this.debug)
|
618
|
+
console.log("Execute query", conn);
|
574
619
|
if (!conn) {
|
575
620
|
(0, LogService_1.logCrit)("${MysqlService.js}", `No connection created!`);
|
576
621
|
resolve({
|