Skip to content

Commit ad0b327

Browse files
authored
Refactor towards End-use doc. (tetratelabs#190)
Signed-off-by: Takeshi Yoneda <[email protected]>
1 parent e9861eb commit ad0b327

File tree

25 files changed

+550
-696
lines changed

25 files changed

+550
-696
lines changed

README.md

Lines changed: 22 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -3,58 +3,19 @@ __This project is in its early stage, and the API is likely to change and not st
33
# WebAssembly for Proxies (Go SDK) [![Build](https://github.com/tetratelabs/proxy-wasm-go-sdk/workflows/test/badge.svg)](https://github.com/tetratelabs/proxy-wasm-go-sdk/actions) [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
44

55
The Go SDK for
6-
[Proxy-Wasm](https://github.com/proxy-wasm/spec), enabling developers to write Proxy-Wasm extensions in Go.
7-
6+
[Proxy-Wasm](https://github.com/proxy-wasm/spec), enabling developers to write Proxy-Wasm plugins in Go.
87
This SDK is powered by [TinyGo](https://tinygo.org/) and does not support the official Go compiler.
98

10-
```golang
11-
import (
12-
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
13-
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
14-
)
15-
16-
type vmContext struct{}
17-
18-
// Implement types.VMContext.
19-
func (*vmContext) NewPluginContext(contextID uint32) types.PluginContext {
20-
return &pluginContext{}
21-
}
22-
23-
type pluginContext struct {
24-
counter proxywasm.MetricCounter
25-
}
26-
27-
// Implement types.PluginContext.
28-
func (*pluginContext) NewHttpContext(contextID uint32) types.HttpContext {
29-
return &httpContext{counter: proxywasm.DefineCounterMetric("proxy_wasm_go.request_counter")}
30-
}
31-
32-
type httpContext struct {
33-
counter proxywasm.MetricCounter
34-
}
35-
36-
// Implement types.HttpContext.
37-
func (ctx *httpContext) OnHttpRequestHeaders(int, bool) types.Action {
38-
// Increment the request counter when we receive request headers.
39-
ctx.counter.Increment(1)
40-
return types.ActionContinue
41-
}
42-
```
43-
44-
## Requirements
45-
46-
This SDK depends on TinyGo and leverages its [WASI](https://github.com/WebAssembly/WASI) (WebAssembly System Interface) target.
9+
## Getting Started
4710

48-
Please follow the official instruction [here](https://tinygo.org/getting-started/) for installing TinyGo.
11+
- [examples](examples) directory contains the example codes on top of this SDK.
4912

50-
### Compatible ABI / Envoy builds (tested on CI)
13+
## Requirements
5114

52-
| proxy-wasm-go-sdk| proxy-wasm ABI version |istio/proxyv2| Envoy upstream|
53-
|:-------------:|:-------------:|:-------------:|:-------------:|
54-
| main | 0.2.0| 1.9, 1.10 | 1.18 |
55-
| v0.3.0 | 0.2.0| 1.9, 1.10 | 1.18 |
15+
- [TinyGo](https://tinygo.org/) - This SDK depends on TinyGo and leverages its [WASI](https://github.com/WebAssembly/WASI) (WebAssembly System Interface) target. Please follow the official instruction [here](https://tinygo.org/getting-started/) for installing TinyGo.
16+
- [Envoy](https://www.envoyproxy.io) - To run compiled examples, you need to have Envoy binary. Please follow [the official instruction](https://www.envoyproxy.io/docs/envoy/latest/start/install).
5617

57-
## Development
18+
## Build and run Examples
5819

5920
```bash
6021
# Build all examples.
@@ -64,48 +25,28 @@ make build.examples
6425
make build.example name=helloworld
6526

6627
# Run a specific example.
67-
# This requires you to have Envoy binary locally.
6828
make run name=helloworld
29+
```
6930

70-
# Run local tests without running envoy processes.
71-
make test
31+
## Compatible Envoy builds (tested on CI)
7232

73-
# Run all e2e tests.
74-
# This requires you to have Envoy binary locally.
75-
make test.e2e
33+
Envoy is the first host side implementation of Proxy-Wasm ABI,
34+
and we run end-to-end tests with multiple Envoy versions in order to verify Proxy-Wasm Go SDK works as expected.
7635

77-
# Run e2e tests for a specific example.
78-
# This requires you to have Envoy binary locally.
79-
make test.e2e.single name=helloworld
80-
```
36+
| proxy-wasm-go-sdk| istio/proxyv2| Envoy upstream|
37+
|:-------------:|:-------------:|:-------------:|
38+
| main | 1.9, 1.10 | 1.18 |
39+
| v0.3.0 | 1.9, 1.10 | 1.18 |
40+
41+
## Contributing
42+
43+
We welcome contributions from the community! See [CONTRIBUTING.md](doc/CONTRIBUTING.md) for how to contribute to this repository.
8144

82-
## Limitations and Considerations
83-
84-
- Some of existing libraries are not available (importable but runtime panic / non-importable)
85-
- There are several reasons for this:
86-
1. TinyGo's WASI target does not support some of syscall: For example, we cannot import `crypto/rand` package.
87-
2. TinyGo does not implement all of reflect package([examples](https://github.com/tinygo-org/tinygo/blob/v0.14.1/src/reflect/value.go#L299-L305)).
88-
3. [proxy-wasm-cpp-host](https://github.com/proxy-wasm/proxy-wasm-cpp-host) has not supported some of WASI APIs yet
89-
- These issues will be mitigated as TinyGo and proxy-wasm-cpp-host evolve.
90-
- There's performance overhead of using Go/TinyGo due to GC
91-
- `runtime.GC` is called whenever the heap runs out (see [1](https://tinygo.org/lang-support/#garbage-collection),
92-
[2](https://github.com/tinygo-org/tinygo/blob/v0.14.1/src/runtime/gc_conservative.go#L218-L239)).
93-
- TinyGo allows us to disable GC, but we cannot do that since we need to use maps (implicitly causes allocation)
94-
for saving the plugin's [state](https://github.com/tetratelabs/proxy-wasm-go-sdk/blob/cf6ad74ed58b284d3d8ceeb8c5dba2280d5b1007/proxywasm/vmstate.go#L41-L46).
95-
- Theoretically, we can implement our own GC algorithms tailored for proxy-wasm through `alloc(uintptr)` [interface](https://github.com/tinygo-org/tinygo/blob/v0.14.1/src/runtime/gc_none.go#L13)
96-
with `-gc=none` option. This is the future TODO.
97-
- `recover` is [not implemented](https://github.com/tinygo-org/tinygo/issues/891) in TinyGo, and there's no way to prevent the Wasm virtual machine from aborting.
98-
- Goroutine support
99-
- In TinyGo, Goroutine is implmeneted through LLVM's coroutine (see [this blog post](https://aykevl.nl/2019/02/tinygo-goroutines)).
100-
- In Envoy, Wasm modules are run in the event driven manner, and therefore the "scheduler" is not executed once the main function exits.
101-
That means you cannot have the expected behavior of Goroutine as in ordinary host environments.
102-
- The question "How to deal with Goroutine in a thread local Wasm VM executed in the event drive manner" has yet to be answered.
103-
- We strongly recommend that you implement the `OnTick` function for any asynchronous task instead of using Goroutine.
104-
- The scheduler can be disabled with `-scheduler=none` option of TinyGo.
105-
106-
## References
45+
## External links
10746

10847
- [WebAssembly for Proxies (ABI specification)](https://github.com/proxy-wasm/spec)
48+
- [WebAssembly for Proxies (AssemblyScript SDK)](https://github.com/solo-io/proxy-runtime)
10949
- [WebAssembly for Proxies (C++ SDK)](https://github.com/proxy-wasm/proxy-wasm-cpp-sdk)
11050
- [WebAssembly for Proxies (Rust SDK)](https://github.com/proxy-wasm/proxy-wasm-rust-sdk)
51+
- [WebAssembly for Proxies (Zig SDK)](https://github.com/mathetake/proxy-wasm-zig-sdk)
11152
- [TinyGo - Go compiler for small places](https://tinygo.org/)

doc/CONTRIBUTING.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Contributing
2+
3+
We welcome contributions from the community. Please read the following guidelines carefully to maximize the chances of your PR being merged.
4+
5+
## Coding Style
6+
7+
The code is linted using a stringent golang-ci. To run this linter (and a few others) use run `make check`. To format your files, you can run `make format`.
8+
9+
## Running tests
10+
11+
```
12+
# Run local tests without running envoy processes.
13+
make test
14+
15+
# Run all e2e tests.
16+
# This requires you to have Envoy binary locally.
17+
make test.e2e
18+
19+
# Run e2e tests for a specific example.
20+
# This requires you to have Envoy binary locally.
21+
make test.e2e.single name=helloworld
22+
```
23+
24+
## Code Reviews
25+
26+
* Indicate the priority of each comment, following this
27+
[feedback ladder](https://www.netlify.com/blog/2020/03/05/feedback-ladders-how-we-encode-code-reviews-at-netlify/).
28+
If none was indicated it will be treated as `[dust]`.
29+
* A single approval is sufficient to merge, except when the change cuts
30+
across several components; then it should be approved by at least one owner
31+
of each component. If a reviewer asks for changes in a PR they should be
32+
addressed before the PR is merged, even if another reviewer has already
33+
approved the PR.
34+
* During the review, address the comments and commit the changes _without_ squashing the commits.
35+
This facilitates incremental reviews since the reviewer does not go through all the code again to
36+
find out what has changed since the last review.

e2e/e2e_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ func Test_network(t *testing.T) {
220220
func Test_shared_data(t *testing.T) {
221221
stdErr, kill := startEnvoy(t, 8001)
222222
defer kill()
223-
var count int
223+
var count int = 10000000
224224
require.Eventually(t, func() bool {
225225
res, err := http.Get("http://localhost:18000")
226226
if err != nil {
@@ -231,7 +231,7 @@ func Test_shared_data(t *testing.T) {
231231
return false
232232
}
233233
count++
234-
return count == 10
234+
return count == 10000010
235235
}, 5*time.Second, time.Millisecond, "Endpoint not healthy.")
236236
require.Eventually(t, func() bool {
237237
return checkMessage(stdErr.String(), []string{fmt.Sprintf("shared value: %d", count)}, nil)

examples/dispatch_call_on_tick/main_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
// These tests are supposed to run with `proxytest` build tag, and this way we can leverage the testing framework in "proxytest" package.
2+
// The framework emulates the expected behavior of Envoyproxy, and you can test your extensions without running Envoy and with
3+
// the standard Go CLI. To run tests, simply run
4+
// go test -tags=proxytest ./...
5+
6+
//+build proxytest
7+
18
package main
29

310
import (

examples/foreign_call_on_tick/main_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
// These tests are supposed to run with `proxytest` build tag, and this way we can leverage the testing framework in "proxytest" package.
2+
// The framework emulates the expected behavior of Envoyproxy, and you can test your extensions without running Envoy and with
3+
// the standard Go CLI. To run tests, simply run
4+
// go test -tags=proxytest ./...
5+
6+
//+build proxytest
7+
18
package main
29

310
import (

examples/helloworld/main_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
// These tests are supposed to run with `proxytest` build tag, and this way we can leverage the testing framework in "proxytest" package.
2+
// The framework emulates the expected behavior of Envoyproxy, and you can test your extensions without running Envoy and with
3+
// the standard Go CLI. To run tests, simply run
4+
// go test -tags=proxytest ./...
5+
6+
//+build proxytest
7+
18
package main
29

310
import (

examples/http_auth_random/main_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
// These tests are supposed to run with `proxytest` build tag, and this way we can leverage the testing framework in "proxytest" package.
2+
// The framework emulates the expected behavior of Envoyproxy, and you can test your extensions without running Envoy and with
3+
// the standard Go CLI. To run tests, simply run
4+
// go test -tags=proxytest ./...
5+
6+
//+build proxytest
7+
18
package main
29

310
import (

examples/http_body/main_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
// These tests are supposed to run with `proxytest` build tag, and this way we can leverage the testing framework in "proxytest" package.
2+
// The framework emulates the expected behavior of Envoyproxy, and you can test your extensions without running Envoy and with
3+
// the standard Go CLI. To run tests, simply run
4+
// go test -tags=proxytest ./...
5+
6+
//+build proxytest
7+
18
package main
29

310
import (

examples/http_headers/main_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
// These tests are supposed to run with `proxytest` build tag, and this way we can leverage the testing framework in "proxytest" package.
2+
// The framework emulates the expected behavior of Envoyproxy, and you can test your extensions without running Envoy and with
3+
// the standard Go CLI. To run tests, simply run
4+
// go test -tags=proxytest ./...
5+
6+
//+build proxytest
7+
18
package main
29

310
import (

examples/http_routing/main_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
// These tests are supposed to run with `proxytest` build tag, and this way we can leverage the testing framework in "proxytest" package.
2+
// The framework emulates the expected behavior of Envoyproxy, and you can test your extensions without running Envoy and with
3+
// the standard Go CLI. To run tests, simply run
4+
// go test -tags=proxytest ./...
5+
6+
//+build proxytest
7+
18
package main
29

310
import (

0 commit comments

Comments
 (0)