Commit 787749d
feat(server): add TenantRegistry with per-tenant health tracking
Closes #619. Adds TenantRegistry — a higher-level multi-tenant primitive
that provides JS createTenantRegistry parity for Python deployments.
Adopters pre-build per-tenant DecisioningPlatform instances and register
them; the registry tracks health state (pending/healthy/unverified/disabled)
and surfaces a synchronous resolve_by_host for the hot request path.
Key design choices over the JS surface:
- resolve_by_host is sync (in-memory dict) rather than async — Python owns
the mapping directly via register()/unregister(), no external resolver.
- auto_validate dropped; validator presence is the opt-in (None = principal-
token mode, always healthy).
- Per-tenant asyncio.Lock prevents TOCTOU on concurrent recheck() calls.
- unregister()-during-recheck race is guarded: post-validator writes check
whether the tenant was removed while the validator was awaited.
Exports added to adcp.server: TenantRegistry, TenantResolution,
TenantHealthState, TenantValidator.
Tested with pytest: 25 tests covering lifecycle, state machine, host
normalization, sync/async validators, and concurrency correctness.
https://claude.ai/code/session_019ucMgF6YS9X5bygYUADztx1 parent 14d294c commit 787749d
3 files changed
Lines changed: 837 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
141 | 141 | | |
142 | 142 | | |
143 | 143 | | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
144 | 150 | | |
145 | 151 | | |
146 | 152 | | |
| |||
211 | 217 | | |
212 | 218 | | |
213 | 219 | | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
214 | 225 | | |
215 | 226 | | |
216 | 227 | | |
| |||
0 commit comments