I made some experiments with go and webasm. I know that it is
experimental, I know that webasm runs in one thread only (at least on
one core only), and that a "Sleep" will block or even crash if applied without care.
But I read that goroutines can be used, and I wanted to test myself. Yes, it works.
So I tried to do "forbidden" things. The javascript part of my
rudimentary website looks as follows:
<script>
function log(s) {
console.log(s);
}
async function runrunner(event) {
alert(await runner());
}
document.addEventListener('click', runrunner);
</script>The odd function "log" is needed since console.log can not be called
from go directly. The go program is:
package main
import (
"sync"
"syscall/js"
"time"
)
var wg sync.WaitGroup
func main() {
done := make(chan struct{}, 0)
js.Global().Set("runner", js.FuncOf(runner))
<-done
}
func logmsg(msg string) {
defer wg.Done()
for i:=0; i<3; i++ {
time.Sleep(1000*time.Millisecond)
js.Global().Call("log", msg)
}
}
func runner(this js.Value, args []js.Value) interface{} {
js.Global().Call("log", "start")
wg.Add(2)
go logmsg("A")
go logmsg("B")
wg.Wait()
js.Global().Call("log", "stop")
return "success"
}Because of the Sleep() in the go part, runner() must be called
asynchronously.
So after enabling the browser console (usually F12) and clicking on the
page, both goroutines write three times "A" resp. "B" in the console
output. And yes, it works. Almost. I expected a collision, and indeed,
sometimes it occurs:
"Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource."
This looks like a racing condition. One should hope that javascript
actions (like Call() here) are put in the microtask queue one by one and
not at the same time. It seems that there is no mechanisms to prevent
this.
Of course, one could forbid this, but I think that in larger projects it
can not be excluded that such calls compete. The workaround would be to
put such actions in a channel and do the calls from one place only, but
this is not so easy and makes code complicated.
Does anybody know the backgrounds?