-
Notifications
You must be signed in to change notification settings - Fork 18k
misc/wasm: long tasks with Go WebAssembly #39620
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
Comments
Preemption of goroutines to let the event loop continue is not yet implemented. I think it only makes sense to tackle this after we have WebAssembly threads. You can try |
Thanks for the quick response @neelance. I'll try this out. I'm still somewhat confused about something. Why do I see the event loop being able to continue for some function calls and not others? There are other functions that we call that do not seem to cause these problems, but I haven't been able to determine what contributes to this difference yet. |
I don't know. In general the event loop can continue as soon as all goroutines are asleep/blocked. |
Gotcha. Okay, well I will try to see if sleeping solves the problem. Thanks again! |
I wonder if it would be possible/helpful to let the scheduler do a very short sleep (to give the event loop a chance to kick in) once a while, instead of only yielding when we run out of works? |
@cherrymui That seems super valuable if it would actually solve the problem. |
@cherrymui Maybe possible, but not trivial. An event/callback handler needs to be able to run synchronous. Yielding would make the handler return early. |
Related: #32840. |
Ah yes, now that makes sense. I was wondering why would yielding make the handler return early. Thanks for that correction @neelance. |
What version of Go are you using (
go version
)?go v1.14.3
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?GOOS=js and GOARCH=wasm
go env
OutputWhat did you do?
Compiled 0x-mesh to WebAssembly and ran in the browser. I put a hot function inside of a
goroutine
and used a channel for synchronization to try to get the go runtime to release the main thread enough to prevent the UI from stuttering.What did you expect to see?
I expected the go runtime to not block the event loop for long periods of time when a goroutine was invoked.
What did you see instead?
These are two flame graphs of different functions that block for a long period of time (up to 1 second). As you'll notice, the sub-calls within these graphs run in significantly less time, so I would think that it would be possible to pick execution back up after clearing the event loop.
Notes
If there is an easy way to break these tasks up (like putting something inside of a go-routine), that would fix my problem.
The tasks in the pictures provided correspond to two different scenarios involving the same function,
HandleOrderSyncResponse
. This can be found in our codebase here: https://github.com/0xProject/0x-mesh/blob/master/core/ordersync/ordersync.go#L471.We do a few things that are somewhat non-standard for optimization purposes within this callstack including calling out to functions registered on the Javascript
window
object. This code can be found here: https://github.com/0xProject/0x-mesh/blob/master/orderfilter/validate_js.go#L36. I recently created a new PR that makes the Javascript function that is being called asynchronous, which significantly reduced the time that the individual calls would hold onto the event loop; however, the underlying task held onto the event loop for a much longer period of time. The second image is the flame graph contains calls to the updatedMatchOrder
function. This PR can be found here.The text was updated successfully, but these errors were encountered: