dnfjson: Add dnf-json result cache to BaseSolver

This is used to cache the results of dump and search requests for 60s.
Once the timeout has passed the request is repeated and the timeout
reset. The timeout is *not* reset on every cache hit which prevents, for
example, a request every 59 seconds from keeping the cache from
updating.

When the existing CleanCache() function is called to check the on-disk
metadata cache it will also delete any expired entries from the
resultCache in order to keep it from eventually consuming all memory.
This commit is contained in:
Brian C. Lane 2022-08-25 15:40:12 -07:00 committed by Tom Gundersen
parent e307a8174a
commit 9827126d30

View file

@ -38,6 +38,8 @@ type BaseSolver struct {
// Path to the dnf-json binary and optional args (default: "/usr/libexec/osbuild-composer/dnf-json")
dnfJsonCmd []string
resultCache *dnfCache
}
// Create a new unconfigured BaseSolver (without platform information). It can
@ -45,8 +47,9 @@ type BaseSolver struct {
// method.
func NewBaseSolver(cacheDir string) *BaseSolver {
return &BaseSolver{
cache: newRPMCache(cacheDir, 524288000), // 500 MiB
dnfJsonCmd: []string{"/usr/libexec/osbuild-composer/dnf-json"},
cache: newRPMCache(cacheDir, 524288000), // 500 MiB
dnfJsonCmd: []string{"/usr/libexec/osbuild-composer/dnf-json"},
resultCache: NewDNFCache(60 * time.Second),
}
}
@ -80,6 +83,7 @@ func (bs *BaseSolver) NewWithConfig(modulePlatformID string, releaseVer string,
// the total size of the cache falls below the configured maximum size (see
// SetMaxCacheSize()).
func (bs *BaseSolver) CleanCache() error {
bs.resultCache.CleanCache()
return bs.cache.shrink()
}
@ -153,6 +157,11 @@ func (s *Solver) FetchMetadata(repos []rpmmd.RepoConfig) (rpmmd.PackageList, err
s.cache.locker.RLock()
defer s.cache.locker.RUnlock()
// Is this cached?
if pkgs, ok := s.resultCache.Get(req.Hash()); ok {
return pkgs, nil
}
result, err := run(s.dnfJsonCmd, req)
if err != nil {
return nil, err
@ -177,6 +186,9 @@ func (s *Solver) FetchMetadata(repos []rpmmd.RepoConfig) (rpmmd.PackageList, err
sort.Slice(pkgs, func(i, j int) bool {
return sortID(pkgs[i]) < sortID(pkgs[j])
})
// Cache the results
s.resultCache.Store(req.Hash(), pkgs)
return pkgs, nil
}
@ -191,6 +203,11 @@ func (s *Solver) SearchMetadata(repos []rpmmd.RepoConfig, packages []string) (rp
s.cache.locker.RLock()
defer s.cache.locker.RUnlock()
// Is this cached?
if pkgs, ok := s.resultCache.Get(req.Hash()); ok {
return pkgs, nil
}
result, err := run(s.dnfJsonCmd, req)
if err != nil {
return nil, err
@ -215,6 +232,9 @@ func (s *Solver) SearchMetadata(repos []rpmmd.RepoConfig, packages []string) (rp
sort.Slice(pkgs, func(i, j int) bool {
return sortID(pkgs[i]) < sortID(pkgs[j])
})
// Cache the results
s.resultCache.Store(req.Hash(), pkgs)
return pkgs, nil
}