One Module/Engine interface with a JSON-in/JSON-out calling convention runs four pure-Go engines behind a Pool that makes single-threaded interpreters serve requests as parallel goroutines: native plain Go handlers, zero overhead goja + esbuild JavaScript and TypeScript (TS transpiled to ES2020) gpython Python, no cgo and no GIL -> true goroutine parallelism wazero Rust/WASM via a trivial string ABI Services mount from a manifest (lang + source + routes), so any Go, Python, Rust or JS backend collapses into a single static CGO_ENABLED=0 binary served on the zip/gofiber app. A Go-backed json stdlib shim lets Python backends keep importing the real module names while running at Go speed. Examples and tests cover every engine; the Rust guest is a real wasm32 fixture exercised end to end.
50 lines
1.4 KiB
Go
50 lines
1.4 KiB
Go
package goa
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sort"
|
|
)
|
|
|
|
// HandlerFunc is a native Go handler in the canonical JSON-in/JSON-out shape.
|
|
type HandlerFunc func(ctx context.Context, payload []byte) ([]byte, error)
|
|
|
|
// NativeModule mounts plain Go functions through the same Module interface as
|
|
// the interpreted engines — zero overhead, full type safety. This is how Go
|
|
// services join the unified binary: register their handlers and they sit beside
|
|
// the Python/JS/Rust ones behind the identical routing surface.
|
|
//
|
|
// NativeModule is goroutine-safe (the underlying Go funcs are expected to be),
|
|
// so it needs no Pool — though you may still pool it uniformly if you like.
|
|
type NativeModule struct {
|
|
funcs map[string]HandlerFunc
|
|
}
|
|
|
|
// NewNativeModule wraps a set of named Go handlers as a Module.
|
|
func NewNativeModule(funcs map[string]HandlerFunc) *NativeModule {
|
|
cp := make(map[string]HandlerFunc, len(funcs))
|
|
for k, v := range funcs {
|
|
cp[k] = v
|
|
}
|
|
return &NativeModule{funcs: cp}
|
|
}
|
|
|
|
func (m *NativeModule) Invoke(ctx context.Context, fn string, payload []byte) ([]byte, error) {
|
|
h, ok := m.funcs[fn]
|
|
if !ok {
|
|
return nil, fmt.Errorf("go: no handler %q", fn)
|
|
}
|
|
return h(ctx, payload)
|
|
}
|
|
|
|
func (m *NativeModule) Funcs() []string {
|
|
out := make([]string, 0, len(m.funcs))
|
|
for k := range m.funcs {
|
|
out = append(out, k)
|
|
}
|
|
sort.Strings(out)
|
|
return out
|
|
}
|
|
|
|
func (m *NativeModule) Close() error { return nil }
|