fix(34): WR-06 bound the Plugins screen's search cache
pluginCatalog.lists was keyed by every distinct query and category and never dropped an expired entry, so searching distinct strings grew the process without limit (each entry can hold a 4 MiB answer). Storing a search into a full cache now drops the expired searches and then the ones that expire first, keeping at most 256.
This commit is contained in:
@@ -133,6 +133,9 @@ const (
|
||||
registryFailureTTL = time.Minute
|
||||
registryLookups = 4
|
||||
marketplaceMaxQuery = 100
|
||||
// marketplaceCacheSize bounds the cached searches: every distinct
|
||||
// query is a key, so the map must not grow with them (WR-06).
|
||||
marketplaceCacheSize = 256
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -247,11 +250,35 @@ func (c *pluginCatalog) list(ctx context.Context, q, category string) (kiosk.Lis
|
||||
resp, ttl = kiosk.ListResponse{}, registryFailureTTL
|
||||
}
|
||||
c.mu.Lock()
|
||||
c.lists[key] = cachedList{resp: resp, err: err, expires: c.now().Add(ttl)}
|
||||
c.storeList(key, cachedList{resp: resp, err: err, expires: c.now().Add(ttl)})
|
||||
c.mu.Unlock()
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// storeList caches a search under key with c.mu held. It first drops the
|
||||
// expired searches and then, while the cache is full, the one that
|
||||
// expires first, so it never holds more than marketplaceCacheSize.
|
||||
func (c *pluginCatalog) storeList(key string, entry cachedList) {
|
||||
if _, ok := c.lists[key]; !ok && len(c.lists) >= marketplaceCacheSize {
|
||||
now := c.now()
|
||||
for k, v := range c.lists {
|
||||
if !now.Before(v.expires) {
|
||||
delete(c.lists, k)
|
||||
}
|
||||
}
|
||||
for len(c.lists) >= marketplaceCacheSize {
|
||||
oldest, first := "", true
|
||||
for k, v := range c.lists {
|
||||
if first || v.expires.Before(c.lists[oldest].expires) {
|
||||
oldest, first = k, false
|
||||
}
|
||||
}
|
||||
delete(c.lists, oldest)
|
||||
}
|
||||
}
|
||||
c.lists[key] = entry
|
||||
}
|
||||
|
||||
// releases returns the releases of plugin id, cached. listed is false when
|
||||
// the registry does not know the ID (a 404 is an answer, not a failure).
|
||||
func (c *pluginCatalog) releases(ctx context.Context, id string) ([]kiosk.RegistryVersion, bool, error) {
|
||||
|
||||
Reference in New Issue
Block a user