Summary
I replaced this branch with a smaller change, because upstream moved underneath the old one. The old version resolved a client's mappings once per batch in DownloadClientGateway. #964 (c07a9a2, #964) fixed the DbContext crash. What I think #964 left is the read volume: a two-item queue poll costs 12 reads of the mapping table (2 plus source files per item), repeated every poll interval. With this change it is 1.
The service still removes rpm_client_{id} on create, update and delete, but nothing populates that key, so every translated path reads the table. I think the #576 restructure (#535) dropped the cache by accident (inferred: git log -S rpm_client_ shows 1d6a8e9, from #576, deleting the read and keeping the three Remove calls, and the commit message does not mention caching).
Changes
Fixed
GetPathMappingByClientAsyncpopulates the existing key for 10 s and returns a copy to each caller.- A cold miss is single-flighted per client, so one poll does one read.
- Create, update and delete invalidate under the same lock as the fill, so an in-flight fill cannot overwrite a newer write. Moving a mapping to another client clears both owners.
Only RemotePathMappingService changes. #964's per-operation contexts and the gateway are untouched.
Trade-offs
A mapping edited directly in the database (not through the service) is stale for up to 10 s; the three service methods are the only writers I found. A write on a client now waits for that client's in-flight fill, bounded by one read. The 10 s lifetime and the lock are judgement calls and easy to change.
Testing
- Against bare canary, 4 of the 5 first tests failed: a two-item poll did 12 reads, not 1, and concurrent cold reads did 8. The write-through test passed on canary on purpose, as a control.
- Two further tests (a create during an in-flight cold read is seen by the next read; a move clears the old client) ...
Automated Canary build