-
Notifications
You must be signed in to change notification settings - Fork 569
Closed
Labels
Description
The program below implements a typical timeout cancellation pattern for a pair communicating goroutines:
package main
import (
"context"
"time"
)
func main() {
c := make(chan bool)
ctx, cancel := context.WithCancel(context.Background())
go func() {
time.Sleep(time.Second)
cancel()
}()
go func() {
for {
select {
case c <- true:
case <-ctx.Done():
return
}
}
}()
go func() {
for {
select {
case <-c:
case <-ctx.Done():
return
}
}
}()
<-ctx.Done()
}
Under regular Go this program exits after 1 second as one may expect, however under GopherJS it runs forever: even though the two goroutines that are passing messages through the channel get blocked and unblocked on a regular basis, the sleeping goroutine never returns from the sleep.
I think what happens here is that the two communicating goroutines never return control to NodeJS's loop and the setTimeout's callback never has a chance to run. Although this probably isn't against the spec, this breaks a common usage pattern.