envoy-go-extension
Implement Envoy filter by using Go.
- support full-featured Go language, including goroutine.
- support streaming, with rarely worry about concurrency conflict.
Table of Contents
Status
This project is under heavy active development at this stage.
API
coming soon.
Requirements
- Go >= 1.18
- Gcc >= 9 or Clang >= 11.1.0
- Bazel >= 5.1.1
Samples
If you just want to use this extension. Please refer to envoy-go-filter-samples.
It shows how to implement a filter by using pure Go.
Build
Envoy
- Install Bazel
See details in envoyproxy
- Build Envoy
Generate executable envoy file under bazel-bin.
# use default build options
make build-envoy
# add more build options
build_opts="--define=wasm=disabled"
make build-envoy BUILD_OPTS=$build_opts
golang shared object
Generate libgolang.so under the current directory.
# using local go command, recommended when you are using linux.
make build-so-local
# using docker
make build-so
Run
Please update the so_path
field (in envoy-golang.yaml) to you local path.
# it will use the envoy-golang.yaml config file.
make run
Test
# use default build options for testing
make test-envoy
# add more build options for testing
build_opts=""
make build-envoy BUILD_OPTS=$build_opts
Design
Memory Safety
Users use Go as normal, do not need to care about memory safety.
- Go objects from these APIs, come from Go GC manager.
- Copy memory from envoy on demand, for performance.
- Go could only touch Envoy memory before OnDestroy.
Concurrency Safety
Go side
We support async(goroutine) in the Go side, and streaming. But, users do not need to care about the conncurrency in go side.
We buffer the data (with watermark) in Envoy (C++) side, until the Go returns. So, there is no concurrency in Go side, except OnDestory
.
Envoy side
Go code may run in Go thread (not the safe enovy thread), since we support goroutine.
In honesty, this breaks the Enovy thread-safe model.
But, users do not need to care about if the code is running Go thread or not.
- For
Data
we always consume data from filtermanager
to private BufferInstance
, so there won't be concurrency conflict between Go and Envoy, even without lock.
- For
HeaderMap
and TrailerMap
Now, no lock with optimism.
Go only read Envoy memory in Go thread, before the headers or trailers continue to the next filter.
Yeah, We are optimistic that other filters will not write headers or trailers when they are not processing them.
Write operations still happens in Envoy safe thread.
If we are proven wrong, we will add lock for them.
Sandbox Safety
Go code may cause panic, leads to breaking down the whole Envoy process, when there is dangerous code. i.e. concurrent write on a map.
Now, the users should care about the risk, align to users develop a filter using C++, or users develop a service using Go.
In the feature, we may provide a Go release which support sandbox safety.