mathetake / proxy-wasm-go-sdk

WebAssembly for Proxies (Go SDK)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

This project is in its early stage, and the API is likely to change and not stable.

WebAssembly for Proxies (Go SDK) Build License

The Go SDK for Proxy-Wasm, enabling developers to write Proxy-Wasm extensions in Go.

This SDK is powered by TinyGo and does not support the official Go compiler.

import (
	"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
	"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
)

var counter proxywasm.MetricCounter

type metricRootContext struct { types.DefaultRootContext }

func (ctx *metricRootContext) OnVMStart(int) types.OnVMStartStatus {
	// Initialize the metric.
	counter = proxywasm.DefineCounterMetric("proxy_wasm_go.request_counter")
	return types.OnVMStartStatusOK
}

func (*metricRootContext) NewHttpContext(contextID uint32) types.HttpContext {
	return &metricHttpContext{}
}

type metricHttpContext struct { types.DefaultHttpContext }

func (ctx *metricHttpContext) OnHttpRequestHeaders(int, bool) types.Action {
	// Increment the request counter when we receive request headers.
	counter.Increment(1)
	return types.ActionContinue
}

Requirements

This SDK depends on TinyGo and leverages its WASI (WebAssembly System Interface) target.

Please follow the official instruction here for installing TinyGo.

Compatible ABI / Envoy builds (tested on CI)

proxy-wasm-go-sdk proxy-wasm ABI version istio/proxyv2 Envoy upstream
main 0.2.0 1.9, 1.10 1.18
v0.2.0 0.2.0 1.8, 1.9 1.17

Run examples

build:

# Build all examples.
make build.examples

# Build a specific example.
make build.example name=helloworld

run:

# This requires you to have Envoy binary locally.
make run name=helloworld

SDK development

# Run local tests without running envoy processes.
make test

# Run all e2e tests.
# This requires you to have Envoy binary locally.
make test.e2e

# Run e2e tests for a specific example.
# This requires you to have Envoy binary locally.
make test.e2e.single name=helloworld

Limitations and Considerations

  • Some of existing libraries are not available (importable but runtime panic / non-importable)
    • There are several reasons for this:
      1. TinyGo's WASI target does not support some of syscall: For example, we cannot import crypto/rand package.
      2. TinyGo does not implement all of reflect package(examples).
      3. proxy-wasm-cpp-host has not supported some of WASI APIs yet
    • These issues will be mitigated as TinyGo and proxy-wasm-cpp-host evolve.
  • There's performance overhead of using Go/TinyGo due to GC
    • runtime.GC is called whenever the heap runs out (see 1, 2).
    • TinyGo allows us to disable GC, but we cannot do that since we need to use maps (implicitly causes allocation) for saving the plugin's state.
    • Theoretically, we can implement our own GC algorithms tailored for proxy-wasm through alloc(uintptr) interface with -gc=none option. This is the future TODO.
  • recover is not implemented in TinyGo, and there's no way to prevent the Wasm virtual machine from aborting.
  • Goroutine support
    • In TinyGo, Goroutine is implmeneted through LLVM's coroutine (see this blog post).
    • In Envoy, Wasm modules are run in the event driven manner, and therefore the "scheduler" is not executed once the main function exits. That means you cannot have the expected behavior of Goroutine as in ordinary host environments.
      • The question "How to deal with Goroutine in a thread local Wasm VM executed in the event drive manner" has yet to be answered.
    • We strongly recommend that you implement the OnTick function for any asynchronous task instead of using Goroutine.
    • The scheduler can be disabled with -scheduler=none option of TinyGo.

References

About

WebAssembly for Proxies (Go SDK)

License:Apache License 2.0


Languages

Language:Go 98.2%Language:Makefile 1.8%