@mojaloop/database-lib 11.1.4-snapshot.1 → 11.1.4

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/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [11.1.4](https://github.com/mojaloop/database-lib/compare/v11.1.3...v11.1.4) (2025-03-13)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * process termination handling ([#169](https://github.com/mojaloop/database-lib/issues/169)) ([d0de3e1](https://github.com/mojaloop/database-lib/commit/d0de3e1924ee36ddd5018054140d2962a2353892))
11
+
5
12
  ### [11.1.3](https://github.com/mojaloop/database-lib/compare/v11.1.2...v11.1.3) (2025-02-21)
6
13
 
7
14
  ### [11.1.2](https://github.com/mojaloop/database-lib/compare/v11.1.1...v11.1.2) (2025-01-27)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mojaloop/database-lib",
3
- "version": "11.1.4-snapshot.1",
3
+ "version": "11.1.4",
4
4
  "description": "Shared database code for central services",
5
5
  "main": "src/index.js",
6
6
  "license": "Apache-2.0",
@@ -44,6 +44,7 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "@mojaloop/central-services-error-handling": "13.0.7",
47
+ "async-exit-hook": "^2.0.1",
47
48
  "knex": "3.1.0",
48
49
  "lodash": "4.17.21",
49
50
  "mysql": "2.18.1"
package/src/database.js CHANGED
@@ -4,6 +4,7 @@ const Knex = require('knex')
4
4
  const ErrorHandler = require('@mojaloop/central-services-error-handling')
5
5
  const Table = require('./table')
6
6
  const Utils = require('./utils.js')
7
+ const exitHook = require('async-exit-hook')
7
8
 
8
9
  /* Default config to fall back to when using deprecated URI connection string */
9
10
  const defaultConfig = {
@@ -29,7 +30,6 @@ class Database {
29
30
  this._knex = null
30
31
  this._tables = []
31
32
  this._schema = null
32
- this._signalHandlersRegistered = false // Track if signal handlers are already registered
33
33
 
34
34
  this._listTableQueries = {
35
35
  mysql: (knex) => {
@@ -80,26 +80,17 @@ class Database {
80
80
  this._tables = await this._listTables()
81
81
  await this._setTableProperties()
82
82
 
83
- // Register signal handlers only once
84
- if (!this._signalHandlersRegistered) {
85
- process.on('SIGINT', async () => {
86
- await this._handleShutdown('SIGINT')
87
- })
88
- process.on('SIGTERM', async () => {
89
- await this._handleShutdown('SIGTERM')
90
- })
91
- this._signalHandlersRegistered = true
92
- }
83
+ exitHook(callback => {
84
+ this.disconnect().finally(callback)
85
+ })
93
86
  }
94
87
 
95
88
  async disconnect () {
96
89
  if (this._knex) {
97
- console.log('Closing database connection...')
98
90
  this._removeTableProperties()
99
91
  this._tables = []
100
92
  await this._knex.destroy()
101
93
  this._knex = null
102
- console.log('Database connection closed.')
103
94
  }
104
95
  }
105
96
 
@@ -149,13 +140,6 @@ class Database {
149
140
  }
150
141
  return this._knex.client.pool.numPendingAcquires()
151
142
  }
152
-
153
- async _handleShutdown (signal) {
154
- console.log(`Received ${signal}, shutting down database...`)
155
- await this.disconnect()
156
- console.log('Cleanup complete. Exiting process.')
157
- process.exit(0)
158
- }
159
143
  }
160
144
 
161
145
  const configureKnex = async ({ maxPendingAcquire, ...config }) => {
@@ -13,6 +13,7 @@ Test('database', databaseTest => {
13
13
  let knexConnStub
14
14
  let Database
15
15
  let dbInstance
16
+ let exitHookStub
16
17
 
17
18
  const connectionConfig = {
18
19
  client: 'mysql',
@@ -52,6 +53,8 @@ Test('database', databaseTest => {
52
53
  databaseTest.beforeEach(t => {
53
54
  sandbox = Sinon.createSandbox()
54
55
 
56
+ exitHookStub = sandbox.stub()
57
+
55
58
  knexConnStub = sandbox.stub()
56
59
  knexConnStub.destroy = sandbox.stub()
57
60
  knexConnStub.client = { config: { client: 'mysql' }, pool: { numPendingAcquires () {} } }
@@ -62,7 +65,7 @@ Test('database', databaseTest => {
62
65
 
63
66
  tableStub = sandbox.stub()
64
67
 
65
- Database = Proxyquire(`${src}/database`, { knex: knexStub, './table': tableStub })
68
+ Database = Proxyquire(`${src}/database`, { knex: knexStub, './table': tableStub, 'async-exit-hook': exitHookStub })
66
69
  dbInstance = new Database()
67
70
 
68
71
  t.end()
@@ -383,50 +386,34 @@ Test('database', databaseTest => {
383
386
  })
384
387
 
385
388
  databaseTest.test('connect should', connectTest => {
386
- connectTest.test('register signal handlers only once', async test => {
387
- const processOnStub = sandbox.stub(process, 'on')
388
-
389
- await dbInstance.connect(connectionConfig)
390
- await dbInstance.connect(connectionConfig)
391
-
392
- test.ok(processOnStub.calledTwice)
393
- test.ok(processOnStub.calledWith('SIGINT'))
394
- test.ok(processOnStub.calledWith('SIGTERM'))
395
- test.equal(dbInstance._signalHandlersRegistered, true)
396
-
397
- processOnStub.restore()
398
- test.end()
399
- })
400
-
401
- connectTest.test('handle SIGINT signal', async test => {
402
- const processOnStub = sandbox.stub(process, 'on')
403
- const handleShutdownStub = sandbox.stub(dbInstance, '_handleShutdown')
404
-
389
+ connectTest.test('register exit hook', async test => {
390
+ // Act
405
391
  await dbInstance.connect(connectionConfig)
406
- const sigintHandler = processOnStub.firstCall.args[1]
407
392
 
408
- await sigintHandler()
409
-
410
- test.ok(handleShutdownStub.calledOnceWith('SIGINT'))
393
+ // Assert
394
+ test.ok(exitHookStub.calledOnce)
395
+ test.ok(exitHookStub.calledWith(Sinon.match.func))
411
396
 
412
- processOnStub.restore()
413
- handleShutdownStub.restore()
397
+ // Cleanup
414
398
  test.end()
415
399
  })
416
400
 
417
- connectTest.test('handle SIGTERM signal', async test => {
418
- const processOnStub = sandbox.stub(process, 'on')
419
- const handleShutdownStub = sandbox.stub(dbInstance, '_handleShutdown')
420
-
401
+ connectTest.test('call disconnect on process exit', async test => {
402
+ // Arrange
403
+ // Simulate process exit by manually calling the registered function
421
404
  await dbInstance.connect(connectionConfig)
422
- const sigtermHandler = processOnStub.secondCall.args[1]
405
+ const exitCallback = exitHookStub.firstCall.args[0] // Get the first function registered
406
+ const disconnectStub = sandbox.stub(dbInstance, 'disconnect').resolves()
423
407
 
424
- await sigtermHandler()
408
+ // Act
409
+ exitCallback() // Simulate process exit
425
410
 
426
- test.ok(handleShutdownStub.calledOnceWith('SIGTERM'))
411
+ // Assert
412
+ test.ok(exitHookStub.calledOnce)
413
+ test.ok(disconnectStub.calledOnce)
427
414
 
428
- processOnStub.restore()
429
- handleShutdownStub.restore()
415
+ // Cleanup
416
+ disconnectStub.restore()
430
417
  test.end()
431
418
  })
432
419