-
Notifications
You must be signed in to change notification settings - Fork 570
synchronous calls in goroutine blocks other concurrent goroutines #849
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
I also have a:
This is outside of any goroutines I have created. (assume it is called from main). |
What does the synchronous function look like / do? Is it Go or regular Javascript? js.Global.Call("setInterval", func() {
println("test 1")
}, 1000)
I'm not sure I agree. This would run as regular Javascript outside the Go runloop. If you had Go code that said go func() {
for {
println("test 1")
time.Sleep(time.Second)
}
}() and that kept running, I think that would imply that the Go runloop is not blocked. |
The synchronous function is a non-Go function (electron function). |
Do you have any ideas why a synchronous function inside a goroutine would prevent other independent goroutines from running? That's definitely not the case in standard go. |
The synchronous function is not Go, so it blocks the Go scheduler. It's as if in regular Go (before, I wanna say, 1.5?) you set MAXPROCS to 1 and then started a goroutine that just sat in a loop doing no function calls. The scheduler doesn't run. GopherJS is not Go (though obviously it does its best). It compiles to Javascript. Javascript is single threaded. If some Javascript function blocks the rest of the Javascript engine, then there's nothing magical about GopherJS that can get around that, it'll block too. Edit: I re-read this issue after commenting and I'm not as sure as I was. I think it's going to be hard to diagnose here without showing example code. Can you boil it down to a minimal working example? |
The non-synchronous function doesn't seem to block entire javascript engine: A redacted Go-version (which is what I actually use):
|
setTimeout not working reliably may be relevant: GopherJS uses Instead of testing with When you say the main thread is blocked, how long do you wait? electron/electron#7079 (comment) mentions 10+ second delays. |
I added:
I tried |
I think to test if var f func()
f = func() {
println("test2")
js.Global.Call("setTimeout", f, 1000)
}
f() As it is, you've got a stalled goroutine, which we already know doesn't work. I was also thinking that, since js.Global.Call("setInterval", func() {
runtime.Gosched()
}, 1000) on the theory that this might let the GopherJS scheduler run, but then I looked at the source to Gosched, and it just calls |
|
I still think this is a gopherjs bug that a call to a synchronous function is able to block all independent goroutines. |
I made a discovery. I replaced the synchronous code with a I replaced original code:
Now:
|
The non-Go function is an electron function which I suspect is a node.js function which wraps a Objective-C++ function. |
Thank you for verifying that The func Sleep(d Duration) {
c := make(chan struct{})
js.Global.Call("$setTimeout", js.InternalObject(func() { close(c) }), int(d/Millisecond))
<-c
} I've played around for a while, simulating a blocking function with block := func() {
for n := 0; n < busyloop; n++ {
_ = n
}
} (where busyloop is a variable I can increase outside of the blocked function), and different ways of calling It does appear that you can call So here's what I tried if you want to try it: js.Global.Call("setInterval",
js.InternalObject(js.Global.Get("$runScheduled")),
10) which compiles to $global.setInterval($runScheduled, 10); @dmitshur I'm about out of ideas. Please take a look at this when you get a chance. I'd recommend you take special notice of electron/electron#7079, which discusses |
I have 1 goroutine which contains a call to a synchronous function.
I have many other independent concurrent goroutines which ordinarily would run concurrently. But they don't run until the synchronous function returns.
The text was updated successfully, but these errors were encountered: