Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using await before go.run(inst) of wasm_exec await indefinitely #49710

Closed
oliverlj opened this issue Nov 21, 2021 · 6 comments
Closed

Using await before go.run(inst) of wasm_exec await indefinitely #49710

oliverlj opened this issue Nov 21, 2021 · 6 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Milestone

Comments

@oliverlj
Copy link

What version of Go are you using (go version)?

$ go version
go version go1.17.2 linux/amd64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
❯ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/oliver/.cache/go-build"
GOENV="/home/oliver/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/oliver/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/oliver/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/lib/go-1.17"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go-1.17/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.17.2"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build2669847847=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Trying to run wasm module with await, then wait is lock

export async function loadCff2Wasm() {
  const go = new Go();
  const result = await WebAssembly.instantiateStreaming(fetch('cff2.wasm'), go.importObject);

  go.run(result.instance);
  // workaround, if I put await before go.run, promise never resolve
  await new Promise((resolve) => setTimeout(resolve, 1000));
}

I'm using it with an ember service. calling fetchTransactions will run indefinitely.

import { tracked } from '@glimmer/tracking';
import Service from '@ember/service';

import { loadCff2Wasm } from 'cryptofiscafacile-wasm';
import { dropTask, enqueueTask, task, timeout } from 'ember-concurrency';
import { perform } from 'ember-concurrency-ts';

import type { TxData } from 'cryptofiscafacile-wasm';

export default class WasmService extends Service {
  #cff2WasmLoaded = false;

  @tracked
  transactions?: TxData;

  @enqueueTask
  async loadCff2WasmTask() {
    if (!this.#cff2WasmLoaded) {
      await loadCff2Wasm();
      this.#cff2WasmLoaded = true;
    }
  }

  @task
  async getTransactionsTask() {
    await perform(this.loadCff2WasmTask);

    this.transactions = await getTransactions();
  }

  async fetchTransactions() {
    perform(this.getTransactionsTask);
  }
@seankhliao
Copy link
Member

can you provide a self contained reproducer?

@heschi
Copy link
Contributor

heschi commented Nov 22, 2021

cc @neelance @cherrymui

@heschi heschi added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. labels Nov 22, 2021
@heschi heschi added this to the Go1.18 milestone Nov 22, 2021
@oliverlj
Copy link
Author

please find a repo where the case is reproductible
https://gitlab.com/c1560/cryptofiscafacile/-/tree/develop

It is a monorepo with a wasm lib and a frontend in Ember which use the wasm lib

@fiscafacile
Copy link

Here is a much more simple example : https://github.com/fiscafacile/exampleGoWasmIssue49710

The Run button never get enabled, event after fetch(main.wasm) and Wasm Init is done ("Go WebAssembly Initialized" in Console)

@tessellator
Copy link

I think this feature is working as intended. The promise returned by go.run resolves when the Wasm program exits. In the original example, the Wasm program is not intended to exit (because the host JS application will make calls into it).

If you want the host application to wait for the Wasm program to finish initializing, you can create a promise in the host application and resolve it from the Wasm program. For example, you might modify the code in the original post like this:

let isReady = new Promise((resolve) => {
  // @ts-ignore
  window.onWasmInitialized = resolve;
});

export async function loadCff2Wasm() {
  const go = new Go();
  const result = await WebAssembly.instantiateStreaming(fetch('cff2.wasm'), go.importObject);

  go.run(result.instance);
  await isReady;
}

You can then add the following call in the Go Wasm program after it is initialized:

js.Global().Get("onWasmInitialized").Invoke()

This call will resolve the isReady promise and let the host application continue.

You might also consider calling and awaiting go.run in a setTimeout so that you can perform some action if the Wasm program exits.

setTimeout(async () => {
  await go.run(result.instance);
  console.log('Wasm program exited! ...Restart it?');
});

@ianlancetaylor
Copy link
Contributor

Closing based on the last comment. Please comment if you disagree.

ulope added a commit to shutter-network/rolling-shutter that referenced this issue Jul 18, 2022
The Go runtime needs a small amount of time to initialize.
However the promise returned by `Go().run()` only resolves once the
wasm process exits.

Wheich means we need another way to wait for the initialization to be
completed.
Solution taken from:
golang/go#49710 (comment)
@golang golang locked and limited conversation to collaborators Jan 29, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
None yet
Development

No branches or pull requests

7 participants