So, finally I solved the problem! The trick is to add a new parameter to the exported function. This parameter will be a javascript callback. Then we call the exported function as a goroutine passing the callback to it. The exported function had also to be changed: no more values to be returned, now they are passed to the callback function. Doing so, when the function is called the execution flow immediately returns to javascript and no panic occurs. The exported function (called asynchronously) keeps running (sleeping from time to time when it calls http.Get) until all the work is done, then it calls the javascript callback!
If someone wants to see the code, the main function can be seen (although can't be executed thanks to the private package it imports) here: https://go.dev/play/p/Iyy-pgCZCHI . The javascript code invoking the wasm function: window.addEventListener('message', function(event) { console.log("STARTING WASM"); img2data(event.data.body, { success: function(htmldoc) { event.source.postMessage({doc: htmldoc, err: null}, event.origin); console.log("ENDING success WASM"); }, fail: function(err) { event.source.postMessage({doc: "", err: err}, event.origin); console.log("ENDING failed WASM"); }, }); console.log("WASM pending"); }); So, I ended up answering my own question, but I think that the question should be "closed" to prevent anyone of wasting time and also it could help someone else with the same problem in the future. Best regards! Em quinta-feira, 16 de junho de 2022 às 17:41:43 UTC-3, Luis Furquim escreveu: > > Hi Gophers! > > I am trying to work with web assembly and got stuck with a deadlock > problem, > The main function has nothing more than simple steps, but if someone wants > to check, it is at https://go.dev/play/p/y_0aiIzFA0j . > It imports an internal package so it is not compilable outside my > computer, it is at the Go Playground just to show the source if someone > wants to see it. > > So, it sets a javascript callable function exported as img2data. The > purpose of the function is to receive an HTML string and check each image > reference (IMG tags and alse elements with "background-image: url(...)" > style), download the image, generate a data URL, and finally replacing the > reference in the HTML with the data URL. > > But when it starts the process it deadlocks at the very first image it > finds. The panic message is as follows: > > 2022/06/16 17:19:01 {main}[Img2data-wasm.go]<main.func1>(26): Calling > Img2data > wasm_exec.js:51 2022/06/16 17:19:01 {Img2data}[Img2data.go]<Img2data>(21): > START > 8wasm_exec.js:51 2022/06/16 17:19:02 > {Img2data}[Img2data.go]<Img2data.func1>(30): NOSCRIPT > wasm_exec.js:51 2022/06/16 17:19:02 > {Img2data}[Img2data.go]<Img2data.func2>(41): IMG > wasm_exec.js:51 2022/06/16 17:19:02 > {Img2data}[Img2data.go]<Img2data.func2>(44): img: src=https://<censored > image url>.png > wasm_exec.js:51 2022/06/16 17:19:02 > {Img2data}[Img2data.go]<Img2data.func2>(46): img: src=https://<censored > image url>.png > wasm_exec.js:51 fatal error: all goroutines are asleep - deadlock! > wasm_exec.js:51 > wasm_exec.js:51 goroutine 1 [chan receive]: > wasm_exec.js:51 main.main() > wasm_exec.js:51 /home/vuco/repos/mpf/Img2data/cmd/Img2data-wasm.go:35 +0xa > wasm_exec.js:51 > wasm_exec.js:51 goroutine 6 [select]: > wasm_exec.js:51 net/http.(*Transport).RoundTrip(0x36c640, 0x1a0a200, > 0x36c640, 0x0, 0x0) > wasm_exec.js:51 /home/vuco/repos/go/src/net/http/roundtrip_js.go:169 +0x4f > wasm_exec.js:51 net/http.send(0x1a0a200, 0xe14d8, 0x36c640, 0x0, 0x0, 0x0, > 0x0, 0x40c0b8, 0x718ed0, 0x1) > wasm_exec.js:51 /home/vuco/repos/go/src/net/http/client.go:251 +0x5b > wasm_exec.js:51 net/http.(*Client).send(0x379940, 0x1a0a200, 0x0, 0x0, > 0x0, 0x40c0b8, 0x0, 0x1, 0x1a0a200) > wasm_exec.js:51 /home/vuco/repos/go/src/net/http/client.go:175 +0x13 > wasm_exec.js:51 net/http.(*Client).do(0x379940, 0x1a0a200, 0x0, 0x0, 0x0) > wasm_exec.js:51 /home/vuco/repos/go/src/net/http/client.go:717 +0x36 > wasm_exec.js:51 net/http.(*Client).Do(...) > wasm_exec.js:51 /home/vuco/repos/go/src/net/http/client.go:585 > wasm_exec.js:51 net/http.(*Client).Get(0x379940, 0x4c4320, 0x4e, 0xb, > 0x1a05d50, 0x1) > wasm_exec.js:51 /home/vuco/repos/go/src/net/http/client.go:474 +0xe > wasm_exec.js:51 net/http.Get(...) > wasm_exec.js:51 /home/vuco/repos/go/src/net/http/client.go:446 > wasm_exec.js:51 mpf/Img2data.Img2data.func2(0x0, 0x718de0) > wasm_exec.js:51 /home/vuco/repos/mpf/Img2data/Img2data.go:48 +0x19 > wasm_exec.js:51 github.com/PuerkitoBio/goquery.(*Selection).Each(0x718db0, > 0xa8378, 0x3) > wasm_exec.js:51 /home/vuco/repos/gopkg/pkg/mod/ > github.com/!puerkito!bio/goq...@v1.8.0/iteration.go:10 > <http://github.com/!puerkito!bio/goquery@v1.8.0/iteration.go:10> +0x16 > wasm_exec.js:51 mpf/Img2data.Img2data(0x2000000, 0x9ef7fd, 0x2000000, > 0x9ef7fd, 0x0, 0x0) > wasm_exec.js:51 /home/vuco/repos/mpf/Img2data/Img2data.go:34 +0x14 > wasm_exec.js:51 main.main.func1(0x0, 0x0, 0x40ec60, 0x1, 0x1, 0x4102b8, > 0x3a0108) > wasm_exec.js:51 /home/vuco/repos/mpf/Img2data/cmd/Img2data-wasm.go:28 +0x10 > wasm_exec.js:51 syscall/js.handleEvent() > wasm_exec.js:51 /home/vuco/repos/go/src/syscall/js/func.go:96 +0x24 > > I shared the point of the code where it panics at > https://go.dev/play/p/3chb2eQo8sD . Again, it is not runnable, it's just > there to check the code. It panics at line 15. > > The point is: there is only 2 goroutines (done by me, I don't know about > other go routines started by the libraries) > 1) the main function running, but, as learnt from golang wasm tutorial, it > is doing nothing, just waiting forever for a channel read that will never > read anything, > 2) the img2data function that tries to download the images ang, when I > call the http.Get it goes to sleep waiting for the server to answer the > request and at this very moment all my goroutines are sleeping ang the > runtime detects this condition and panics! > > I also tried to make the main function do something while it waits forever > by using a "for{}", it did not panicked, but I got stuck anyway and I > suspect that it is because in the web assembly runtime only one goroutine > can execute until it sleeps and leave place for other goroutines and doing > a "for{}" makes the main function run forever but it never allows the > img2data function to be run. > > So, someone could help me on how to solve this problem? > > Thank you in advance! > Best regards, > > -- > Luis Otavio de Colla Furquim > > -- 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/c13835ef-8490-4fd1-b537-e98c9d3534e1n%40googlegroups.com.