Skip to content

Commit 123307c

Browse files
committed
ensure max listener count before adding listeners
1 parent db3e060 commit 123307c

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

lib/lifecycle-handler.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class LifecycleHandler {
2121

2222
this.server = server
2323
this.logger = logger
24+
this.isStopping = null
2425
this.preShutdown = preShutdown
2526
this.preServerStop = preServerStop
2627
this.postServerStop = postServerStop
@@ -44,10 +45,27 @@ class LifecycleHandler {
4445
*/
4546
addListeners () {
4647
this.signals.forEach(signal => {
48+
this.ensureMaxListenerCountFor(signal)
4749
process.on(signal, this.shutdownListener)
4850
})
4951
}
5052

53+
/**
54+
* Ensures that registering the event listener
55+
* for hapi-pulse won’t exceed the max
56+
* listener count.
57+
*
58+
* @param {String} event
59+
*/
60+
ensureMaxListenerCountFor (event) {
61+
const maxListeners = process.getMaxListeners()
62+
const listenerCount = process.listenerCount(event)
63+
64+
if (listenerCount >= maxListeners) {
65+
process.setMaxListeners(maxListeners + 1)
66+
}
67+
}
68+
5169
/**
5270
* Remove all shutdown listeners.
5371
*/
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
'use strict'
2+
3+
const Lab = require('lab')
4+
const Code = require('code')
5+
const Hapi = require('hapi')
6+
const Hoek = require('hoek')
7+
const Sinon = require('sinon')
8+
9+
const { describe, it, beforeEach, afterEach } = (exports.lab = Lab.script())
10+
11+
describe('server stop with custom signals:', () => {
12+
beforeEach(async () => {
13+
// stub process.exit to keep the Node.js process alive while running the tests
14+
// else it would actually EXIT the process
15+
Sinon.stub(process, 'exit')
16+
})
17+
18+
afterEach(() => {
19+
process.exit.restore()
20+
})
21+
22+
it('increases the max listeners count for the given signals', async () => {
23+
process.setMaxListeners(1)
24+
25+
const server = new Hapi.Server()
26+
await server.register({
27+
plugin: require('../lib'),
28+
options: {
29+
signals: ['HAPIPULSE', 'HAPIPULSE']
30+
}
31+
})
32+
33+
Code.expect(process.getMaxListeners()).to.equal(2)
34+
35+
await server.start()
36+
37+
Code.expect(process.getMaxListeners()).to.equal(2)
38+
Code.expect(process.listenerCount('HAPIPULSE')).to.equal(2)
39+
40+
// a stopped hapi server has a "started" timestamp of 0
41+
Code.expect(server.info.started).to.not.equal(0)
42+
43+
process.emit('HAPIPULSE')
44+
45+
// wait for the server to stop
46+
await Hoek.wait(100)
47+
48+
Sinon.assert.called(process.exit)
49+
50+
// a stopped hapi server has a "started" timestamp of 0
51+
Code.expect(server.info.started).to.equal(0)
52+
})
53+
})

0 commit comments

Comments
 (0)