perf: offload virtual repo merge to thread pool via asyncio.to_thread (#38)
Closes #35 ## Summary - Wraps `handler.merge(...)` in `await asyncio.to_thread(...)` so the CPU-bound YAML parse/merge/dump runs in the thread pool instead of blocking the event loop - Change is at the generic `handle()` dispatch site — applies to all current and future `_VirtualHandler` implementations without modification - Also fixes a pre-existing bug in `examples/single-file/remotes.yaml` where `base_url` and `package` keys were merged onto a single line, preventing `docker-compose up` from starting the app ## Measured performance gain 19-member `helm-all` virtual repo, single uvicorn worker, cache miss (38s merge): | | Concurrent `/health` latency | |---|---| | Before (blocking) | **37,721ms** for first request (stalled) | | After (thread pool) | **8–63ms** for all requests | ## Test plan - [x] 278 unit tests pass (`make test`) - [x] Live concurrency test: cache miss merge started in background, 5 concurrent `/health` checks measured — all <65ms - [x] Baseline comparison: same test with blocking call — first health check stalled 37.7s Reviewed-on: #38
This commit was merged in pull request #38.
This commit is contained in:
@@ -224,7 +224,7 @@ async def handle(request: Request, virtual_name: str, path: str, storage, cache,
|
||||
min_ttl = 3600
|
||||
|
||||
t_merge = time.perf_counter()
|
||||
merged = handler.merge(raw_indexes, used_members, used_configs, proxy_base)
|
||||
merged = await asyncio.to_thread(handler.merge, raw_indexes, used_members, used_configs, proxy_base)
|
||||
merge_ms = int((time.perf_counter() - t_merge) * 1000)
|
||||
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user