Initialize every configured volume once at storage proxy startup and serve all lookups from a single registry, so that no volume is constructed a second time on a request path.
Problem
VolumePool.create() already initializes every configured volume at startup, but RootContext.volumes is seeded with the noop volume alone, and RootContext.get_volume(name) lazily constructs and initializes a second object for the same volume on first request.
- Legacy REST handlers reach volumes through
RootContext.get_volume (23 call sites across the manager API, the client API and the migration path), while the v2 service layer, the stats observer and the background tasks already use VolumePool.
- Each volume therefore ends up with two live objects: duplicated health probe loops and thread pools, duplicated vendor API clients, and a duplicated mount baseline capture.
- Shutdown is split to match.
volume_pool.shutdown() stops one copy and shutdown_volumes() stops the other.
get_volume() awaits init() between the membership check and the registration, so concurrent first requests for the same volume each build and initialize their own object. Every one but the last is orphaned, and an orphan is in no registry, so nothing ever stops its probe loops or releases its thread pool.
Scope
- Make
VolumePool the single volume registry, addressable by the configuration key.
- Resolve the partition in
VolumePool.create(): a volume whose [volume.<name>] section key parses as a UUID lands in _volumes and every other one in _volumes_by_name, so a lookup by configuration key currently reaches only one of the two.
- Move the 23
RootContext.get_volume call sites onto VolumePool.
- Settle where the noop volume belongs.
init_noop_volume() does not call init() today, so it carries no probe loops.
- Remove
RootContext.volumes, get_volume() and shutdown_volumes().
Behaviour change to agree on
A volume with a broken mount currently fails only when it is first requested, leaving the other volumes serving. Once every volume is initialized eagerly, the asyncio.gather in VolumePool.create() propagates that failure and the storage proxy does not start at all.
JIRA Issue: BA-7792
Initialize every configured volume once at storage proxy startup and serve all lookups from a single registry, so that no volume is constructed a second time on a request path.
Problem
VolumePool.create()already initializes every configured volume at startup, butRootContext.volumesis seeded with the noop volume alone, andRootContext.get_volume(name)lazily constructs and initializes a second object for the same volume on first request.RootContext.get_volume(23 call sites across the manager API, the client API and the migration path), while the v2 service layer, the stats observer and the background tasks already useVolumePool.volume_pool.shutdown()stops one copy andshutdown_volumes()stops the other.get_volume()awaitsinit()between the membership check and the registration, so concurrent first requests for the same volume each build and initialize their own object. Every one but the last is orphaned, and an orphan is in no registry, so nothing ever stops its probe loops or releases its thread pool.Scope
VolumePoolthe single volume registry, addressable by the configuration key.VolumePool.create(): a volume whose[volume.<name>]section key parses as a UUID lands in_volumesand every other one in_volumes_by_name, so a lookup by configuration key currently reaches only one of the two.RootContext.get_volumecall sites ontoVolumePool.init_noop_volume()does not callinit()today, so it carries no probe loops.RootContext.volumes,get_volume()andshutdown_volumes().Behaviour change to agree on
A volume with a broken mount currently fails only when it is first requested, leaving the other volumes serving. Once every volume is initialized eagerly, the
asyncio.gatherinVolumePool.create()propagates that failure and the storage proxy does not start at all.JIRA Issue: BA-7792