daemon split (8/8): document capability decoupling + wireServices
Update ARCHITECTURE.md's Composition section to reflect the finished
split: capabilities carry explicit service-pointer fields, nothing
reaches *Daemon at dispatch time, and wireServices(d) is the single
entry point that builds services + capabilities eagerly (from Open
in production, from tests after constructing &Daemon{...} literals).
Removes the paragraph admitting capability→*Daemon coupling and the
lazy-init getters justification, neither of which applies anymore.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9c73155e17
commit
011b59a72f
1 changed files with 13 additions and 8 deletions
|
|
@ -41,15 +41,20 @@ consumer-defined seams:
|
||||||
declaring a function-typed interface for every call would balloon
|
declaring a function-typed interface for every call would balloon
|
||||||
the surface for no win — services are unexported, so package-external
|
the surface for no win — services are unexported, so package-external
|
||||||
code can never reach them.
|
code can never reach them.
|
||||||
- Capability hooks still take `*Daemon` as their receiver argument,
|
- Capability hooks do not take `*Daemon`. Each capability is a struct
|
||||||
but `VMService` calls into them through a `capabilityHooks` struct
|
with explicit service-pointer fields (`workDiskCapability{vm, ws,
|
||||||
(function-typed bag) populated at construction. The service has no
|
store, defaultImageName}`, `dnsCapability{net}`, `natCapability{vm,
|
||||||
`*Daemon` pointer.
|
net, logger}`) populated at wiring time. `VMService` invokes them
|
||||||
|
through a `capabilityHooks` struct (function-typed bag) populated at
|
||||||
|
construction; neither the service nor any capability has a `*Daemon`
|
||||||
|
pointer.
|
||||||
|
|
||||||
Lazy-init getters (`d.hostNet()`, `d.imageSvc()`, `d.workspaceSvc()`,
|
Services + capabilities are built eagerly by `wireServices(d)`, called
|
||||||
`d.vmSvc()`) let existing test literals (`&Daemon{store: db, runner: r}`)
|
once from `Daemon.Open` after the composition root's infrastructure is
|
||||||
keep working — the getter constructs the service from whatever is on
|
populated, and once per test that constructs a `&Daemon{...}` literal.
|
||||||
the `Daemon` if nothing was pre-wired.
|
Tests that want to stub a particular service or the capability list
|
||||||
|
assign the field before calling `wireServices` — the helper is
|
||||||
|
idempotent and skips anything already set.
|
||||||
|
|
||||||
## Service state
|
## Service state
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue