Fix hanging IORedis connections; add extollo.wontstop debugging helper
This commit is contained in:
parent
8f08b94f74
commit
cdecb7e628
@ -74,12 +74,14 @@
|
|||||||
"@types/chai": "^4.2.22",
|
"@types/chai": "^4.2.22",
|
||||||
"@types/mocha": "^9.0.0",
|
"@types/mocha": "^9.0.0",
|
||||||
"@types/sinon": "^10.0.6",
|
"@types/sinon": "^10.0.6",
|
||||||
|
"@types/wtfnode": "^0.7.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.26.0",
|
"@typescript-eslint/eslint-plugin": "^4.26.0",
|
||||||
"@typescript-eslint/parser": "^4.26.0",
|
"@typescript-eslint/parser": "^4.26.0",
|
||||||
"chai": "^4.3.4",
|
"chai": "^4.3.4",
|
||||||
"eslint": "^7.27.0",
|
"eslint": "^7.27.0",
|
||||||
"mocha": "^9.1.3",
|
"mocha": "^9.1.3",
|
||||||
"sinon": "^12.0.1"
|
"sinon": "^12.0.1",
|
||||||
|
"wtfnode": "^0.9.1"
|
||||||
},
|
},
|
||||||
"extollo": {
|
"extollo": {
|
||||||
"discover": true,
|
"discover": true,
|
||||||
|
@ -21,6 +21,7 @@ specifiers:
|
|||||||
'@types/sinon': ^10.0.6
|
'@types/sinon': ^10.0.6
|
||||||
'@types/ssh2': ^0.5.46
|
'@types/ssh2': ^0.5.46
|
||||||
'@types/uuid': ^8.3.0
|
'@types/uuid': ^8.3.0
|
||||||
|
'@types/wtfnode': ^0.7.0
|
||||||
'@typescript-eslint/eslint-plugin': ^4.26.0
|
'@typescript-eslint/eslint-plugin': ^4.26.0
|
||||||
'@typescript-eslint/parser': ^4.26.0
|
'@typescript-eslint/parser': ^4.26.0
|
||||||
bcrypt: ^5.0.1
|
bcrypt: ^5.0.1
|
||||||
@ -50,6 +51,7 @@ specifiers:
|
|||||||
typedoc-plugin-sourcefile-url: ^1.0.6
|
typedoc-plugin-sourcefile-url: ^1.0.6
|
||||||
typescript: ^4.2.3
|
typescript: ^4.2.3
|
||||||
uuid: ^8.3.2
|
uuid: ^8.3.2
|
||||||
|
wtfnode: ^0.9.1
|
||||||
zod: ^3.11.6
|
zod: ^3.11.6
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -99,12 +101,14 @@ devDependencies:
|
|||||||
'@types/chai': 4.2.22
|
'@types/chai': 4.2.22
|
||||||
'@types/mocha': 9.0.0
|
'@types/mocha': 9.0.0
|
||||||
'@types/sinon': 10.0.6
|
'@types/sinon': 10.0.6
|
||||||
|
'@types/wtfnode': 0.7.0
|
||||||
'@typescript-eslint/eslint-plugin': 4.26.0_942c48837be95e76bb4156c78358cdbe
|
'@typescript-eslint/eslint-plugin': 4.26.0_942c48837be95e76bb4156c78358cdbe
|
||||||
'@typescript-eslint/parser': 4.26.0_eslint@7.27.0+typescript@4.2.3
|
'@typescript-eslint/parser': 4.26.0_eslint@7.27.0+typescript@4.2.3
|
||||||
chai: 4.3.4
|
chai: 4.3.4
|
||||||
eslint: 7.27.0
|
eslint: 7.27.0
|
||||||
mocha: 9.1.3
|
mocha: 9.1.3
|
||||||
sinon: 12.0.1
|
sinon: 12.0.1
|
||||||
|
wtfnode: 0.9.1
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
@ -447,6 +451,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-0LbEEx1zxrYB3pgpd1M5lEhLcXjKJnYghvhTRgaBeUivLHMDM1TzF3IJ6hXU2+8uA4Xz+5BA63mtZo5DjVT8iA==}
|
resolution: {integrity: sha512-0LbEEx1zxrYB3pgpd1M5lEhLcXjKJnYghvhTRgaBeUivLHMDM1TzF3IJ6hXU2+8uA4Xz+5BA63mtZo5DjVT8iA==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@types/wtfnode/0.7.0:
|
||||||
|
resolution: {integrity: sha512-kdBHgE9+M1Os7UqWZtiLhKye5reFl8cPBYyCsP2fatwZRz7F7GdIxIHZ20Kkc0hYBfbXE+lzPOTUU1I0qgjtHA==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@typescript-eslint/eslint-plugin/4.26.0_942c48837be95e76bb4156c78358cdbe:
|
/@typescript-eslint/eslint-plugin/4.26.0_942c48837be95e76bb4156c78358cdbe:
|
||||||
resolution: {integrity: sha512-yA7IWp+5Qqf+TLbd8b35ySFOFzUfL7i+4If50EqvjT6w35X8Lv0eBHb6rATeWmucks37w+zV+tWnOXI9JlG6Eg==}
|
resolution: {integrity: sha512-yA7IWp+5Qqf+TLbd8b35ySFOFzUfL7i+4If50EqvjT6w35X8Lv0eBHb6rATeWmucks37w+zV+tWnOXI9JlG6Eg==}
|
||||||
engines: {node: ^10.12.0 || >=12.0.0}
|
engines: {node: ^10.12.0 || >=12.0.0}
|
||||||
@ -3112,6 +3120,11 @@ packages:
|
|||||||
/wrappy/1.0.2:
|
/wrappy/1.0.2:
|
||||||
resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=}
|
resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=}
|
||||||
|
|
||||||
|
/wtfnode/0.9.1:
|
||||||
|
resolution: {integrity: sha512-Ip6C2KeQPl/F3aP1EfOnPoQk14Udd9lffpoqWDNH3Xt78svxPbv53ngtmtfI0q2Te3oTq79XKTnRNXVIn/GsPA==}
|
||||||
|
hasBin: true
|
||||||
|
dev: true
|
||||||
|
|
||||||
/xtend/4.0.2:
|
/xtend/4.0.2:
|
||||||
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
|
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
|
||||||
engines: {node: '>=0.4'}
|
engines: {node: '>=0.4'}
|
||||||
|
@ -8,13 +8,14 @@ import {
|
|||||||
StandardLogger,
|
StandardLogger,
|
||||||
universalPath,
|
universalPath,
|
||||||
UniversalPath,
|
UniversalPath,
|
||||||
|
FileLogger,
|
||||||
|
ifDebugging,
|
||||||
} from '../util'
|
} from '../util'
|
||||||
import {Logging} from '../service/Logging'
|
import {Logging} from '../service/Logging'
|
||||||
import {RunLevelErrorHandler} from './RunLevelErrorHandler'
|
import {RunLevelErrorHandler} from './RunLevelErrorHandler'
|
||||||
import {Unit, UnitStatus} from './Unit'
|
import {Unit, UnitStatus} from './Unit'
|
||||||
import * as dotenv from 'dotenv'
|
import * as dotenv from 'dotenv'
|
||||||
import {CacheFactory} from '../support/cache/CacheFactory'
|
import {CacheFactory} from '../support/cache/CacheFactory'
|
||||||
import {FileLogger} from '../util/logging/FileLogger'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function that resolves and infers environment variable values.
|
* Helper function that resolves and infers environment variable values.
|
||||||
@ -260,6 +261,13 @@ export class Application extends Container {
|
|||||||
async run(): Promise<void> {
|
async run(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await this.up()
|
await this.up()
|
||||||
|
|
||||||
|
ifDebugging('extollo.wontstop', () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
import('wtfnode').then(wtf => wtf.dump())
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
|
||||||
await this.down()
|
await this.down()
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
if ( e instanceof Error ) {
|
if ( e instanceof Error ) {
|
||||||
|
@ -121,7 +121,8 @@ export class RedisBus implements EventBus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
down(): Awaitable<void> {
|
down(): Awaitable<void> {
|
||||||
this.subscriberConnection?.disconnect()
|
// The Redis service will clean up the connections when the framework exits,
|
||||||
this.publisherConnection?.disconnect()
|
// so we don't need to do anything here.
|
||||||
|
return undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import * as IORedis from 'ioredis'
|
|||||||
import {RedisOptions} from 'ioredis'
|
import {RedisOptions} from 'ioredis'
|
||||||
import {Logging} from '../../service/Logging'
|
import {Logging} from '../../service/Logging'
|
||||||
import {Unit} from '../../lifecycle/Unit'
|
import {Unit} from '../../lifecycle/Unit'
|
||||||
import {AsyncPipe} from '../../util'
|
import {AsyncPipe, Collection} from '../../util'
|
||||||
|
|
||||||
export {RedisOptions} from 'ioredis'
|
export {RedisOptions} from 'ioredis'
|
||||||
|
|
||||||
@ -28,19 +28,25 @@ export class Redis extends Unit {
|
|||||||
*/
|
*/
|
||||||
private connection?: IORedis.Redis
|
private connection?: IORedis.Redis
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collection of all Redis connections opened by this service.
|
||||||
|
* We keep track of these here so we can make sure -all- of them get closed
|
||||||
|
* when the framework tries to shut down.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
private spawnedConnections: Collection<IORedis.Redis> = new Collection()
|
||||||
|
|
||||||
async up(): Promise<void> {
|
async up(): Promise<void> {
|
||||||
this.logging.info('Attempting initial connection to Redis...')
|
this.logging.info('Attempting initial connection to Redis...')
|
||||||
this.logging.debug('Config:')
|
|
||||||
this.logging.debug(Config)
|
|
||||||
this.logging.debug(this.config)
|
this.logging.debug(this.config)
|
||||||
await this.getConnection()
|
await this.getConnection()
|
||||||
}
|
}
|
||||||
|
|
||||||
async down(): Promise<void> {
|
async down(): Promise<void> {
|
||||||
this.logging.info('Disconnecting Redis...')
|
this.logging.info('Disconnecting Redis...')
|
||||||
if ( this.connection?.status === 'ready' ) {
|
await this.spawnedConnections
|
||||||
await this.connection.disconnect()
|
.where('status', '=', 'ready')
|
||||||
}
|
.awaitMapCall('disconnect')
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,7 +65,9 @@ export class Redis extends Unit {
|
|||||||
*/
|
*/
|
||||||
public async getNewConnection(): Promise<IORedis.Redis> {
|
public async getNewConnection(): Promise<IORedis.Redis> {
|
||||||
const options = this.config.get('redis.connection') as RedisOptions
|
const options = this.config.get('redis.connection') as RedisOptions
|
||||||
return new IORedis(options)
|
const inst = new IORedis(options)
|
||||||
|
this.spawnedConnections.push(inst)
|
||||||
|
return inst
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user