feat: remove module/rollout config key

This commit is contained in:
2025-11-18 15:37:21 +08:00
parent dcd85a9f41
commit 347eb3adc5
36 changed files with 167 additions and 566 deletions

View File

@@ -2,10 +2,9 @@
## Common Fields
- `hub`/`domain`/`hub_type`:当前 Hub 标识与协议类型,例如 `debian`/`apk`
- `module_key`:命中的模块键( `legacy` 时表示新模块生效)。
- `module_key`:命中的模块键( `Type` 同名)。
- `cache_hit``true` 表示直接复用缓存;`false` 表示从上游获取或已刷新。
- `upstream`/`upstream_status`:实际访问的上游地址与状态码。
- `rollout_flag``legacy-only`/`dual`/`modular`,便于排查路由与灰度。
- `action``proxy`,表明代理链路日志。
## APT (debian 模块)
@@ -19,4 +18,4 @@
## Quick Checks
- 观察 `cache_hit``upstream_status``cache_hit=true``upstream_status=200/304` 表示缓存复用成功;`cache_hit=false` 表示回源或刷新。
-期望模块日志字段但出现 `module_key":"legacy"`,检查 `Module``Rollout` 配置是否指向新模块。
-`module_key` 与配置的 `Type` 不符,检查该类型的 hook 是否已注册,或是否误用了旧版二进制。

View File

@@ -1,58 +1,33 @@
# Modular Hub Migration Playbook
# Module Binding Notes
This playbook describes how to cut a hub over from the shared legacy adapter to a dedicated module using the new rollout flags, diagnostics endpoint, and structured logs delivered in feature `004-modular-proxy-cache`.
Legacy rollout flags (`Module`/`Rollout`) have been removed. Hubs now bind to modules solely through their `Type` values, which map 1:1 to registered modules (docker, npm, go, pypi, composer, debian, apk, ...).
## Prerequisites
## Migrating to a New Module
- Target module must be registered via `hubmodule.MustRegister` and expose a proxy handler through `proxy.RegisterModuleHandler`.
- `config.toml` must already map the hub to its target module through `[[Hub]].Module`.
- Operators must have access to the running binary port (default `:5000`) to query `/-/modules`.
1. **Register the module**
Implement the new module under `internal/hubmodule/<type>/`, call `hubmodule.MustRegister` in `init()`, and register hooks via `hooks.MustRegister`.
## Rollout Workflow
2. **Expose a handler**
New modules continue to reuse the shared proxy handler registered via `proxy.RegisterModule`. No per-module handler wiring is required unless the module supplies a bespoke handler.
1. **Snapshot current state**
Run `curl -s http://localhost:5000/-/modules | jq '.hubs[] | select(.hub_name=="<hub>")'` to capture the current `module_key` and `rollout_flag`. Legacy hubs report `module_key=legacy` and `rollout_flag=legacy-only`.
2. **Prepare config for dual traffic**
Edit the hub block to target the new module while keeping rollback safety:
```toml
[[Hub]]
Name = "npm-prod"
Domain = "npm.example.com"
Upstream = "https://registry.npmjs.org"
Module = "npm"
Rollout = "dual"
```
Dual mode keeps routing on the new module but keeps observability tagged as a partial rollout.
3. **Deploy and monitor**
Restart the service and tail logs filtered by `module_key`:
```sh
jq 'select(.module_key=="npm" and .rollout_flag=="dual")' /var/log/any-hub.json
```
Every request now carries `module_key`/`rollout_flag`, allowing dashboards or `grep`-based analyses without extra parsing.
3. **Update the config schema**
Add the new type to `internal/config/validation.go`s `supportedHubTypes`, then redeploy. Every hub that should use the new module only needs `Type = "<type>"` plus the usual `Domain`/`Upstream` fields.
4. **Verify diagnostics**
Query `/-/modules/npm` to inspect the registered metadata and confirm cache strategy, or `/-/modules` to ensure the hub binding reflects `rollout_flag=dual`.
`curl http://127.0.0.1:<port>/-/modules` to ensure the new type appears under `modules[]` and that the desired hubs show `module_key="<type>"`.
5. **Promote to modular**
Once metrics are healthy, change `Rollout = "modular"` in config and redeploy. Continue monitoring logs to make sure both `module_key` and `rollout_flag` show the fully promoted state.
5. **Monitor logs**
Structured logs still carry `module_key`, making it easy to confirm that traffic is flowing through the expected module. Example:
6. **Rollback procedure**
To rollback, set `Rollout = "legacy-only"` (without touching `Module`). The runtime forces traffic through the legacy module while keeping the desired module declaration for later reattempts. Confirm via diagnostics (`module_key` reverts to `legacy`) before announcing rollback complete.
```json
{"action":"proxy","hub":"npm","module_key":"npm","cache_hit":false,"upstream_status":200}
```
## Observability Checklist
- **Logs**: Every proxy log line now contains `hub`, `module_key`, `rollout_flag`, upstream status, and `request_id`. Capture at least five minutes of traffic per flag change.
- **Diagnostics**: Store JSON snapshots from `/-/modules` before and after each rollout stage for incident timelines.
- **Config History**: Keep the `config.toml` diff (especially `Rollout` changes) attached to change records for auditability.
6. **Rollback**
Since modules are now type-driven, rollback is as simple as reverting the `Type` value (or config deployment) back to the previous modules type.
## Troubleshooting
- **Error: `module_not_found` during diagnostics** → module key not registered; ensure the module packages `init()` calls `hubmodule.MustRegister`.
- **Requests still tagged with `legacy-only` after promotion** → double-check the running process uses the updated config path (`ANY_HUB_CONFIG` vs `--config`) and restart the service.
- **Diagnostics 404** → confirm you are hitting the correct port and that the CLI user/network path allows HTTP access; the endpoint ignores Host headers, so `curl http://127.0.0.1:<port>/-/modules` should succeed locally.
- **`module_not_found` in diagnostics** → ensure the module registered via `hubmodule.MustRegister` before the hub references its type.
- **Hooks missing** → `/-/modules` exposes `hook_registry`; confirm the new type reports `registered`.
- **Unexpected module key in logs** → confirm the running binary includes your module (imported in `internal/config/modules.go`) and that the config `/--config` path matches the deployed file.