Skip to content

Commit

Permalink
Merge branch 'master' into await-ready
Browse files Browse the repository at this point in the history
  • Loading branch information
mcollina authored Dec 20, 2017
2 parents a70fbcd + a838e70 commit a1668fc
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 26 deletions.
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ async function third (instance, opts) {
* <a href="#use"><code>instance.<b>use()</b></code></a>
* <a href="#after"><code>instance.<b>after()</b></code></a>
* <a href="#ready"><code>instance.<b>ready()</b></code></a>
* <a href="#start"><code>instance.<b>start()</b></code></a>
* <a href="#override"><code>instance.<b>override()</b></code></a>
* <a href="#onClose"><code>instance.<b>onClose()</b></code></a>
* <a href="#close"><code>instance.<b>close()</b></code></a>
Expand All @@ -81,7 +82,7 @@ async function third (instance, opts) {
-------------------------------------------------------
<a name="constructor"></a>

### avvio([instance], [started])
### avvio([instance], [options], [started])

Starts the avvio sequence.
As the name suggest, `instance` is the object representing your application.
Expand All @@ -107,6 +108,9 @@ server.use(function first (s, opts, cb) {
Options:

* `expose`: a key/value property to change how `use`, `after` and `ready` are exposed.
* `autostart`: do not start loading plugins automatically, but wait for
a call to [`.start()`](#start)  or [`.ready()`](#ready).


Events:

Expand Down Expand Up @@ -282,6 +286,16 @@ async function main () [

The callback form of this function has no return value.

If `autostart: false` is passed as an option, calling `.ready()`  will
also start the boot sequence.

-------------------------------------------------------
<a name="start"></a>

### app.start()

Start the boot sequence, if it was not started yet.

-------------------------------------------------------
<a name="express"></a>

Expand Down
58 changes: 33 additions & 25 deletions boot.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ function Boot (server, opts, done) {
return instance
}

if (opts.autostart !== false) {
opts.autostart = true
}

server = server || this

this._server = server
Expand All @@ -97,6 +101,7 @@ function Boot (server, opts, done) {
this.once('start', done)
}

this.started = false
this.booted = false

this._readyQ = fastq(this, callWithCbOrNextTick, 1)
Expand All @@ -113,34 +118,34 @@ function Boot (server, opts, done) {
}
this._thereIsCloseCb = false

// we init, because we need to emit "start" if no use is called
this._init()
this._doStart = null
const main = new Plugin(this, (s, opts, done) => {
this._doStart = done
if (opts.autostart) {
this.start()
}
}, opts, noop)

Plugin.loadPlugin.call(this, main, (err) => {
debug('root plugin ready')
if (err) {
this._error = err
if (this._readyQ.length() === 0) {
throw err
}
} else {
this._readyQ.resume()
}
})
}

inherits(Boot, EE)

Boot.prototype._init = function () {
if (this.booted) {
throw new Error('root plugin has already booted')
}
Boot.prototype.start = function () {
this.started = true

if (this._current.length === 0) {
const main = new Plugin(this, function root (s, opts, done) {
// we need to wait any call to use() to happen
process.nextTick(done)
}, {}, noop)
Plugin.loadPlugin.call(this, main, (err) => {
debug('root plugin ready')
if (err) {
this._error = err
if (this._readyQ.length() === 0) {
throw err
}
} else {
this._readyQ.resume()
}
})
}
// we need to wait any call to use() to happen
process.nextTick(this._doStart)
}

// allows to override the instance of a server, given a plugin
Expand Down Expand Up @@ -175,8 +180,9 @@ Boot.prototype._addPlugin = function (plugin, opts, callback) {
opts = opts || {}
callback = callback || null

// we reinit, if use is called after emitting start once
this._init()
if (this.booted) {
throw new Error('root plugin has already booted')
}

// we always add plugins to load at the current element
const current = this._current[0]
Expand Down Expand Up @@ -233,11 +239,13 @@ Boot.prototype.ready = function (func) {
throw new Error('not a function')
}
this._readyQ.push(func)
this.start()
return
}

return new Promise((resolve, reject) => {
this._readyQ.push(readyPromiseCB)
this.start()

function readyPromiseCB (err, context, done) {
if (err) {
Expand Down
50 changes: 50 additions & 0 deletions test/basic.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,3 +205,53 @@ test('promise long resolve', (t) => {
t.notOk(err)
})
})

test('do not autostart', (t) => {
const app = boot(null, {
autostart: false
})
app.on('start', () => {
t.fail()
})
t.end()
})

test('start with ready', (t) => {
t.plan(2)

const app = boot(null, {
autostart: false
})

app.on('start', () => {
t.pass()
})

app.ready(function (err) {
t.error(err)
})
})

test('load a plugin after start()', (t) => {
t.plan(1)

var startCalled = false
const app = boot(null, {
autostart: false
})

app.use((s, opts, done) => {
t.ok(startCalled)
done()
})

// we use a timer because
// it is more reliable than
// nextTick and setImmediate
// this almost always will come
// after those are completed
setTimeout(() => {
app.start()
startCalled = true
}, 2)
})

0 comments on commit a1668fc

Please sign in to comment.