Go: runtime: implement timers, JavaScript callbacks back into WebAssembly

Created on 23 May 2018  路  24Comments  路  Source: golang/go

After some discussion last week with @cherrymui, @rsc, @aclements, et al, we decided that users would be really sad if Go 1.11 was released with WebAssembly support and then realized they couldn't really use it in a browser well, without working timers & callbacks back into Go.

@cherrymui did a little prototype of callbacks and it was enough to show a demo of a Go webassembly program updating images in the DOM and responding to button clicks.

So we decided it was worth spending a bit of time and making sure the wasm support is what users will expect for Go 1.11.

@neelance, what's your availability look like to finish that in the next month or two?

I see you updated your branch (https://github.com/neelance/go/commits/wasm-wip) 3 days ago with https://github.com/neelance/go/commit/773eb4660f4aa163becf70b55d967c879029c2ab

Do you need any help? @cherrymui and perhaps @aclements could help if needed.

Please use this issue number in any related CLs. Thanks!

Arch-Wasm FrozenDueToAge NeedsFix release-blocker

Most helpful comment

An http.DefaultTransport value implementing http.RoundTripper I assume? SGTM for Go 1.11. Let's do it.

If the author wants to send it via a PR or CL I can review. (PRs get converted into Gerrit these days)

All 24 comments

Change https://golang.org/cl/114197 mentions this issue: runtime, sycall/js: add support for callbacks from JavaScript

Thanks for offering the help! Callbacks are already working quite well. I just cleaned up the commit some more and pushed the CL for initial feedback/review: https://go-review.googlesource.com/c/go/+/114197

Do we also want to use this to get support for http.Transport into this release? There is already a POC at https://github.com/johanbrandhorst/fetch.

An http.DefaultTransport value implementing http.RoundTripper I assume? SGTM for Go 1.11. Let's do it.

If the author wants to send it via a PR or CL I can review. (PRs get converted into Gerrit these days)

I'm happy to offer help with implementing and/or reviewing here as well.

I'm the author of the original Fetch API-based http.RoundTripper implementation in GopherJS that https://github.com/johanbrandhorst/fetch is based on, so I'm very familiar with how it works.

I've reached out to @johanbrandhorst and I'll coordinate next steps (regarding http.DefaultTransport) with him.

@shurcooL I'll try and get something in as soon as I can. I'm thinking we should implement the XHR transport as well and maybe make that the default as even among browsers that support WASM, they don't all support Fetch out of the box.

fetch can be polyfilled and services like https://polyfill.io/ make it trivially easy to do so efficiently. I nowadays always prefer the newer (stable) APIs + polyfills.

@neelance, in general I agree with that, but note that we want Go WebAssembly to work for users without the users needing to write or deal with any JavaScript. So unless that polyfill is part of some Go JS library, I'd rather we just fall back to an XHR RoundTripper if fetch is unavailable.

@bradfitz This is a slippery slope. What about all the ES6 features that wasm_exec.js is using?

For example fetch is supported by older browsers than async/await.

@johanbrandhorst, @neelance, which browsers support WebAssembly & the ES6 features we're depending on but do NOT support Fetch?

If zero, then obviously we don't need XHR support.

https://caniuse.com/#feat=fetch suggests everything supports Fetch that already supports wasm.

Oh yes, working on WebAssembly such much made me take it for granted. ;-) Yes, it looks like all browsers that support WebAssembly also support Fetch. No XHR needed.

Same goes for async/await and the other ES6 features.

As far as I know, all modern browsers support the basic Fetch API by now, but not all of them support streams, which are required for streaming the response body. E.g., see https://caniuse.com/#search=Streams. Firefox has javascript.options.streams and dom.streams.enabled flags that can enable it.

I think it should still be possible to use Fetch for those browsers, and avoid using Streams when they're not available.

Great, that sounds fine. I'll put together a PR as soon as I can (I want to try the PR workflow).

Change https://golang.org/cl/114515 mentions this issue: net/http: add js/wasm compatible DefaultTransport

With https://golang.org/cl/114515 merged, we didn't quite finish the discussion opened in https://go-review.googlesource.com/c/go/+/114515#129. I'd like to revisit and implement that discussion as the existing implementation may break some use cases. How can we identify if a test binary is running?

@johanbrandhorst, I can think of hacky ways to do it, but I'm not sure we have a supported way. For this application in particular I think we can look at os.Args[0] and see if it's "node".

That actually makes a lot of sense since Fetch isn't supported natively by Node anyway. I'll get a CL up.

Change https://golang.org/cl/115495 mentions this issue: net/http: use fake Transport network when running in Node

The net/http package does not compile any more:

src/net/http/roundtrip_js.go:23:10: undefined: t
src/net/http/roundtrip_js.go:200:11: undefined: errClosed
src/net/http/roundtrip_js.go:258:11: undefined: errClosed

Please fix.

My bad, I'll sort it.

Change https://golang.org/cl/116076 mentions this issue: net/http: fix build errors on js/wasm target

@neelance - Just checking, is there anything else pending on this that you wanted to do ?

I think we can close this issue. I only want to add some minor additions to the API for convenience (e.g. an easy way to create a promise).

Was this page helpful?
0 / 5 - 0 ratings