Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Start loading the nested plugins after the current function completes #29

Merged
merged 9 commits into from
Oct 9, 2017

Conversation

mcollina
Copy link
Member

@mcollina mcollina commented Oct 6, 2017

This resolves fastify/fastify#329, but it will be a major version for avvio.

It is impossible for us to retain the context of which plugin is loaded in the current scenario:

avvio.use(function first  (s, opts, next) {
  s.use(second)
  s.use(third)
})

As in this case, third will be loaded as a child of second, not as a child of first. This is typically not a problem, but it messes with the chaining of prefixes ({ prefix: '/path' }) in fastify.

This change makes the callbacks to use (register in fastify) completely irrelevant within the plugins, and it makes the following code not work anymore:

avvio.use(function first  (s, opts, next) {
  s.use(second, next)
})

Instead this must be replaced by:

avvio.use(function first  (s, opts, next) {
  s.use(second)
  next()
})

The callback to use is still supported, but probably is only needed as the top-level, and I think we should stop recommending users to use it (in the plugins readme and the docs).

Another PR will be needed in fastify after this is released.

cc @delvedor @StarpTech

(I have also added debug and a lot of debug points, because I am tired of adding those in via console.log every time there is an hard issue here).

The docs would need to updated.

@mcollina mcollina requested a review from delvedor October 6, 2017 02:33
@mcollina
Copy link
Member Author

mcollina commented Oct 6, 2017

I would also like to pull in #28, as this change would simplify it greatly.

Copy link
Member

@delvedor delvedor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stunning work!
I think that with this change the api is even better than before :)

boot.js Outdated
@@ -165,8 +167,12 @@ Boot.prototype._addPlugin = function (plugin, opts, callback) {

const obj = new Plugin(this, plugin, opts, callback)

if (current.loaded) {
throw new Error(`Impossible to load (${obj.name}) plugin because the parent (${current.name}) was already loaded`)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

" instead of (?

s.use(third, done)
t.throws(() => {
s.use(third)
}, 'Impossible to load (third) because the parent (first) already loaded')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error is:
throw new Error('Impossible to load (${obj.name}) plugin because the parent (${current.name}) was already loaded')
Why here there is not the was?

@StarpTech
Copy link
Member

StarpTech commented Oct 6, 2017

I also like the change and it simplifies the api to use next on top level instead of in nested calls.

@delvedor
Copy link
Member

delvedor commented Oct 6, 2017

I would also like to pull in #28, as this change would simplify it greatly.

👍

@mcollina
Copy link
Member Author

mcollina commented Oct 6, 2017

@delvedor this includes #28 as well and it's ready to land. Can I get one last check? Are any more tests that we should add?

README.md Outdated
2. the next `ready` or `after` callback

In order to handle errors in the loading plugins, you must use the
`.reayd()` method, like so:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ready

@@ -136,9 +131,9 @@ app.on('start', () => {
-------------------------------------------------------
<a name="use"></a>

### app.use(func, [opts], [cb])
### app.use(func, [opts])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you removed [cb]?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because it's very bad to use it anyway, but we still support it for backward compat.

plugin.js Outdated
debug('exec', this.name)

var promise = func(this.server, this.opts, done)
if (promise && typeof promise.then === 'function') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add a debug log here, something like debug('resolving promise', this.name).
Same few lines below: debug('promise resolved', this.name).

@delvedor
Copy link
Member

delvedor commented Oct 7, 2017

Everything looks good!!

A test that will fail, and we should be able to detect it, is:

test('promise long resolve', (t) => {
  t.plan(1)
  const app = boot()
  var insidePromise = false

  new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve()
    }, 500)
  })
    .then(() => {
      app.use((s, opts, done) => {
        insidePromise = true
        done()
      })
    })

  app.ready(function () {
    t.ok(insidePromise)
  })
})

If we can't detect it we should document that this behaviour is not supported.

@mcollina
Copy link
Member Author

mcollina commented Oct 7, 2017

@delvedor that test will fail right now.

A change that we can do is in https://github.com/mcollina/avvio/blob/master/boot.js#L110, basically not reinitializing avvio if the root plugin has finished loading.

One more question.. should we add app.start(), and not make it autostarting?

@mcollina
Copy link
Member Author

mcollina commented Oct 7, 2017

@delvedor I implemented detection for that condition, you might want to remove.

Copy link
Member

@delvedor delvedor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@delvedor
Copy link
Member

delvedor commented Oct 8, 2017

One more question.. should we add app.start(), and not make it autostarting?

I think we should autostart.

@mcollina mcollina merged commit 5ca4d73 into master Oct 9, 2017
@mcollina mcollina deleted the load-plugins-after-callback branch October 9, 2017 07:08
@mcollina mcollina mentioned this pull request Oct 9, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Issue while using register inside a register function
3 participants