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?

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/bfd5d82c-6ba7-4c29-adea-a3bf25ad4fb8n%40googlegroups.com.

Reply via email to