Go SDK for WebAssembly-based Envoy extensions
The Go sdk for
proxy-wasm, enabling developers to write Envoy extensions in Go.
proxy-wasm-go-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
const metricName = "proxy_wasm_go.request_counter"
type context struct{ proxywasm.DefaultContext }
func (ctx *context) OnVMStart(int) bool {
// initialize the new metric
counter, _ = proxywasm.DefineCounterMetric(metricName)
return true
}
func (ctx *context) OnHttpRequestHeaders(int, bool) types.Action {
// increment the request counter when we receive request headers
counter.Increment(1)
return types.ActionContinue
}
requirements
proxy-wasm-go-sdk depends on the latest TinyGo which supports WASI target(tinygo-org/tinygo#1373).
In order to install that, simply run (Ubuntu/Debian):
# this corresponds to https://github.com/tinygo-org/tinygo/commit/f50ad3585d084b17f7754f4b3cb0d42661fee036
wget https://19227-136505169-gh.circle-artifacts.com/0/tmp/tinygo_amd64.deb
dpkg -i tinygo_amd64.deb
Alternatively, you can use the pre-built docker container getenvoy/extention-tingyo-builder:wasi-dev
for any platform.
TinyGo's official release of WASI target will come soon, and after that you could
just follow https://tinygo.org/getting-started/ to install the requirement on any platform. Stay tuned!
compatible ABI / Envoy builds
proxy-wasm-go-sdk |
proxy-wasm ABI version |
istio/proxyv2 |
main |
0.2.0 |
v1.17.x |
v0.0.4 |
0.2.0 |
v1.17.x |
run examples
build:
make build.examples # build all examples
make build.example name=helloworld # build a specific example
run:
make run name=helloworld
sdk development
make test # run local tests without running envoy processes
make test.e2e # run e2e tests
compiler limitations and considerations
- Some of existing libraries are not available (importable but runtime panic / non-importable)
- There are two reasons for this:
- TinyGo's WASI target does not support some of syscall: For example, we cannot import
crypto/rand
package.
- TinyGo does not implement all of reflect package(examples).
- These issues will be mitigated as the TinyGo improves.
- There's performance overhead in 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.
- Be careful about using Goroutine
- In Tinygo, Goroutine is implmeneted through LLVM's coroutine (see this blog post).
- Make every goroutine exit as soon as possible, otherwise it will block the proxy's worker thread. That is too bad for processing realtime network requests.
- We strongly recommend that you implement the
OnTick
function for any asynchronous task instead of using Goroutine so we do not block requests.
references
Special thanks to TinyGo folks:)