[wasm] net/http crashes application

138 views
Skip to first unread message

Patrick Gaubatz

unread,
Jul 30, 2019, 12:47:10 PM7/30/19
to golang-nuts
Hi!

When compiled to wasm, the following small application involving the net/http client completely crashes the Go runtime:

// +build js,wasm

package main

import (
       
"fmt"
       
"net/http"
       
"syscall/js"
)

func doFetch
() {
        res
, err := http.Get("http://localhost:8181")
        fmt
.Println(res, err)
}

func goFetch
(this js.Value, inputs []js.Value) interface{} {
        doFetch
()
       
return nil
}

func main
() {
        fmt
.Println("Running doFetch() from wasm directly...")
        doFetch
()
        fmt
.Println("Now run goFetch() from javascript (this will crash):")
        js
.Global().Set("goFetch", js.FuncOf(goFetch))
       
select {}
}

All that's needed is calling `goFetch()` in the Web browser's console, as you can see in this screenshot:
The complete source code can be found in this repository: https://github.com/pgaubatz/golang-wasm-http-client-bug
The interesting part is that executing the GET request directly from Go using `doFetch()` just works fine.
Only if the request is triggered via `goFetch()` from Javascript it crashes.
However, in the Web browsers network monitor it can be seen that the acutal request is sent out but the Go runtime somehow is not able to process the response.

Does anyone have a clue how to debug this problem? 

I even tried compiling the example code with the latest Go 1.13 beta version using (albeit with not success):

$ docker run --rm -v $PWD:/src -w /src golang:rc-buster

Any hints are really appreciated!

Thank you very much in advance! 

Best regards,
Patrick

Jihoon Chung

unread,
Jul 30, 2019, 11:58:54 PM7/30/19
to golang-nuts
Because the syscall/js doc says, (from https://golang.org/pkg/syscall/js/#FuncOf )
A wrapped function triggered during a call from Go to JavaScript gets executed on the same goroutine. A wrapped function triggered by JavaScript's event loop gets executed on an extra goroutine. Blocking operations in the wrapped function will block the event loop. As a consequence, if one wrapped function blocks, other wrapped funcs will not be processed. A blocking function should therefore explicitly start a new goroutine.

and http.Get() is a blocking function.

Changing doFetch() call in goFetch to "go doFetch()" should work.

2019년 7월 31일 수요일 오전 1시 47분 10초 UTC+9, Patrick Gaubatz 님의 말:

Patrick Gaubatz

unread,
Jul 31, 2019, 3:46:28 AM7/31/19
to golang-nuts
Hi Jihoon,

On Wednesday, July 31, 2019 at 5:58:54 AM UTC+2, Jihoon Chung wrote:

Changing doFetch() call in goFetch to "go doFetch()" should work.

You're right, this actually fixes the crashes. Thank you so much! 

Patrick
Reply all
Reply to author
Forward
0 new messages