-
Notifications
You must be signed in to change notification settings - Fork 38
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
support await after / await use #92
Conversation
Please target https://github.com/mcollina/avvio/tree/next instead and drop 6 and 8. |
@mcollina done |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work!!
Can you add a more complex test that verifies what happens when you register multiple plugins, some await and some not?
For example:
await app.use(first)
// check decorated app
app.use(second)
// check that second has noot decorated the instance
await app.use(third => app.use(fourth))
// check that we have third and fourth decorators
await app.ready()
// check all
So the way this is currently implemented is the queue is processed when we hit an await, to put this example into app.use(first)
app.after(() => {
// check decorated app
app.use(second)
app.use(async function third (app) { app.use(fourth) })
// CANT CHECK HERE BECAUSE AWAIT WILL TRIGGER AN AFTER
app.after(async () => {
// check that second has not decorated the instance (SPOILER, IT HAS)
// check that we have third and fourth decorators
await app.ready()
// check all
})
}) Are we saying it's essential to ensure that non-awaited |
I would not say that is essential, but it's important to at least document what's happening here. |
Yes. Right now, plugins are run after the main function complete. I think we should retain this behavior.
I think that should be the goal, yes. |
@mcollina wait.. am I misunderstanding or is that a contradiction.
I think I agree it's worth the effort to keep the behaviour as unsurprising as possible, which means processing unawaited plugins at the end of the function |
We have two options:
Option 2
Which one do you think we should pick? |
the non-breaking changes one (2) - it's just a case of making it work |
Ahum, I think option 1 is better and it's compatible to how .after() wroks right now. |
well @mcollina that depends on how you interpret the use of await, if you think of it as enclosing all code after the await in an |
Yes, it's similar on when you will access the decorators, but the moment when the plugin is executed is not. |
in 1), the |
In the context of replicating queueAThing()
await aThing()
queueAThing()
await processTheQueue() what's intuitive in this case? that both |
The problem is that app.use(first)
const p = app.use(second)
app.use(third)
await p // which one will be loaded?
await app.ready() Note that the order in which plugins are loaded in scenario 2 depends on when |
In your example under 2, it'll be |
@mcollina @delvedor I've added the more complex test (and some bug fixes) - behaviour is as per 1, tests show behaviour is as per 1. If we decide on 1 this is probably ready to go, if we decide on 2 (which I'm actually more in favour of) then I'll adapt it for that. My vote is for 2, if you @delvedor @jsumners and @mcollina can come to a consensus I'll act accordingly. |
7be7671
to
894ba56
Compare
I think it's fair to say that if you do not |
thanks @Ethan-Arrowood for doing that! ok I'm confused by this test, it's my understanding that In the failing test we're doing an after, then a decorate. Then as a sibling to the after, we're doing a register and expecting the decorator to be present? I'm not trying to be arrogant but is it possible that this test is incorrect and there is a bug in current? Or am I failing to understand how after is supposed to work? |
That is not correct with the behavior in master. Each function passed to after is queued in the same queue of the plugins, and as a result it should be executed before the second register. |
gotcha, okay |
28d0466
to
d392bd2
Compare
boot.js
Outdated
server[useKey] = function (fn, opts) { | ||
instance.use(fn, opts) | ||
const plugin = instance._lastUsed | ||
instance.then = (resolve) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you are missing reject.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah and a catch
method. Promise returned from _loadRegistered
has no rejection in its still currently a mystery to me on how to determine the failure mode of this case. A throw in a plugin that has been await registered does not end up on the _error
property. Any tips appreciated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would share this case because I didn't understand what it should happen reading the README:
Without autostart the await app.after
is blocking the loading:
const boot = require('..')
const app = {}
boot(app, { autostart: false })
async function run () {
app.use((f, opts, cb) => {
console.log('plugin init')
app.use((f, opts, cb) => {
console.log('plugin2 init')
cb()
})
cb()
})
await app.after()
console.log('after')
await app.ready()
console.log('ready')
}
run().catch(e => console.log(e))
Maybe should we threat await app.after
as a trigger for starting the app as app.ready
or avoid this setup?
I think we should start.
Il giorno mar 11 feb 2020 alle ore 22:37 Manuel Spigolon <
[email protected]> ha scritto:
… ***@***.**** commented on this pull request.
I would share this case because I didn't understand what it should happen
reading the README:
Without autostart the await app.after is blocking the loading:
const boot = require('..')const app = {}boot(app, { autostart: false })
async function run () {
app.use((f, opts, cb) => {
console.log('plugin init')
app.use((f, opts, cb) => {
console.log('plugin2 init')
cb()
})
cb()
})
await app.after()
console.log('after')
await app.ready()
console.log('ready')
}run().catch(e => console.log(e))
Maybe should we threat await app.after as a trigger for starting the app
as app.ready or avoid this setup?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#92>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAMXY5TLW7NF4CYTFZKHVDRCMLCVANCNFSM4KEY7NQQ>
.
|
Oh, and I forgot to tell that, in the example, if you replace ready with start and autoload:true, an error is thrown |
I'm working on a fix for the problems you flagged @Eomm and one more that we have if |
@Eomm this should now work as expected, thanks for the review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great docs. Really cool code too! Nice work everyone. Also, this is very exciting because it unblocks a couple of things upstream in fastify 😄
ok I've had one last sweep and addressed nits. LGTM to me from here - cc @mcollina |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👏🏼
for fastify this will enable
as an alternative to