You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While working on #2425 turned out that there is a very common pattern of having multiple events happening, needing some code to be ran on the event loop, possibly (and usually) before the previous ran has managed to complete.
Usually this is done by calling RegisterCallback while on the event loop and keeping it as field on a struct while running off the event loop (in a separate goroutine). And then using that callback to run on the event loop and if needed to call RegisterCallback again to "restore" it and be able to use it again.
This works great if you have 1 event for each time you need to something off the event loop. For example a (fairly) basic http request of the event loop will likely have only 1 thing that will make it run on event loop again - the request finishing. In this way each http.asyncRequest will call RegisterCallback before spinning off a goroutine and (for example) returning promise to the js.
With web sockets there is very good chance that you will get a second event (receiving a message for example) wanting to run something on the event loop before the previous one has had time to run. This will be true as well for a more complex HTTP API having events for stuff such as "tls handshak start", "tls handshake started", "sended headers", "received headers", etc.
It gets RegisterCallback, the whole method not just its result, and will call it to get a callback. IT also exposes a Queue method to queue concurrently, that will wait for the currently running one(if any) to finish, refresh the RegisterCallback and queue the ones that have been queued.
The only strange part is that again the event loop needs to know that it can end, so there is also a Close.
Proposal
Given that this seems like it will be really common pattern for protocols such as tcp, udp, websockets, http server-push, gRPC, just to name a few it makes sense that this gets better integration in k6.
Adding exactly the same API seems a bit strange as you have RegisterCallback and then this and likely most users will opt to use this especially as it makes it a lot less likely they will make a mistake. I even somewhat wonder if we should let RegisterCallback long-term.
Some considerations include the fact that the ECMAScript specification talks about jobs and the web application api talks about task queues in it's event loop section.
An event loop has one or more task queues. A task queue is an ordered list of tasks, which are algorithms that a ...
In those cases there is even different global (as per the whole document/VM) queues with possibly different ways of handling of events being scheduled on them.
Given this and the fact that we need to still somehow signal that:
we will want to queue jobs on the event loop
we will no longer want to queue jobs on the event loop
so that iteration can end ... appropriately
I propose that we have an API to:
Say you will want to queue on specific named queue which returns an Object TaskQueue on the modules.VU - something like GetQueue(name string) TaskQueue
Have a "default" queue as the only queue for now
TaskQueue has:
3.1. Queue as the link library
3.2. Close as the link library.
This shall be sufficient for now and let us add more queues in the future.
The text was updated successfully, but these errors were encountered:
While working on #2425 turned out that there is a very common pattern of having multiple events happening, needing some code to be ran on the event loop, possibly (and usually) before the previous ran has managed to complete.
Usually this is done by calling
RegisterCallback
while on the event loop and keeping it as field on a struct while running off the event loop (in a separate goroutine). And then using that callback to run on the event loop and if needed to callRegisterCallback
again to "restore" it and be able to use it again.This works great if you have 1 event for each time you need to something off the event loop. For example a (fairly) basic http request of the event loop will likely have only 1 thing that will make it run on event loop again - the request finishing. In this way each
http.asyncRequest
will callRegisterCallback
before spinning off a goroutine and (for example) returning promise to the js.With web sockets there is very good chance that you will get a second event (receiving a message for example) wanting to run something on the event loop before the previous one has had time to run. This will be true as well for a more complex HTTP API having events for stuff such as "tls handshak start", "tls handshake started", "sended headers", "received headers", etc.
This is more or less what happened and is what https://github.com/MStoykov/k6-taskqueue-lib solves.
It gets RegisterCallback, the whole method not just its result, and will call it to get a callback. IT also exposes a Queue method to queue concurrently, that will wait for the currently running one(if any) to finish, refresh the RegisterCallback and queue the ones that have been queued.
The only strange part is that again the event loop needs to know that it can end, so there is also a Close.
Proposal
Given that this seems like it will be really common pattern for protocols such as tcp, udp, websockets, http server-push, gRPC, just to name a few it makes sense that this gets better integration in k6.
Adding exactly the same API seems a bit strange as you have
RegisterCallback
and then this and likely most users will opt to use this especially as it makes it a lot less likely they will make a mistake. I even somewhat wonder if we should let RegisterCallback long-term.Some considerations include the fact that the ECMAScript specification talks about jobs and the web application api talks about task queues in it's event loop section.
In those cases there is even different global (as per the whole document/VM) queues with possibly different ways of handling of events being scheduled on them.
Given this and the fact that we need to still somehow signal that:
so that iteration can end ... appropriately
I propose that we have an API to:
GetQueue(name string) TaskQueue
3.1.
Queue
as the link library3.2.
Close
as the link library.This shall be sufficient for now and let us add more queues in the future.
The text was updated successfully, but these errors were encountered: