Hanzo Dev 202bcdc873 goa: load services from any fs.FS (embed.FS or disk)
Generalize the manifest loader to io/fs so services can be baked into a
static binary via embed.FS or read from disk via os.DirFS — LoadFS is the
one path; LoadDir is os.DirFS sugar. This is what lets hanzoai/cloud mount
embedded polyglot services into the single unified binary.
2026-06-28 19:21:30 -07:00

goa

Pure-Go polyglot embedding. Run Go, Python, TypeScript/JavaScript, and Rust/WASM services in one process — as goroutines, no cgo, no subprocesses, no GIL — so a fleet of services collapses into a single static binary (CGO_ENABLED=0) that scales horizontally by replication.

import "github.com/hanzoai/goa"

Why

hanzoai/cloud is one Go binary: subsystems register and mount onto a zip (gofiber) app. Most of our backends are not Go — Langflow is Python, the migrated explorer services are Rust, assorted tools are TypeScript. The choice was a swarm of sidecar containers, or embed the runtimes. goa embeds them, in pure Go, preserving the static build.

Model

One contract, every language: JSON in, JSON out.

type Module interface {
    Invoke(ctx context.Context, fn string, payload []byte) ([]byte, error)
    Funcs() []string
    Close() error
}

type Engine interface {
    Lang() string
    Aliases() []string
    Load(ctx context.Context, src []byte, opt LoadOptions) (Module, error)
}

Four engines register themselves, all pure-Go:

Lang Engine Notes
Go native map[string]HandlerFunc, zero overhead
JavaScript / TS goja + esbuild TS transpiled to ES2020 CommonJS
Python gpython no cgo, no GIL → true goroutine parallelism
Rust / WASM wazero wasm32 + WASI, trivial string ABI

Engines that run single-threaded code (goja, gpython, a wasm instance) are made concurrent by a Pool: N independent interpreters, one per in-flight request, so every HTTP route is still just a goroutine.

Use

Embed source directly

m, _ := goa.Load(ctx, "python", []byte(`
import json
def greet(p):
    return json.dumps({"hello": json.loads(p)["name"]})
`), goa.LoadOptions{Name: "greeter"})

out, _ := m.Invoke(ctx, "greet", []byte(`{"name":"ada"}`))
// {"hello":"ada"}

Mount Go natively (zero overhead)

m := goa.NewNativeModule(map[string]goa.HandlerFunc{
    "greet": func(ctx context.Context, p []byte) ([]byte, error) { return p, nil },
})

Drop-in services: a manifest + a source file

hello-py.manifest.json

{
  "name": "hello-py",
  "lang": "python",
  "source": "hello.py",
  "pool": 8,
  "prefix": "/v1/hello-py",
  "routes": [{ "method": "POST", "path": "/greet", "func": "greet" }]
}
services, _ := goa.LoadDir(ctx, "services")  // every *.manifest.json
mux := http.NewServeMux()
for _, s := range services {
    s.Mount(mux)
}

In hanzoai/cloud the same Service mounts onto the gofiber app via zip.AdaptNetHTTP(svc.Handler()) — goa stays host-agnostic.

Python stdlib

gpython is "batteries not included." goa ships Go-backed implementations of the modules our backends actually use, registered under their real names — so the Python keeps import json and runs at Go speed (the modules that are C-accelerated in CPython are Go-native here). json ships today; re, hashlib, base64, datetime, uuid extend the same pyToGo/goToPy pattern in stdlib_gpython.go.

Two tiers

goa is Tier 1: in-process logic, pure-Go, for handlers and transforms. Anything that needs a real OS process — a long-running server, a GPU workload, heavy native Python (NumPy/Torch), an unported C extension — is Tier 2: run it out-of-process and front it with a native proxy module. Tier 1 is the default; reach for Tier 2 only when the workload genuinely needs an OS boundary.

Rust / WASM ABI

A guest module exports:

alloc(len: i32) -> i32              // buffer pointer for the payload
dealloc(ptr: i32, len: i32)         // optional
<fn>(ptr: i32, len: i32) -> i64     // returns (resultPtr << 32 | resultLen)

The host writes JSON at alloc()'s pointer, calls <fn>, reads JSON back. A #[goa::handler] proc-macro generates this boilerplate on the Rust side.

License

Apache-2.0

S
Description
Hanzo tenant service — sourced from hanzoai/goa
Readme Apache-2.0
54 KiB
Languages
Go 100%