3.1 KiB
3.1 KiB
Research Log: Modular Proxy & Cache Segmentation
Decision 1: Module Registry Location
- Decision: Introduce
internal/hubmodule/as the root for module implementations plus aregistry.gothat exposesRegister(name ModuleFactory)andResolve(hubType string)helpers. - Rationale: Keeps new hub-specific code outside
internal/proxy/internal/cachecore while still within internal tree; mirrors existing package layout expectations and eases discovery. - Alternatives considered:
- Embed modules under
internal/proxy/<hub>: rejected because cache + proxy concerns would blend with shared proxy infra, blurring ownership lines. - Place modules under
pkg/: rejected since repo avoids exported libraries and wants all runtime code underinternal.
- Embed modules under
Decision 2: Config Binding Field
- Decision: Add optional
Modulestring field to each[[Hub]]block inconfig.toml, defaulting to"legacy"to preserve current behavior. Validation ensures the value matches a registered module key. - Rationale: Minimal change to config schema, symmetric across hubs, and allows gradual opt-in by flipping a single field.
- Alternatives considered:
- Auto-detect module from
hub.Name: rejected because naming conventions differ across users and would impede third-party forks. - Separate
ProxyModule/CacheModulefields: rejected per clarification outcome that modules encapsulate both behaviors.
- Auto-detect module from
Decision 3: Fiber/Viper/Logrus Best Practices for Modular Architecture
- Decision: Continue to initialize Fiber/Viper/Logrus exactly once at process start; modules receive interfaces (logger, config handles) instead of initializing their own instances.
- Rationale: Prevents duplicate global state and adheres to constitution (single binary, centralized config/logging).
- Alternatives considered: Allow modules to spin up custom Fiber groups or loggers—rejected because it complicates shutdown hooks and breaks structured logging consistency.
Decision 4: Storage Layout Compatibility
- Decision: Reuse the original request path directly (
StoragePath/<Hub>/<path>) so operators can browse cached artifacts without suffix translation; modules share the same layout and rely on directory creation safeguards to avoid traversal issues. - Rationale: Aligns with operational workflows that expect “what you request is what you store,” simplifying manual cache invalidation and disk audits now that we no longer need
.bodyindirection. - Alternatives considered: Keep the
.bodysuffix or add per-module subdirectories—rejected because suffix-based migrations complicate tooling and dedicated subdirectories fragment cache quotas.
Decision 5: Testing Strategy
- Decision: For each module, enforce a shared test harness that spins a fake upstream using
httptest.Server, writes tot.TempDir()storage, and asserts registry wiring end-to-end via integration tests. - Rationale: Aligns with Technical Context testing guidance while avoiding bespoke harnesses per hub type.
- Alternatives considered: Rely solely on unit tests per module—rejected since regressions often arise from wiring/registry mistakes.