badmfck-api-server 2.2.1 → 2.2.2
Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,8 @@
|
|
1
|
+
/// <reference types="node" />
|
1
2
|
import { BaseService } from "./BaseService";
|
2
3
|
import Signal, { Req } from "badmfck-signal";
|
3
4
|
import * as mysql from "mysql2/promise";
|
5
|
+
import fs from "fs";
|
4
6
|
export declare const S_MYSQL_STARTED: Signal<void>;
|
5
7
|
export declare const REQ_MYSQL_QUERY: Req<MySqlQuery | MySqlQuery[], MysqlResult[]>;
|
6
8
|
export declare const REQ_MYSQL_TRANSACTION: Req<MySqlQuery[], MysqlResult>;
|
@@ -82,6 +84,9 @@ export declare class MysqlService extends BaseService {
|
|
82
84
|
static nextTransactionID: number;
|
83
85
|
transactions: ITransaction[];
|
84
86
|
maxTransactionWaitTime: number;
|
87
|
+
failReportFileStream: fs.WriteStream | null;
|
88
|
+
failReportFileStreamName: string | null;
|
89
|
+
failReportLastAccessTime: number;
|
85
90
|
constructor(options: MysqlServiceOptions);
|
86
91
|
static executeQuery(query: MySqlQuery | MySqlQuery[]): Promise<MysqlResult[]>;
|
87
92
|
init(): Promise<void>;
|
@@ -22,6 +22,9 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
22
22
|
__setModuleDefault(result, mod);
|
23
23
|
return result;
|
24
24
|
};
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
27
|
+
};
|
25
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
26
29
|
exports.MysqlService = exports.executeQuery = exports.REQ_MYSQL_TEND = exports.REQ_MYSQL_TQUERY = exports.REQ_MYSQL_TBEGIN = exports.REQ_MYSQL_TRANSACTION = exports.REQ_MYSQL_QUERY = exports.S_MYSQL_STARTED = void 0;
|
27
30
|
const BaseService_1 = require("./BaseService");
|
@@ -29,6 +32,8 @@ const badmfck_signal_1 = __importStar(require("badmfck-signal"));
|
|
29
32
|
const crypto_1 = require("crypto");
|
30
33
|
const LogService_1 = require("./LogService");
|
31
34
|
const mysql = __importStar(require("mysql2/promise"));
|
35
|
+
const fs_1 = __importDefault(require("fs"));
|
36
|
+
const path_1 = __importDefault(require("path"));
|
32
37
|
exports.S_MYSQL_STARTED = new badmfck_signal_1.default();
|
33
38
|
exports.REQ_MYSQL_QUERY = new badmfck_signal_1.Req(undefined, "REQ_MYSQL_QUERY");
|
34
39
|
exports.REQ_MYSQL_TRANSACTION = new badmfck_signal_1.Req(undefined, "REQ_MYSQL_TRANSACTION");
|
@@ -48,6 +53,9 @@ class MysqlService extends BaseService_1.BaseService {
|
|
48
53
|
static nextTransactionID = 0;
|
49
54
|
transactions = [];
|
50
55
|
maxTransactionWaitTime = 1000 * 60 * 2;
|
56
|
+
failReportFileStream = null;
|
57
|
+
failReportFileStreamName = null;
|
58
|
+
failReportLastAccessTime = 0;
|
51
59
|
constructor(options) {
|
52
60
|
super("mysql");
|
53
61
|
this.options = options;
|
@@ -76,11 +84,18 @@ class MysqlService extends BaseService_1.BaseService {
|
|
76
84
|
return false;
|
77
85
|
});
|
78
86
|
}, 1000 * 30);
|
87
|
+
setInterval(() => {
|
88
|
+
if (!this.failReportFileStream)
|
89
|
+
return;
|
90
|
+
if (Date.now() - this.failReportLastAccessTime > 1000 * 60 * 15) {
|
91
|
+
this.failReportFileStream.end();
|
92
|
+
this.failReportFileStream = null;
|
93
|
+
}
|
94
|
+
}, 1000 * 60 * 5);
|
79
95
|
if (options.transactionFailReportDir) {
|
80
|
-
const fs = require('fs');
|
81
96
|
try {
|
82
|
-
if (!
|
83
|
-
|
97
|
+
if (!fs_1.default.existsSync(options.transactionFailReportDir)) {
|
98
|
+
fs_1.default.mkdirSync(options.transactionFailReportDir);
|
84
99
|
}
|
85
100
|
}
|
86
101
|
catch (e) {
|
@@ -225,40 +240,46 @@ class MysqlService extends BaseService_1.BaseService {
|
|
225
240
|
try {
|
226
241
|
await conn.beginTransaction();
|
227
242
|
await conn.query("SET autocommit=0");
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
}
|
238
|
-
trx.queries.push({
|
239
|
-
sql: query,
|
240
|
-
status: err ? err.message : "completed"
|
241
|
-
});
|
242
|
-
if (err)
|
243
|
-
return { error: err, data: null };
|
244
|
-
}
|
243
|
+
}
|
244
|
+
catch (e) {
|
245
|
+
const err = this.createMysqlQueryError(e);
|
246
|
+
this.storeTransactionAsProblem(trx, err.message);
|
247
|
+
return { error: err, data: null };
|
248
|
+
}
|
249
|
+
for (let i of data) {
|
250
|
+
const query = MysqlService.prepareQuery(i.query, i.fields);
|
251
|
+
let err = null;
|
245
252
|
try {
|
246
|
-
await conn.
|
253
|
+
const d = await conn.query(query);
|
254
|
+
income.push(d[0]);
|
247
255
|
}
|
248
256
|
catch (e) {
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
return { error:
|
257
|
+
err = this.createMysqlQueryError(e);
|
258
|
+
}
|
259
|
+
trx.queries.push({
|
260
|
+
sql: query,
|
261
|
+
status: err ? err.message : "completed"
|
262
|
+
});
|
263
|
+
if (err) {
|
264
|
+
this.storeTransactionAsProblem(trx, err.message);
|
265
|
+
return { error: err, data: null };
|
258
266
|
}
|
259
267
|
}
|
268
|
+
try {
|
269
|
+
await conn.commit();
|
270
|
+
}
|
260
271
|
catch (e) {
|
261
|
-
|
272
|
+
let rollbackError = null;
|
273
|
+
try {
|
274
|
+
await conn.rollback();
|
275
|
+
}
|
276
|
+
catch (e2) {
|
277
|
+
(0, LogService_1.logCrit)("${MysqlService.js}", "Can't rollback transaction!");
|
278
|
+
rollbackError = this.createMysqlQueryError(e2);
|
279
|
+
}
|
280
|
+
const err = this.createMysqlQueryError(e);
|
281
|
+
this.storeTransactionAsProblem(trx, err.message);
|
282
|
+
return { error: err, data: null, rollbackError: rollbackError };
|
262
283
|
}
|
263
284
|
return { error: null, data: income };
|
264
285
|
};
|
@@ -283,13 +304,37 @@ class MysqlService extends BaseService_1.BaseService {
|
|
283
304
|
(0, LogService_1.logCrit)("${MysqlService.js}", "Can't close MYSQL pool!");
|
284
305
|
}
|
285
306
|
}
|
307
|
+
if (this.failReportFileStream)
|
308
|
+
this.failReportFileStream.end();
|
309
|
+
this.failReportFileStream = null;
|
286
310
|
}
|
287
311
|
async storeTransactionAsProblem(trx, message) {
|
288
|
-
if (!this.options.transactionFailReport) {
|
289
|
-
(0, LogService_1.logCrit)("${MysqlService.js}", "Can't report failed transaction, no report function: transactionFailReport in options");
|
312
|
+
if (!this.options.transactionFailReport && !this.options.transactionFailReportDir) {
|
313
|
+
(0, LogService_1.logCrit)("${MysqlService.js}", "Can't report failed transaction, no report function: transactionFailReport in options, and transactionFailReportDir isnt set");
|
290
314
|
return;
|
291
315
|
}
|
292
|
-
this.options.
|
316
|
+
if (this.options.transactionFailReportDir) {
|
317
|
+
const yyymmdd = new Date().toISOString().substring(0, 10).replaceAll("-", "");
|
318
|
+
const date = new Date();
|
319
|
+
const file = path_1.default.resolve(this.options.transactionFailReportDir, yyymmdd + ".json");
|
320
|
+
if (this.failReportFileStream) {
|
321
|
+
if (this.failReportFileStreamName !== file) {
|
322
|
+
this.failReportFileStream.end();
|
323
|
+
this.failReportFileStream = null;
|
324
|
+
}
|
325
|
+
}
|
326
|
+
if (this.failReportFileStreamName) {
|
327
|
+
this.failReportFileStream = fs_1.default.createWriteStream(file, { flags: 'a' });
|
328
|
+
this.failReportFileStreamName = file;
|
329
|
+
}
|
330
|
+
this.failReportFileStream?.write(JSON.stringify({ trx, date, message }) + "\n{'s':'&$5__1AzZa'}\n", err => {
|
331
|
+
if (err)
|
332
|
+
(0, LogService_1.logCrit)("${MysqlService.js}", "Can't write to transaction fail report file");
|
333
|
+
});
|
334
|
+
this.failReportLastAccessTime = Date.now();
|
335
|
+
}
|
336
|
+
if (this.options.transactionFailReport)
|
337
|
+
this.options.transactionFailReport(trx, message);
|
293
338
|
}
|
294
339
|
async recreatePool() {
|
295
340
|
(0, LogService_1.logInfo)("${MysqlService.js}", "Connecting to mysql: \n HOST: " + this.options.host + '\n PORT:' + this.options.port);
|