Architecture
System overview of go-faas modules, data flow, and execution lifecycle.
System Overview
graph TB
Client[HTTP Client] -->|POST /upload| Upload[Upload Handler]
Client -->|POST /run/*path| Run[Run Handler]
Client -->|POST /run-now| RunNow[RunNow Handler]
Upload --> Redis[(Redis)]
Run --> Redis
Run --> Sandbox[Sandbox]
RunNow --> Sandbox
Sandbox --> Response[JSON / SSE]
Response --> Client
Components
| Component | Package | Responsibility |
|---|---|---|
| Entry | cmd/api |
Load env, check packages, init Redis and slice, serve HTTP |
| Router | internal |
Gin engine, routes, HTTP_PORT |
| Handler | internal/handler |
Upload, Run, RunNow, SSE |
| Database | internal/database |
Redis meta, code blobs, version sets |
| Sandbox | internal/sandbox |
Platform isolation commands |
| Checker | internal/checker |
Runtime dependency checks |
| Utils | internal/utils |
Env helpers with defaults |
Startup Sequence
cmd/api/main.go runs in this order:
godotenv.Load()(warn and continue if.envis missing)checker.CheckPackage()— Linux may install missing tools; darwin is a no-opdatabase.Init()— ping Redis or exitsandbox.NewSlice()— create systemd user slice on Linux (warn only on failure)internal.CreateServer()— listen until SIGINT / SIGTERM, then 5s graceful shutdown
Router
CreateServer builds gin.Default(), binds:
POST /upload→handler.UploadPOST /run/*targetPath→handler.RunPOST /run-now→handler.RunNow
Listen address is :{HTTP_PORT} (default 8080).
Handler Flow
graph TB
subgraph Handler
Upload[Upload] --> DBAdd[database.Add]
Run[Run] --> DBGet[database.Get]
Run --> RunCore[run]
RunNow[RunNow] --> RunCore
RunCore -->|stream=false| RunScript[runScript]
RunCore -->|stream=true| RunSSE[runScriptWithSSE]
RunScript --> SandboxCmd[sandbox.SandboxCommand]
RunSSE --> SandboxCmd
end
- Upload validates path (no
..), language, and stores via Redis pipeline. - Run loads code by path and optional
versionquery, then executes. - RunNow requires
code+ supportedlanguage, skips Redis. - Shared
run()chooses JSON (runScript) or SSE (runScriptWithSSE).
Database Keys
Path is MD5-hashed. Keys:
| Key | Type | Content |
|---|---|---|
meta:{hash} |
Hash | path, language, latest |
code:{hash}:{ts} |
String | Code blob |
meta:{hash}:version |
Set | Version timestamps |
Get with version=0 uses latest.
Sandbox
- Linux:
systemd-run --slice=go-faas-slice→bwrap(namespaces, cap-drop ALL, no network) → language wrapper - darwin:
sandbox-execseatbelt profile → wrapper
Wrappers under internal/resource/ (wrapper.py, wrapper.js, wrapper.ts) read stdin JSON {code, input}, expose event / input, and print the return value as JSON.
State Machine
stateDiagram-v2
[*] --> Idle
Idle --> Preparing: receive Run / RunNow
Preparing --> Running: start sandbox process
Running --> Streaming: stream=true
Running --> Completed: clean exit
Streaming --> Completed: emit result
Running --> Failed: timeout / stderr / non-zero exit
Streaming --> Failed: client disconnect / error
Failed --> Idle
Completed --> Idle
Related
- Core Concepts — versioning and event model
- Sandbox — isolation details
- API Reference — HTTP contract