wasmerio / wasmer-go

🐹🕸️ WebAssembly runtime for Go
https://pkg.go.dev/github.com/wasmerio/wasmer-go
MIT License
2.8k stars 161 forks source link

Executing HTTP Requests from within WASM functions ? #403

Open HarshVaragiya opened 10 months ago

HarshVaragiya commented 10 months ago

Summary

I am trying to create a "test.wasm" file such that "PingTheServer" function inside the main.go file makes a http GET request using the standard builtin http library and then another go program uses the wasm file as a plugin to load it and execute the function.

main.go file for the plugin:

package main

import (
    "net/http"
)

//export PingTheServer
func PingTheServer() int {
    r, _ := http.Get("http://127.0.0.1:8000/test-from-plugin.go")
    return r.StatusCode
}

func main() {}

Compiling the module with:

tinygo build -panic=trap -scheduler=none --no-debug -o "bin/test.wasm" -target wasi .

And finally, running the WASM code using runner.go as:

package main

import (
    "fmt"
    "os"

    wasmer "github.com/wasmerio/wasmer-go/wasmer"
)

func main() {
    wasmBytes, _ := os.ReadFile("bin/test.wasm")

    store := wasmer.NewStore(wasmer.NewEngine())
    module, _ := wasmer.NewModule(store, wasmBytes)

    wasiEnv, _ := wasmer.NewWasiStateBuilder("wasi-program").Finalize()
    importObject, err := wasiEnv.GenerateImportObject(store, module)
    check(err)

    instance, err := wasmer.NewInstance(module, importObject)
    check(err)

    fx, err := instance.Exports.GetFunction("PingTheServer")
    check(err)
    result, _ := fx()
    fmt.Println(result)
}

func check(err error) {
    if err != nil {
        panic(err)
    }
}

Additional details

I tried the different scheduler options from https://tinygo.org/docs/reference/usage/important-options/ like none and tasks but none of them worked.

  1. None Scheduler with -scheduler=none flag to tinyGo during compilation:

    /usr/lib/go-1.21/src/net/http/client.go:405:2: attempted to start a goroutine without a scheduler
    /usr/lib/go-1.21/src/net/http/h2_bundle.go:7283:4: attempted to start a goroutine without a scheduler
    /usr/lib/go-1.21/src/net/http/h2_bundle.go:7276:4: attempted to start a goroutine without a scheduler
    /usr/lib/go-1.21/src/net/http/h2_bundle.go:900:3: attempted to start a goroutine without a scheduler
    /usr/lib/go-1.21/src/net/http/h2_bundle.go:855:2: attempted to start a goroutine without a scheduler
    /usr/lib/go-1.21/src/net/http/h2_bundle.go:8254:2: attempted to start a goroutine without a scheduler
    /usr/lib/go-1.21/src/net/http/h2_bundle.go:9960:2: attempted to start a goroutine without a scheduler
    /usr/lib/go-1.21/src/net/http/h2_bundle.go:7469:2: attempted to start a goroutine without a scheduler
    /usr/lib/go-1.21/src/net/http/h2_bundle.go:7843:2: attempted to start a goroutine without a scheduler
    /usr/lib/go-1.21/src/net/http/transport.go:1448:3: attempted to start a goroutine without a scheduler
    /usr/lib/go-1.21/src/net/http/transport.go:1436:3: attempted to start a goroutine without a scheduler
    /usr/lib/go-1.21/src/net/http/transport.go:1061:5: attempted to start a goroutine without a scheduler
    /usr/lib/go-1.21/src/net/http/transport.go:1551:2: attempted to start a goroutine without a scheduler
    /usr/lib/go-1.21/src/net/http/socks_bundle.go:45:3: attempted to start a goroutine without a scheduler
    /usr/lib/go-1.21/src/net/http/transport.go:1715:3: attempted to start a goroutine without a scheduler
    /usr/lib/go-1.21/src/net/http/transport.go:1776:2: attempted to start a goroutine without a scheduler
    /usr/lib/go-1.21/src/net/http/transport.go:1612:5: attempted to start a goroutine without a scheduler
    /usr/lib/go-1.21/src/net/http/transport.go:1505:5: attempted to start a goroutine without a scheduler
    /usr/lib/go-1.21/src/net/http/transfer.go:208:2: attempted to start a goroutine without a scheduler
    /usr/lib/go-1.21/src/crypto/tls/conn.go:1527:3: attempted to start a goroutine without a scheduler
    /usr/lib/go-1.21/src/context/context.go:504:2: attempted to start a goroutine without a scheduler
    /usr/lib/go-1.21/src/time/sleep.go:176:2: attempted to start a goroutine without a scheduler
  2. Tasks scheduler with -scheduler=tasks flag or Async scheduler with -scheduler=asyncify flag have same error message:

    tinygo:wasm-ld: error: /tmp/tinygo153007994/main.o: undefined symbol: tinygo_startTask
    tinygo:wasm-ld: error: /tmp/tinygo153007994/main.o: undefined symbol: crypto/internal/bigmod.addMulVVW1024
    tinygo:wasm-ld: error: /tmp/tinygo153007994/main.o: undefined symbol: crypto/internal/bigmod.addMulVVW1024
    tinygo:wasm-ld: error: /tmp/tinygo153007994/main.o: undefined symbol: crypto/internal/bigmod.addMulVVW1536
    tinygo:wasm-ld: error: /tmp/tinygo153007994/main.o: undefined symbol: crypto/internal/bigmod.addMulVVW1536
    tinygo:wasm-ld: error: /tmp/tinygo153007994/main.o: undefined symbol: crypto/internal/bigmod.addMulVVW2048
    tinygo:wasm-ld: error: /tmp/tinygo153007994/main.o: undefined symbol: crypto/internal/bigmod.addMulVVW2048
    failed to run tool: wasm-ld
    error: failed to link /tmp/tinygo153007994/main: exit status 1

My questions are :

  1. How can i make a web request inside a WASM function?
  2. Can i include third party libraries like aws-sdk for golang into a WASM module ?