Serve stale virtual members while they refresh #167
Reference in New Issue
Block a user
Delete Branch "benvin/virtual-serve-stale-member"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Virtual merges expire after 60s and the next request blocks on every member. One slow member (a large github_rpm remote) makes the re-merge outlast dnf's 30s timeout.
serve_staleto remotes (model, v2 API, migration 0008, UI, TUI), default false!remote.ServeStalefalls through tofetchwithout droppinge.stale[sk], so toggling serve_stale off keeps the parsed index in memory indefinitely, and toggling it back on serves that arbitrarily old copy →delete(e.stale, sk)undere.muin the not-flagged branch.slog.Warn→ record fetch time with the copy and fall back to the blocking fetch (surfacing the error) past a bound.evictLRUre-insertse.stale[sk]for the evicted key, and entries are never pruned when a member is removed from a virtual or the virtual/remote is deleted (rpm keys are not evicted at all) → only store whene.gens[key]still exists, and prune on member/virtual removal (or key the map off the gen so it dies with it).evictLRUprunese.stale→ add these.serve_stalethrough the v2 API and DB (PUT is a full replace, so an update omitting it resets to false; undocumented) → add a round-trip case and note the PUT behaviour in docs/common/caching.md.stale_on_errorbut notserve_stale→ add the field.PUT replaces the whole remote...paragraph sit inside the options table, so thequarantine_*andmirrorlistrows below it no longer render as table rows → move the paragraph below the table.prev == nil) re-inserts undere.stale[sk] == prev, which isnil == nilafter eviction, a toggle-off or a toggle-off/on cycle; a cold fetch that outlives its eviction re-adds a copy for an evicted key → track a per-key generation (or checke.gens[key]still exists and the flag is still set) before storing.staleMember, so a deleted virtual, a removed member, or an rpm key (never LRU-evicted) holds its index in memory until some other member fetch happens → also prune fromevictLRU/a merge-cache sweep, or accept and document the ceiling.calls.Load() != 2is asserted right after the 3 merges, but the refresh runs in a singleflight goroutine that may not have reached the member stub yet → callwaitRefresh-style sync (or poll until calls==2 with a deadline) before asserting; a missed increment reads as 1.getRemoteerror deletes the stale copy before falling through to a blocking fetch → on error keep the copy and only delete whengetRemotesucceeds withServeStalefalse.