Commit 97ab8fb
authored
fix(guard): wazero improvements — shutdown cache cleanup, operational log routing, ReadUint32Le (#4700)
Three improvements to wazero usage in `internal/guard/wasm.go`
identified by the Go Fan module review.
## Changes
- **Compilation cache cleanup on shutdown**: `globalCompilationCache`
was initialized at package startup but never closed in production. Added
`guard.CloseGlobalCompilationCache(ctx)` and wired it into
`InitiateShutdown` in `unified.go` after `guardRegistry.Close()`, so JIT
resources are released on graceful shutdown. Failure is logged at
`LogError` severity.
```go
// internal/guard/wasm.go
func CloseGlobalCompilationCache(ctx context.Context) error {
return globalCompilationCache.Close(ctx)
}
// internal/server/unified.go — after guardRegistry.Close()
if err := guard.CloseGlobalCompilationCache(context.Background()); err
!= nil {
logger.LogError("shutdown", "Failed to close WASM compilation cache:
%v", err)
}
```
- **WASM warn/error → operational file logger**: `hostLog` previously
sent all levels only to the debug logger (`logWasm`). `warn` and `error`
now additionally call `logger.LogWarn`/`logger.LogError`, surfacing
guard signals in `mcp-gateway.log` and `gateway.md`.
- **Replace manual LE uint32 decode with `mem.ReadUint32Le()`**: Two
duplicated bit-shift decodes in `tryCallWasmFunction` (allocator path
and fallback path) replaced with the wazero typed helper, eliminating
the intermediate byte-slice read.
```go
// Before
if sizeBytes, ok := mem.Read(outputPtr, 4); ok && len(sizeBytes) == 4 {
requiredSize := uint32(sizeBytes[0]) | uint32(sizeBytes[1])<<8 |
uint32(sizeBytes[2])<<16 | uint32(sizeBytes[3])<<24
// After
if requiredSize, ok := mem.ReadUint32Le(outputPtr); ok && requiredSize >
0 {
```
> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `example.com`
> - Triggering command: `/tmp/go-build463346707/b513/launcher.test
/tmp/go-build463346707/b513/launcher.test
-test.testlogfile=/tmp/go-build463346707/b513/testlog.txt
-test.paniconexit0 -test.timeout=10m0s
/tmp/go-build463346707/b450/vet.cfg _.a
elemetry.io/otel@v1.43.0/semconv/v1.40.0/doc.go x_amd64/vet --gdwarf-5
--64 -o x_amd64/vet -I q8V2zTN1V -I x_amd64/vet --gdwarf-5
.io/otel/metric -o x_amd64/vet` (dns block)
> - Triggering command: `/tmp/go-build192150560/b509/launcher.test
/tmp/go-build192150560/b509/launcher.test
-test.testlogfile=/tmp/go-build192150560/b509/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
lib/rustlib/x86_64-REDACTED-linux-gnu/lib/libobject-926daa94a00ee327.rlib
lib/rustlib/x86_64-REDACTED-linux-gnu/lib/libmemchr-48d5b0db80402653.rlib
lib/rustlib/x86_64-REDACTED-linux-gnu/lib/libaddr2line-3367f26bd486b29d.rlib
lib/rustlib/x86_go .0y4p35u.rcgu.o .0y4p35u.rcgu.o .0y4p35u.rcgu.o
.0y4�� .0y4p35u.rcgu.o .0y4p35u.rcgu.o .0y4p35u.rcgu.o .0y4p35u.rcgu.o
.0y4p35u.rcgu.o .0y4p35u.rcgu.o .0y4p35u.rcgu.o` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build463346707/b495/config.test
/tmp/go-build463346707/b495/config.test
-test.testlogfile=/tmp/go-build463346707/b495/testlog.txt
-test.paniconexit0 -test.timeout=10m0s
/tmp/go-build463346707/b393/vet.cfg
1.80.0/internal/resolver/config_selector.go 236262/b151/ x_amd64/vet
--gdwarf-5 go-sdk/internal/-atomic -o x_amd64/vet 2362�� _.a
ache/go/1.25.9/x-ifaceassert x_amd64/vet 236262/b151/ --64` (dns block)
> - Triggering command: `/tmp/go-build192150560/b491/config.test
/tmp/go-build192150560/b491/config.test
-test.testlogfile=/tmp/go-build192150560/b491/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
-guard/target/de/home/REDACTED/work/gh-aw-mcpg/gh-aw-mcpg/guards/github-guard/rust-guard/target/degit
-guard/target/de/home/REDACTED/work/gh-aw-mcpg/gh-aw-mcpg/guards/github-guard/rust-guard/target/de-c
-guard/target/de/home/REDACTED/work/gh-aw-mcpg/gh-aw-mcpg/guards/github-guard/rust-guard/target/delog.showsignature=false
ntime.v2.task/mogit f07e34dca1.buildrev-parse lib/rustlib/x86_HEAD
lib/rustlib/x86_/home/REDACTED/work/gh-aw-mcpg/gh-aw-mcpg/guards/github-guard/rust-guard/target/de--format=format:%H
%ct %D lib/��
lib/rustlib/x86_/home/REDACTED/work/gh-aw-mcpg/gh-aw-mcpg/guards/github-guard/rust-guard/target/de/opt/hostedtoolcache/go/1.25.9/x64/pkg/tool/linux_amd64/vet
lib/rustlib/x86_/home/REDACTED/work/gh-aw-mcpg/gh-aw-mcpg/guards/github-guard/rust-guard/target/de/tmp/go-build2805575210/b498/vet.cfg
lib/rustlib/x86_/home/REDACTED/work/gh-aw-mcpg/gh-aw-mcpg/guards/github-guard/rust-guard/target/debug/deps/github_guard-57d41235e07a5585.3ky4jndxwogptk4p3m4cqblia.0y4p35u.rcgu.o
lib/rustlib/x86_/opt/hostedtoolcache/CodeQL/2.25.1/x64/codeql/codeql
lib/rustlib/x86_database lib/rustlib/x86_analyze
lib/rustlib/x86_--ram=14575` (dns block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build463346707/b513/launcher.test
/tmp/go-build463346707/b513/launcher.test
-test.testlogfile=/tmp/go-build463346707/b513/testlog.txt
-test.paniconexit0 -test.timeout=10m0s
/tmp/go-build463346707/b450/vet.cfg _.a
elemetry.io/otel@v1.43.0/semconv/v1.40.0/doc.go x_amd64/vet --gdwarf-5
--64 -o x_amd64/vet -I q8V2zTN1V -I x_amd64/vet --gdwarf-5
.io/otel/metric -o x_amd64/vet` (dns block)
> - Triggering command: `/tmp/go-build192150560/b509/launcher.test
/tmp/go-build192150560/b509/launcher.test
-test.testlogfile=/tmp/go-build192150560/b509/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
lib/rustlib/x86_64-REDACTED-linux-gnu/lib/libobject-926daa94a00ee327.rlib
lib/rustlib/x86_64-REDACTED-linux-gnu/lib/libmemchr-48d5b0db80402653.rlib
lib/rustlib/x86_64-REDACTED-linux-gnu/lib/libaddr2line-3367f26bd486b29d.rlib
lib/rustlib/x86_go .0y4p35u.rcgu.o .0y4p35u.rcgu.o .0y4p35u.rcgu.o
.0y4�� .0y4p35u.rcgu.o .0y4p35u.rcgu.o .0y4p35u.rcgu.o .0y4p35u.rcgu.o
.0y4p35u.rcgu.o .0y4p35u.rcgu.o .0y4p35u.rcgu.o` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build463346707/b513/launcher.test
/tmp/go-build463346707/b513/launcher.test
-test.testlogfile=/tmp/go-build463346707/b513/testlog.txt
-test.paniconexit0 -test.timeout=10m0s
/tmp/go-build463346707/b450/vet.cfg _.a
elemetry.io/otel@v1.43.0/semconv/v1.40.0/doc.go x_amd64/vet --gdwarf-5
--64 -o x_amd64/vet -I q8V2zTN1V -I x_amd64/vet --gdwarf-5
.io/otel/metric -o x_amd64/vet` (dns block)
> - Triggering command: `/tmp/go-build192150560/b509/launcher.test
/tmp/go-build192150560/b509/launcher.test
-test.testlogfile=/tmp/go-build192150560/b509/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
lib/rustlib/x86_64-REDACTED-linux-gnu/lib/libobject-926daa94a00ee327.rlib
lib/rustlib/x86_64-REDACTED-linux-gnu/lib/libmemchr-48d5b0db80402653.rlib
lib/rustlib/x86_64-REDACTED-linux-gnu/lib/libaddr2line-3367f26bd486b29d.rlib
lib/rustlib/x86_go .0y4p35u.rcgu.o .0y4p35u.rcgu.o .0y4p35u.rcgu.o
.0y4�� .0y4p35u.rcgu.o .0y4p35u.rcgu.o .0y4p35u.rcgu.o .0y4p35u.rcgu.o
.0y4p35u.rcgu.o .0y4p35u.rcgu.o .0y4p35u.rcgu.o` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build463346707/b522/mcp.test
/tmp/go-build463346707/b522/mcp.test
-test.testlogfile=/tmp/go-build463346707/b522/testlog.txt
-test.paniconexit0 -test.timeout=10m0s 2362�� .cfg
om/tetratelabs/w-ifaceassert x_amd64/vet . --gdwarf2 --64 x_amd64/vet
.cfg�� 236262/b381/_pkg_.a -fPIC x_amd64/vet -pthread
g/grpc/experimen--version -fmessage-length=0 x_amd64/vet` (dns block)
> - Triggering command: `/tmp/go-build192150560/b518/mcp.test
/tmp/go-build192150560/b518/mcp.test
-test.testlogfile=/tmp/go-build192150560/b518/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
st-guard/target/debug/deps/rustc0bKEfQ/raw-dylibs
u/lib/rustlib/x86_64-REDACTED-linux-gnu/lib
known-linux-gnu/lib/rustlib/x86_64-REDACTED-linux-gnu/bin/rust-lld
ithub-guard/rustbash cf4be8585821fe3f/usr/bin/runc ild
known-linux-gnu/lib/rustlib/x86_diff know��
known-linux-gnu/lib/rustlib/x86_--irreversible-delete ild in.so
/lto-wrapper known-linux-gnu/info
known-linux-gnu/lib/rustlib/x86_log.showsignature=false
known-linux-gnu/lib/rustlib/x86_log` (dns block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/github/gh-aw-mcpg/settings/copilot/coding_agent)
(admins only)
>
> </details>2 files changed
Lines changed: 20 additions & 10 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
28 | 37 | | |
29 | 38 | | |
30 | 39 | | |
| |||
310 | 319 | | |
311 | 320 | | |
312 | 321 | | |
| 322 | + | |
313 | 323 | | |
314 | 324 | | |
| 325 | + | |
315 | 326 | | |
316 | 327 | | |
317 | 328 | | |
| |||
972 | 983 | | |
973 | 984 | | |
974 | 985 | | |
975 | | - | |
976 | | - | |
977 | | - | |
978 | | - | |
979 | | - | |
| 986 | + | |
| 987 | + | |
980 | 988 | | |
981 | 989 | | |
982 | 990 | | |
| |||
1039 | 1047 | | |
1040 | 1048 | | |
1041 | 1049 | | |
1042 | | - | |
1043 | | - | |
1044 | | - | |
1045 | | - | |
1046 | | - | |
| 1050 | + | |
| 1051 | + | |
1047 | 1052 | | |
1048 | 1053 | | |
1049 | 1054 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
809 | 809 | | |
810 | 810 | | |
811 | 811 | | |
| 812 | + | |
| 813 | + | |
| 814 | + | |
| 815 | + | |
| 816 | + | |
812 | 817 | | |
813 | 818 | | |
814 | 819 | | |
| |||
0 commit comments