Repository navigation
Architecture
SPACK 的架构目标是把“静态资源服务”拆成清晰的数据平面和控制平面:控制平面负责扫描、生成、清理、预编译;数据平面负责尽可能少做计算地响应 HTTP 请求。
SPACK separates static asset serving into a control plane and a data plane. The control plane scans, generates, cleans, and compiles runtime state. The data plane serves HTTP requests with minimal per-request work.
flowchart TB
subgraph Config["Configuration / 配置层"]
Defaults["Defaults"]
Dotenv[".env / .env.local"]
Files["--config files"]
Env["Environment variables"]
Flags["CLI flags"]
end
Config --> Loader["configx loader"]
Loader --> Container["dix container"]
subgraph Runtime["Runtime / 运行时"]
Container --> Lifecycle["runtime lifecycle"]
Lifecycle --> Source["source"]
Lifecycle --> Catalog["catalog"]
Lifecycle --> Prepared["prepared snapshot"]
Lifecycle --> Resolver["resolver"]
Lifecycle --> Pipeline["pipeline"]
Lifecycle --> Cache["assetcache"]
Lifecycle --> Scheduler["gocron scheduler"]
Lifecycle --> HTTP["Fiber HTTP server"]
Lifecycle --> Debug["debug runtime"]
end
Source --> Catalog
Catalog --> Prepared
Resolver --> Prepared
Pipeline --> Artifact["artifact store"]
Artifact --> Catalog
Cache --> Prepared
Scheduler --> Rescan["source rescan"]
Scheduler --> Janitor["artifact janitor"]
Scheduler --> Warmer["cache warmer"]
Rescan --> Source
Janitor --> Artifact
Warmer --> Cache
HTTP --> Prepared
HTTP --> Metrics["observabilityx metrics"]
Debug --> Metrics
| 模块 / Module | 职责 / Responsibility |
|---|---|
cmd |
CLI、config flags、healthcheck command。CLI, config flags, healthcheck command. |
config |
默认值、配置加载、校验、归一化。Defaults, loading, validation, normalization. |
runtime |
生命周期编排。Lifecycle orchestration. |
source |
本地文件系统 source backend、watcher。Local filesystem source backend and watcher. |
sourcecatalog |
源文件扫描和 sidecar 识别。Source scanning and sidecar detection. |
catalog |
资产、变体、metadata、cache-policy 输入。Assets, variants, metadata, cache-policy inputs. |
server |
HTTP route、prepared delivery、headers、robots、health。HTTP routes, prepared delivery, headers, robots, health. |
resolver |
动态解析规则、variant negotiation、测试辅助。Dynamic resolution rules, variant negotiation, test helpers. |
pipeline |
压缩和图片 stage、lazy/warmup 生成、artifact lifecycle。Compression and image stages, lazy/warmup generation, artifact lifecycle. |
contentcoding |
gzip、brotli、zstd strategy。Content-coding strategies. |
assetcache |
Ristretto-backed small-file cache。Ristretto-backed small-file cache. |
cachepolicy |
response/artifact cache policy。Response and artifact cache policy. |
task |
source rescan、artifact janitor、cache warmer。Background tasks. |
event |
variant/catalog lifecycle event bus。Lifecycle event bus. |
metrics |
Prometheus metric registration and runtime metadata。Metrics and runtime metadata. |
requestpath |
热路径 request path normalization。Hot-path request path normalization. |
SPACK 使用 dix 装配模块,避免在 main 或 CLI 层手动拼接依赖。模块通过 Module 注册 provider、lifecycle hook 和健康检查。
SPACK uses dix to assemble modules so the CLI and main do not manually wire dependencies. Modules register providers, lifecycle hooks, and health checks through Module.
flowchart LR
CLI["cmd/rootCmd"] --> Config["config module"]
Config --> DIX["dix container"]
DIX --> Providers["module providers"]
Providers --> Start["start lifecycle hooks"]
Start --> Health["health checks"]
Start --> Stop["stop lifecycle hooks"]
设计原则:
- dependency graph belongs to modules, not command handlers
- lifecycle start/stop is centralized
- observable module state is exported through metrics
- user configuration only controls product behavior, not internal scheduling details
Design principles:
- Dependency graph belongs to modules, not command handlers.
- Lifecycle start/stop is centralized.
- Observable module state is exported through metrics.
- User configuration controls product behavior, not internal scheduling details.
flowchart LR
Client["HTTP client"] --> Fiber["Fiber route"]
Fiber --> Cleaner["requestpath cleaner"]
Cleaner --> Lookup["prepared lookup"]
Lookup --> Plan["prepared response plan"]
Plan --> Memory["in-memory body"]
Plan --> File["sendfile / range"]
Plan --> Headers["precomputed headers"]
Memory --> Response["HTTP response"]
File --> Response
Headers --> Response
数据平面优化重点:
- 对已规范路径走低分支 fast path。
- prepared snapshot 持有 route-indexed response plan。
- 小文件可以直接使用 prepared body 或 memory cache。
- 大文件和 range request 使用
sendfile。 -
Vary、Content-Length、Last-Modified、resource hints 和 cache headers 预先计算。
Data-plane optimization focus:
- Fast path for already-normalized paths.
- Route-indexed response plans in the prepared snapshot.
- Small files can use prepared bodies or memory cache.
- Large files and range requests use
sendfile. -
Vary,Content-Length,Last-Modified, resource hints, and cache headers are precomputed.
flowchart TB
Source["source tree"] --> Scan["source scan"]
Scan --> Catalog["catalog"]
Catalog --> Compile["prepared compile"]
Compile --> Swap["atomic snapshot publish"]
Catalog --> Pipeline["variant pipeline"]
Pipeline --> Artifact["artifact store"]
Artifact --> Catalog
Scheduler["gocron scheduler"] --> Scan
Scheduler --> Cleanup["artifact cleanup"]
Scheduler --> Warmup["cache warmup"]
EventBus["event bus"] --> Compile
EventBus --> Pipeline
EventBus --> Cache["assetcache"]
控制平面通过事件解耦:
- source rescan 发现新增、变更、删除。
- artifact janitor 删除过期或超过 budget 的生成物。
- pipeline 生成 compression/image variants。
- catalog changed event 触发 prepared snapshot 更新。
The control plane is event-driven:
- Source rescan detects create, change, and delete events.
- Artifact janitor removes stale or over-budget generated artifacts.
- Pipeline creates compression and image variants.
- Catalog-changed events trigger prepared snapshot updates.
stateDiagram-v2
[*] --> SourceAsset: scan
SourceAsset --> SourceSidecar: detect app.js.br/zst/gz
SourceAsset --> GeneratedVariant: lazy or warmup pipeline
SourceSidecar --> CatalogVariant: register
GeneratedVariant --> CatalogVariant: register
CatalogVariant --> PreparedSnapshot: compile
GeneratedVariant --> Removed: janitor or source change
SourceAsset --> Removed: source delete
Removed --> PreparedSnapshot: recompile
中文:sidecar 是源文件的一部分,不被 janitor 当作生成物删除。pipeline 生成物由 artifact policy 控制生命周期。
English: Sidecars are part of the source tree and are not removed by the janitor as generated artifacts. Pipeline-generated artifacts are governed by artifact cache policies.
| 决策 / Decision | 原因 / Reason |
|---|---|
| one process, one asset mount | 减少 location 语义复杂度,让热路径更直接。Reduces routing complexity and keeps the hot path direct. |
| prepared snapshot | 把计算前移到 catalog 更新时,而不是每个请求重复计算。Moves work to catalog updates instead of every request. |
| internal scheduler not configurable | 这些是运行时机制,不是用户策略。They are runtime mechanisms, not user policy. |
| sidecar recognition | 兼容 Vite 等前端插件生成的预压缩文件。Compatible with precompressed assets generated by tools such as Vite plugins. |
| static robots precedence | 用户显式文件优先,生成 fallback 只是辅助能力。User-provided static files win; generated fallback is only an auxiliary feature. |