Skip to content

Commit

Permalink
Avoid deadlocks when using then and returning self.
Browse files Browse the repository at this point in the history
Fixes #94
  • Loading branch information
mcollina committed Feb 17, 2020
1 parent 8e11e0e commit ca09364
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 3 deletions.
14 changes: 11 additions & 3 deletions boot.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const inherits = require('util').inherits
const TimeTree = require('./time-tree')
const Plugin = require('./plugin')
const debug = require('debug')('avvio')
const kAvvio = Symbol('kAvvio')

function wrap (server, opts, instance) {
const expose = opts.expose || {}
Expand Down Expand Up @@ -33,6 +34,7 @@ function wrap (server, opts, instance) {
}

Object.defineProperty(server, 'then', { get: thenify.bind(instance) })
server[kAvvio] = true

server[afterKey] = function (func) {
if (typeof func !== 'function') {
Expand Down Expand Up @@ -188,6 +190,8 @@ function assertPlugin (plugin) {
}
}

Boot.prototype[kAvvio] = true

// load a plugin
Boot.prototype.use = function (plugin, opts) {
this._lastUsed = this._addPlugin(plugin, opts, false)
Expand Down Expand Up @@ -344,7 +348,11 @@ function thenify () {
// await server.ready() as ready() resolves
// with the server, end we will end up here
// because of automatic promise chaining.
if (this.booted) return
if (this.booted) {
debug('thenify returning null because we are already booted')
return
}
debug('thenify')
const p = this._loadRegistered()
return p.then.bind(p)
}
Expand All @@ -359,14 +367,14 @@ function callWithCbOrNextTick (func, cb, context) {
if (func.length === 0) {
this._error = err
res = func()
if (res && typeof res.then === 'function') {
if (res && !res[kAvvio] && typeof res.then === 'function') {
res.then(() => process.nextTick(cb), (e) => process.nextTick(cb, e))
} else {
process.nextTick(cb)
}
} else if (func.length === 1) {
res = func(err)
if (res && typeof res.then === 'function') {
if (res && !res[kAvvio] && typeof res.then === 'function') {
res.then(() => process.nextTick(cb), (e) => process.nextTick(cb, e))
} else {
process.nextTick(cb)
Expand Down
34 changes: 34 additions & 0 deletions test/after-and-ready.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -753,3 +753,37 @@ test('preReady event (errored)', (t) => {
t.is(order.shift(), 3)
})
})

test('after return self', (t) => {
t.plan(6)

const app = boot()
let pluginLoaded = false
let afterCalled = false
let second = false

app.use(function (s, opts, done) {
t.notOk(afterCalled, 'after not called')
pluginLoaded = true
done()
})

app.after(function () {
t.ok(pluginLoaded, 'afterred!')
afterCalled = true
// happens with after(() => app.use(..))
return app
})

app.use(function (s, opts, done) {
t.ok(afterCalled, 'after called')
second = true
done()
})

app.on('start', () => {
t.ok(afterCalled, 'after called')
t.ok(pluginLoaded, 'plugin loaded')
t.ok(second, 'second plugin loaded')
})
})

0 comments on commit ca09364

Please sign in to comment.