badmfck-api-server 3.6.7 → 3.6.8

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.
@@ -95,7 +95,7 @@ async function Initializer(services) {
95
95
  exports.Initializer = Initializer;
96
96
  class APIService extends BaseService_1.BaseService {
97
97
  static nextLogID = 0;
98
- version = "3.6.7";
98
+ version = "3.6.8";
99
99
  options;
100
100
  monitor = null;
101
101
  started = new Date();
@@ -68,7 +68,8 @@ export interface DBAdapterOptions {
68
68
  queueLimit?: number;
69
69
  transactionFailReport?: (trx: any, message: string) => void;
70
70
  transactionFailReportDir?: string;
71
- naxTransactionWaitTime?: number;
71
+ maxTransactionWaitTime?: number;
72
+ maxQueryTimeout?: number;
72
73
  debug?: boolean;
73
74
  }
74
75
  type ILongQuery = {
@@ -70,7 +70,7 @@ class DBService extends BaseService_1.BaseService {
70
70
  longQueries: this.longQueries
71
71
  }
72
72
  });
73
- }, 1000 * 60 * 60);
73
+ }, 1000 * 60 * 1);
74
74
  }
75
75
  async init() {
76
76
  super.init();
@@ -44,6 +44,7 @@ export declare class MysqlAdapter implements IDBAdapter {
44
44
  tRollback(trxid: number): Promise<IDBResult>;
45
45
  bulk(request: IDBBulkQuery): Promise<IDBResult[]>;
46
46
  getConnection(transactionId?: number): Promise<mysql.PoolConnection | IDBError>;
47
+ withTimeout<T>(promise: Promise<T>, ms: number, query: string): Promise<T>;
47
48
  query(request: IDBQuery, conn?: mysql.PoolConnection): Promise<IDBResult>;
48
49
  finalizeConnection(conn: mysql.PoolConnection): void;
49
50
  prepareQuery(request: IDBQuery): string;
@@ -326,15 +326,15 @@ class MysqlAdapter {
326
326
  throwable: i.throwable,
327
327
  }));
328
328
  }
329
- if (conn) {
330
- this.finalizeConnection(conn);
331
- conn = null;
332
- }
333
329
  if (queries && queries.length > 0) {
334
330
  const responses = await Promise.all(queries);
335
331
  for (let i of responses)
336
332
  results.push(i);
337
333
  }
334
+ if (conn) {
335
+ this.finalizeConnection(conn);
336
+ conn = null;
337
+ }
338
338
  return results;
339
339
  }
340
340
  async getConnection(transactionId) {
@@ -368,8 +368,10 @@ class MysqlAdapter {
368
368
  return conn;
369
369
  }
370
370
  catch (e) {
371
- if (`${e}`.indexOf('ECONNREFUSED') !== -1)
371
+ if (`${e}`.indexOf('ECONNREFUSED') !== -1 || `${e}`.indexOf("PROTOCOL_") !== -1 || `${e}`.includes("closed state")) {
372
+ (0, LogService_1.logError)("Connection looks dead, recreating pool 2");
372
373
  this.recreatePool();
374
+ }
373
375
  }
374
376
  (0, LogService_1.logCrit)("${MysqlAdapter.js}", `No connection created!`);
375
377
  return {
@@ -382,6 +384,27 @@ class MysqlAdapter {
382
384
  isDuplicateError: false
383
385
  };
384
386
  }
387
+ withTimeout(promise, ms, query) {
388
+ return new Promise((resolve, reject) => {
389
+ const timeout = setTimeout(() => {
390
+ reject({
391
+ code: "TIME_OUT",
392
+ errno: 100013,
393
+ sql: query,
394
+ name: "TIME_OUT",
395
+ fatal: true,
396
+ message: "Query timeout reached " + ms
397
+ });
398
+ }, ms);
399
+ promise.then((res) => {
400
+ clearTimeout(timeout);
401
+ resolve(res);
402
+ }).catch((err) => {
403
+ clearTimeout(timeout);
404
+ reject(err);
405
+ });
406
+ });
407
+ }
385
408
  async query(request, conn) {
386
409
  let executionStartTime = Date.now();
387
410
  const query = this.prepareQuery(request);
@@ -390,6 +413,8 @@ class MysqlAdapter {
390
413
  (0, LogService_1.logDB)(query);
391
414
  }
392
415
  if (request.parseQueryOnly) {
416
+ if (conn && !request.transactionID)
417
+ this.finalizeConnection(conn);
393
418
  return {
394
419
  data: [{ query }],
395
420
  error: null,
@@ -415,7 +440,11 @@ class MysqlAdapter {
415
440
  }
416
441
  }
417
442
  try {
418
- const result = await conn.query(query);
443
+ let result = null;
444
+ if (this.options.maxQueryTimeout && this.options.maxQueryTimeout > 0)
445
+ result = await this.withTimeout(conn.query(query), this.options.maxQueryTimeout ?? 1000 * 25, query);
446
+ else
447
+ result = await conn.query(query);
419
448
  this.lastSuccessQueryTime = +new Date();
420
449
  if (!request.transactionID && doCloseConnection)
421
450
  this.finalizeConnection(conn);
@@ -440,8 +469,10 @@ class MysqlAdapter {
440
469
  this.finalizeConnection(conn);
441
470
  }
442
471
  const error = this.createMysqlQueryError(e);
443
- if (`${e}`.indexOf('ECONNREFUSED') !== -1)
472
+ if (`${e}`.indexOf('ECONNREFUSED') !== -1 || `${e}`.indexOf("PROTOCOL_") !== -1 || error.message.includes("closed state")) {
473
+ (0, LogService_1.logError)("Connection looks dead, recreating pool 1");
444
474
  this.recreatePool();
475
+ }
445
476
  if (request.throwable)
446
477
  throw { ...DefaultErrors_1.default.DB_ERROR, details: error.message, stack: error };
447
478
  return {
@@ -456,8 +487,8 @@ class MysqlAdapter {
456
487
  }
457
488
  finalizeConnection(conn) {
458
489
  try {
459
- conn.release();
460
490
  conn.removeAllListeners();
491
+ conn.release();
461
492
  if (this.options.debug)
462
493
  (0, LogService_1.logDB)("Release connection: ", conn.threadId);
463
494
  }
@@ -636,7 +667,7 @@ class MysqlAdapter {
636
667
  sql: err.sql,
637
668
  name: err.name,
638
669
  message: err.message,
639
- fatal: false,
670
+ fatal: err.fatal && typeof err.fatal === "boolean" ? err.fatal : false,
640
671
  isDuplicateError: err.code.toLowerCase().indexOf("dup_entry") !== -1
641
672
  };
642
673
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "badmfck-api-server",
3
- "version": "3.6.7",
3
+ "version": "3.6.8",
4
4
  "description": "Simple API http server based on express",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",