Skip to content
This repository was archived by the owner on Apr 24, 2025. It is now read-only.

Commit e31ba70

Browse files
authored
Merge pull request #62 from tetratelabs/wasi-tinygo
use nightly TinyGo: WASI supported version
2 parents 1f21029 + 2db13e1 commit e31ba70

File tree

13 files changed

+161
-87
lines changed

13 files changed

+161
-87
lines changed

.github/workflows/workflow.yaml

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,13 @@ jobs:
2626
name: build examples
2727
runs-on: ubuntu-latest
2828
container:
29-
image: tinygo/tinygo:0.15.0
29+
image: getenvoy/extension-tinygo-builder:wasi-dev
3030
steps:
3131
- name: checkout
3232
uses: actions/checkout@v2
3333

34-
- name: set up go 1.15
35-
uses: actions/setup-go@v1
36-
with:
37-
go-version: 1.15
38-
3934
- name: build examples
40-
run: find ./examples -type f -name "main.go" | xargs -Ip tinygo build -o p.wasm -target=wasm -wasm-abi=generic p
35+
run: make build.examples
4136

4237
- name: upload wasm-binaries
4338
uses: actions/upload-artifact@v2

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ build.example:
1010
tinygo build -o ./examples/${name}/main.go.wasm -target=wasm -wasm-abi=generic ./examples/${name}/main.go
1111

1212
build.examples:
13-
find ./examples -type f -name "main.go" | xargs -Ip tinygo build -o p.wasm -target=wasm -wasm-abi=generic p
13+
find ./examples -type f -name "main.go" | xargs -Ip tinygo build -o p.wasm -target=wasi -wasm-abi=generic p
1414

1515
lint:
1616
golangci-lint run --build-tags proxytest

