Skip to content

perf: add wazero compilation cache and wasm guard improvements#2956

Merged
lpcox merged 2 commits intomainfrom
fix/wasm-guard-improvements-2829
Mar 31, 2026
Merged

perf: add wazero compilation cache and wasm guard improvements#2956
lpcox merged 2 commits intomainfrom
fix/wasm-guard-improvements-2829

Conversation

@lpcox
Copy link
Copy Markdown
Collaborator

@lpcox lpcox commented Mar 31, 2026

Problem

Go Fan report (#2829) identified several improvement opportunities in the wazero/WASM guard implementation: missing compilation cache, inconsistent Close() error handling, undocumented buffer retry protocol, and a redundant function export check.

Changes

All 6 findings addressed:

High Priority

# Finding Change
1 No compilation cache — each WasmGuard re-JITs the WASM binary Added globalCompilationCache (package-level, goroutine-safe) shared across all instances
2 No way to inject custom cache Added CompilationCache field to WasmGuardOptions

Medium Priority

# Finding Change
3 No TestMain for cache lifecycle Added TestMain that closes the global cache after tests

Low Priority (Quick Wins)

# Finding Change
4 Close() swallows module errors, only returns runtime errors Use errors.Join to surface both
5 Buffer retry protocol (-2 error code, adaptive growth) is undocumented Added strategy comment block in callWasmFunction
6 ExportedFunction("label_agent") checked redundantly in LabelAgent Removed — already verified at construction + inside callWasmFunction

Files Changed

File Change
internal/guard/wasm.go Cache, Close() fix, strategy comment, remove redundant check
internal/guard/wasm_test.go TestMain + 3 cache tests

Testing

make agent-finished passes. All changes are backward-compatible — existing callers that pass nil opts automatically benefit from the shared cache.

Closes #2829

Implement all findings from Go Fan report (#2829):

1. Process-level compilation cache: shared globalCompilationCache
   eliminates redundant JIT compilation across WasmGuard instances.
2. CompilationCache field in WasmGuardOptions: allows injection of
   custom caches for testing or per-deployment tuning.
3. TestMain with cache cleanup: properly closes the global cache
   after the test suite runs.
4. Consistent Close() error handling: use errors.Join to surface
   both module and runtime close errors instead of silently
   swallowing module errors.
5. Buffer retry strategy comment: documents the -2 error code
   convention and adaptive buffer growth protocol.
6. Remove redundant ExportedFunction("label_agent") check in
   LabelAgent: already verified at construction time and again
   inside callWasmFunction.

Closes #2829

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 31, 2026 23:17
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves wazero-based WASM guard performance and reliability by introducing a shared compilation cache, making the cache injectable via options, and tightening/clarifying runtime behavior (Close error reporting, retry strategy documentation, and removing a redundant export check).

Changes:

  • Added a process-wide wazero.CompilationCache and plumbed it into runtime construction, with an override in WasmGuardOptions.
  • Improved WasmGuard.Close() to return both module and runtime close errors via errors.Join.
  • Added documentation for the adaptive output-buffer retry protocol and updated tests with a TestMain cache lifecycle hook plus cache-related tests.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
internal/guard/wasm.go Adds global + injectable compilation cache, improves Close() error surfacing, documents buffer retry convention, removes redundant export check.
internal/guard/wasm_test.go Adds TestMain to close the global cache after tests and introduces compilation-cache-focused tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +20 to +24
func TestMain(m *testing.M) {
code := m.Run()
globalCompilationCache.Close(context.Background())
os.Exit(code)
}
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TestMain closes globalCompilationCache but ignores the returned error. If Close can fail (e.g., for future disk-backed caches or internal cleanup), the test process would still exit with a success code. Consider checking the error and failing the test run (e.g., printing to stderr and using a non-zero exit code) so cache lifecycle issues are surfaced.

Copilot uses AI. Check for mistakes.
- Add DisableCompilationCache bool to WasmGuardOptions for explicit
  opt-out of caching (avoids unbounded memory in long-lived processes)
- Check and surface error from globalCompilationCache.Close() in TestMain
- Replace unobservable cache tests with disk-backed assertions that
  verify cache artifacts are actually written to the expected directory

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[go-fan] Go Module Review: tetratelabs/wazero

2 participants