README.md

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,22 @@ func (ctx *context) OnHttpRequestHeaders(int, bool) types.Action {
3535

3636
```
3737

38-
3938
### requirements
4039

41-
- TinyGo(0.15.0+): https://tinygo.org
40+
proxy-wasm-go-sdk depends on the latest TinyGo which supports WASI target([tinygo-org/tinygo#1373](https://github.com/tinygo-org/tinygo/pull/1373)).
41+
In order to install that, simply run (Ubuntu/Debian):
42+
43+
```shell
44+
# this corresponds to https://github.com/tinygo-org/tinygo/commit/f50ad3585d084b17f7754f4b3cb0d42661fee036
45+
wget https://19227-136505169-gh.circle-artifacts.com/0/tmp/tinygo_amd64.deb
46+
dpkg -i tinygo_amd64.deb
47+
```
48+
49+
Alternatively, you can use the pre-built docker container `getenvoy/extention-tingyo-builder:wasi-dev` for any platform.
50+
51+
TinyGo's official release of WASI target will be soon, and after that you could
52+
just follow https://tinygo.org/getting-started/ to install the requirement. Stay tuned!
53+
4254

4355
### compatible Envoy builds
4456

@@ -73,19 +85,13 @@ make test # run local tests without running envoy processes
7385
make test.e2e # run e2e tests
7486
```
7587

76-
## language and compiler limitations/considerations
88+
## compiler limitations and considerations
7789

78-
- You can only use really limited set of existing libraries.
90+
- Some of existing libraries are not available (importable but runtime panic / non-importable)
7991
- There are two reasons for this:
80-
1. TinyGo [uses](https://github.com/tinygo-org/tinygo/blob/release/loader/loader.go#L79-L83) the official parser, lexer, etc.,
81-
which forces your program to implicitly import `syscall/js` package if you import packages using system calls.
82-
The package expects the host environment to have the `syscall/js` specific ABI as in
83-
[wasm_exec.js](https://github.com/tinygo-org/tinygo/blob/154d4a781f6121bd6f584cca4a88909e0b091f63/targets/wasm_exec.js)
84-
which is not available outside of that javascript.
92+
1. TinyGo's WASI target does not support some of syscall: For example, we cannot import `crypto/rand` package.
8593
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)).
86-
- The syscall problem can be solved by one of the followings:
87-
- emulate `syscall/js` function through WASI interface (which is implemented by V8 engine running on Envoy)
88-
- support WASI target in TinyGo: https://github.com/tinygo-org/tinygo/pull/1373
94+
- These issues will be mitigated as the TinyGo improves.
8995
- There's performance overhead in using Go/TinyGo due to GC
9096
- runtime.GC() is called whenever heap allocation happens (see [1](https://tinygo.org/lang-support/#garbage-collection),
9197
[2](https://github.com/tinygo-org/tinygo/blob/v0.14.1/src/runtime/gc_conservative.go#L218-L239)).

examples/helloworld/main.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
package main
1616

1717
import (
18-
"strconv"
19-
2018
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
2119
)
2220

@@ -40,14 +38,13 @@ func newHelloWorld(contextID uint32) proxywasm.RootContext {
4038
func (ctx *helloWorld) OnVMStart(int) bool {
4139
proxywasm.LogInfo("proxy_on_vm_start from Go!")
4240
if err := proxywasm.HostCallSetTickPeriodMilliSeconds(tickMilliseconds); err != nil {
43-
proxywasm.LogCritical("failed to set tick period: ", err.Error())
41+
proxywasm.LogCriticalf("failed to set tick period: %v", err)
4442
}
4543
return true
4644
}
4745

4846
// override
4947
func (ctx *helloWorld) OnTick() {
5048
t := proxywasm.HostCallGetCurrentTime()
51-
proxywasm.LogInfo("OnTick on ", strconv.FormatUint(uint64(ctx.contextID), 10),
52-
", it's ", strconv.FormatInt(t, 10))
49+
proxywasm.LogInfof("OnTick on %d, it's %d", ctx.contextID, t)
5350
}

examples/http_auth_random/main.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ package main
1616

1717
import (
1818
"hash/fnv"
19-
"strconv"
2019

2120
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
2221
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
@@ -42,19 +41,19 @@ func newContext(contextID uint32) proxywasm.HttpContext {
4241
func (ctx *httpHeaders) OnHttpRequestHeaders(int, bool) types.Action {
4342
hs, err := proxywasm.HostCallGetHttpRequestHeaders()
4443
if err != nil {
45-
proxywasm.LogCritical("failed to get request headers: ", err.Error())
44+
proxywasm.LogCriticalf("failed to get request headers: %v", err)
4645
return types.ActionContinue
4746
}
4847
for _, h := range hs {
49-
proxywasm.LogInfo("request header: ", h[0], ": ", h[1])
48+
proxywasm.LogInfof("request header from: %s: %s", h[0], h[1])
5049
}
5150

5251
if _, err := proxywasm.HostCallDispatchHttpCall(
5352
clusterName, hs, "", [][2]string{}, 50000); err != nil {
54-
proxywasm.LogCritical("dipatch httpcall failed: ", err.Error())
53+
proxywasm.LogCriticalf("dipatch httpcall failed: %v", err)
5554
}
5655

57-
proxywasm.LogInfo("http call dispatched to ", clusterName)
56+
proxywasm.LogInfof("http call dispatched to %s", clusterName)
5857

5958
return types.ActionPause
6059
}
@@ -63,24 +62,25 @@ func (ctx *httpHeaders) OnHttpRequestHeaders(int, bool) types.Action {
6362
func (ctx *httpHeaders) OnHttpCallResponse(_ int, bodySize int, _ int) {
6463
hs, err := proxywasm.HostCallGetHttpCallResponseHeaders()
6564
if err != nil {
66-
proxywasm.LogCritical("failed to get response body: ", err.Error())
65+
66+
proxywasm.LogCriticalf("failed to get response body: %v", err)
6767
return
6868
}
6969

7070
for _, h := range hs {
71-
proxywasm.LogInfo("response header from httpbin: ", h[0], ": ", h[1])
71+
proxywasm.LogInfof("response header from %s: %s: %s", clusterName, h[0], h[1])
7272
}
7373

7474
b, err := proxywasm.HostCallGetHttpCallResponseBody(0, bodySize)
7575
if err != nil {
76-
proxywasm.LogCritical("failed to get response body: ", err.Error())
76+
proxywasm.LogCriticalf("failed to get response body: %v", err)
7777
proxywasm.HostCallResumeHttpRequest()
7878
return
7979
}
8080

8181
s := fnv.New32a()
8282
if _, err := s.Write(b); err != nil {
83-
proxywasm.LogCritical("failed to calculate hash: ", err.Error())
83+
proxywasm.LogCriticalf("failed to calculate hash: %v", err)
8484
proxywasm.HostCallResumeHttpRequest()
8585
return
8686
}
@@ -100,5 +100,5 @@ func (ctx *httpHeaders) OnHttpCallResponse(_ int, bodySize int, _ int) {
100100

101101
// override default
102102
func (ctx *httpHeaders) OnLog() {
103-
proxywasm.LogInfo(strconv.FormatUint(uint64(ctx.contextID), 10), " finished")
103+
proxywasm.LogInfof("%d finished", ctx.contextID)
104104
}

examples/http_headers/main.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
package main
1616

1717
import (
18-
"strconv"
19-
2018
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
2119
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
2220
)
@@ -39,11 +37,11 @@ func newContext(contextID uint32) proxywasm.HttpContext {
3937
func (ctx *httpHeaders) OnHttpRequestHeaders(int, bool) types.Action {
4038
hs, err := proxywasm.HostCallGetHttpRequestHeaders()
4139
if err != nil {
42-
proxywasm.LogCritical("failed to get request headers: ", err.Error())
40+
proxywasm.LogCriticalf("failed to get request headers: %v", err)
4341
}
4442

4543
for _, h := range hs {
46-
proxywasm.LogInfo("request header: ", h[0], ": ", h[1])
44+
proxywasm.LogInfof("request header: %s: %s", h[0], h[1])
4745
}
4846
return types.ActionContinue
4947
}
@@ -52,16 +50,16 @@ func (ctx *httpHeaders) OnHttpRequestHeaders(int, bool) types.Action {
5250
func (ctx *httpHeaders) OnHttpResponseHeaders(int, bool) types.Action {
5351
hs, err := proxywasm.HostCallGetHttpResponseHeaders()
5452
if err != nil {
55-
proxywasm.LogCritical("failed to get request headers: ", err.Error())
53+
proxywasm.LogCriticalf("failed to get request headers: %v", err)
5654
}
5755

5856
for _, h := range hs {
59-
proxywasm.LogInfo("response header: ", h[0], ": ", h[1])
57+
proxywasm.LogInfof("response header: %s: %s", h[0], h[1])
6058
}
6159
return types.ActionContinue
6260
}
6361

6462
// override
6563
func (ctx *httpHeaders) OnLog() {
66-
proxywasm.LogInfo(strconv.FormatUint(uint64(ctx.contextID), 10), " finished")
64+
proxywasm.LogInfof("%d finished", ctx.contextID)
6765
}

examples/metrics/main.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
package main
1616

1717
import (
18-
"strconv"
19-
2018
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
2119
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
2220
)
@@ -36,7 +34,7 @@ type metric struct{ proxywasm.DefaultContext }
3634
func (ctx metric) OnVMStart(int) bool {
3735
ct, err := proxywasm.DefineCounterMetric(metricsName)
3836
if err != nil {
39-
proxywasm.LogCritical("error defining metrics: ", err.Error())
37+
proxywasm.LogCriticalf("error defining metrics: %v", err)
4038
}
4139
counter = ct
4240
return true
@@ -46,13 +44,13 @@ func (ctx metric) OnVMStart(int) bool {
4644
func (ctx metric) OnHttpRequestHeaders(int, bool) types.Action {
4745
prev, err := counter.Get()
4846
if err != nil {
49-
proxywasm.LogCritical("error retrieving previous metric: ", err.Error())
47+
proxywasm.LogCriticalf("error retrieving previous metric: %v", err)
5048
}
5149

52-
proxywasm.LogInfo("previous value of ", metricsName, ": ", strconv.Itoa(int(prev)))
50+
proxywasm.LogInfof("previous value of %s: %d", metricsName, prev)
5351

5452
if err := counter.Increment(1); err != nil {
55-
proxywasm.LogCritical("error incrementing metrics", err.Error())
53+
proxywasm.LogCriticalf("error incrementing metrics %v", err)
5654
}
5755
proxywasm.LogInfo("incremented")
5856
return types.ActionContinue

examples/network/main.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func (ctx context) OnVMStart(int) bool {
3535
var err error
3636
counter, err = proxywasm.DefineCounterMetric(connectionCounterName)
3737
if err != nil {
38-
proxywasm.LogCritical("failed to initialize connection counter: ", err.Error())
38+
proxywasm.LogCriticalf("failed to initialize connection counter: %v", err)
3939
}
4040
return true
4141
}
@@ -57,7 +57,7 @@ func (ctx context) OnDownstreamData(dataSize int, _ bool) types.Action {
5757
proxywasm.LogCritical(err.Error())
5858
}
5959

60-
proxywasm.LogInfo("downstream data received: ", string(data))
60+
proxywasm.LogInfof("downstream data received: %s", string(data))
6161
return types.ActionContinue
6262
}
6363

@@ -72,7 +72,7 @@ func (ctx context) OnUpstreamData(dataSize int, _ bool) types.Action {
7272
proxywasm.LogCritical(err.Error())
7373
}
7474

75-
proxywasm.LogInfo("remote address: ", string(ret))
75+
proxywasm.LogInfof("remote address: %s", string(ret))
7676
if dataSize == 0 {
7777
return types.ActionContinue
7878
}
@@ -82,14 +82,14 @@ func (ctx context) OnUpstreamData(dataSize int, _ bool) types.Action {
8282
proxywasm.LogCritical(err.Error())
8383
}
8484

85-
proxywasm.LogInfo("upstream data received: ", string(data))
85+
proxywasm.LogInfof("upstream data received: %s", string(data))
8686
return types.ActionContinue
8787
}
8888

8989
func (ctx context) OnDone() bool {
9090
err := counter.Increment(1)
9191
if err != nil {
92-
proxywasm.LogCritical("failed to increment connection counter: ", err.Error())
92+
proxywasm.LogCriticalf("failed to increment connection counter: %v", err)
9393
}
9494
proxywasm.LogInfo("connection complete!")
9595
return true

examples/shared_data/main.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
package main
1616

1717
import (
18-
"strconv"
19-
2018
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
2119
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
2220
)
@@ -33,7 +31,7 @@ const sharedDataKey = "shared_data_key"
3331
// override
3432
func (ctx data) OnVMStart(int) bool {
3533
if err := proxywasm.HostCallSetSharedData(sharedDataKey, []byte{0}, 0); err != nil {
36-
proxywasm.LogWarn("error setting shared data on OnVMStart: ", err.Error())
34+
proxywasm.LogWarnf("error setting shared data on OnVMStart: %v", err)
3735
}
3836
return true
3937
}
@@ -42,16 +40,16 @@ func (ctx data) OnVMStart(int) bool {
4240
func (ctx data) OnHttpRequestHeaders(int, bool) types.Action {
4341
value, cas, err := proxywasm.HostCallGetSharedData(sharedDataKey)
4442
if err != nil {
45-
proxywasm.LogWarn("error getting shared data on OnHttpRequestHeaders: ", err.Error())
43+
proxywasm.LogWarnf("error getting shared data on OnHttpRequestHeaders: %v", err)
4644
return types.ActionContinue
4745
}
4846

4947
value[0]++
5048
if err := proxywasm.HostCallSetSharedData(sharedDataKey, value, cas); err != nil {
51-
proxywasm.LogWarn("error setting shared data on OnHttpRequestHeaders: ", err.Error())
49+
proxywasm.LogWarnf("error setting shared data on OnHttpRequestHeaders: %v", err)
5250
return types.ActionContinue
5351
}
5452

55-
proxywasm.LogInfo("shared value: ", strconv.Itoa(int(value[0])))
53+
proxywasm.LogInfof("shared value: %d", value[0])
5654
return types.ActionContinue
5755
}

examples/shared_queue/main.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
package main
1616

1717
import (
18-
"strconv"
19-
2018
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
2119
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
2220
)
@@ -42,20 +40,20 @@ func (ctx queue) OnVMStart(int) bool {
4240
panic(err.Error())
4341
}
4442
queueID = qID
45-
proxywasm.LogInfo("queue registered, name: ", queueName, ", id: ", strconv.Itoa(int(qID)))
43+
proxywasm.LogInfof("queue registered, name: %s, id: %d", queueName, qID)
4644

4745
if err := proxywasm.HostCallSetTickPeriodMilliSeconds(tickMilliseconds); err != nil {
48-
proxywasm.LogCritical("failed to set tick period: ", err.Error())
46+
proxywasm.LogCriticalf("failed to set tick period: %v", err)
4947
}
50-
proxywasm.LogInfo("set tick period milliseconds: ", strconv.Itoa(int(tickMilliseconds)))
48+
proxywasm.LogInfof("set tick period milliseconds: %d", tickMilliseconds)
5149
return true
5250
}
5351

5452
// override
5553
func (ctx queue) OnHttpRequestHeaders(int, bool) types.Action {
5654
for _, msg := range []string{"hello", "world", "hello", "proxy-wasm"} {
5755
if err := proxywasm.HostCallEnqueueSharedQueue(queueID, []byte(msg)); err != nil {
58-
proxywasm.LogCritical("error queueing: ", err.Error())
56+
proxywasm.LogCriticalf("error queueing: %v", err)
5957
}
6058
}
6159
return types.ActionContinue
@@ -68,8 +66,8 @@ func (ctx queue) OnTick() {
6866
case types.ErrorStatusEmpty:
6967
return
7068
case nil:
71-
proxywasm.LogInfo("dequeued data: ", string(data))
69+
proxywasm.LogInfof("dequeued data: %s", string(data))
7270
default:
73-
proxywasm.LogCritical("error retrieving data from queue ", strconv.Itoa(int(queueID)), ", ", err.Error())
71+
proxywasm.LogCriticalf("error retrieving data from queue %d: %v", queueID, err)
7472
}
7573
}

0 commit comments

Comments
 (0)