Commit graph

7 commits

Author SHA1 Message Date
Brian C. Lane
35059ca60e dnfjson: Add a cache of dnf-json results
This adds a cache structure with timeout handling and cache cleanup.
Also adds some testing of the new functions.
2022-09-15 11:34:39 +01:00
Achilleas Koutsou
fb34c69e91 dnfjson: lock cache directory when cleaning
Apply a RWMutex lock to a cache directory.
A global map of cache locks is maintained, keyed by the absolute path to
the cache directory, so multiple cache instances can coexist and share
locks if they use the same cache root.

Currently, the lock only prevents multiple concurrent `shrink()`
operations when multiple cache instances share the same root.
2022-06-10 12:45:41 +01:00
Achilleas Koutsou
31f7040e05 dnfjson: use new size-based cache management
- Update timestamps for cache elements whenever a repository is used.
- Call the new `shrink()` function instead of the old `clean()`.
- Remove the old `clean()` function.
2022-06-10 12:45:41 +01:00
Achilleas Koutsou
542da40844 dnfjson: skip deletion if repoID not found in repoElements
If the repoRecency and repoElements somehow become inconsistent (an ID
in repoRecency does not exist in repoElements), ignore and continue.
The repoID will be removed from the repoRecency list at the end as it's
still counted in the nDeleted.
2022-06-10 12:45:41 +01:00
Achilleas Koutsou
a7a1f1ac07 dnfjson: size-based cache management
Functions for managing repository cache management based on a max
desirable size for the entire dnf-json cache directory.
While none of the functions are currently used, the workflow should
be as follows:
- Update the timestamp of a repository whenever it's used in a
  transaction by calling `touchRepo()` with the repository ID and the
  current time.
- Update the internal cache information when desired by calling
  `updateInfo()`.  This should be called for example after multiple
  depsolve transactions are run for a single build request.
- Shrink the cache to below the configured maxSize by calling
  `shrink()`.

The most important work happens in `updateInfo()`.  It collects all the
information it needs from the on-disk cache directories and organises it
in a way that makes it convenient for the `shrink()` function to run
efficiently.  It stores three important pieces of information:
1. repoElements: a map that links a repository ID with all the
   information about a repository's cache:
    - the top-level elements (files and directories) for the cache
    - size of the repository cache (total of all elements)
    - most recent mtime from all the elements which, if the
      `touchRepo()` call is consistently used, should reflect the most
      recent time the repository was used
2. repoRecency: a list of repository IDs sorted by mtime (oldest first)
3. size: the total size of the cache (total of all repository caches)

This way, when `shrink()` is called, the paths associated with the
least-recently-used repositories can be easily deleted by iterating on
repoRecency, obtaining the repository info from the map, deleting every
path in the repoElements array, and subtracting the repository's size
from the total.  The `shrink()` function stops when the new size is
below the maxSize (or when all repositories have been deleted).
2022-06-10 12:45:41 +01:00
Achilleas Koutsou
b8d16bc395 dnfjson: cache information and methods as a substruct
Move cache handling data and code to a substruct of the BaseSolver.
This is all internal to the dnfjson package.

Paves the way for cache management with a persistent state.
2022-06-10 12:45:41 +01:00
Achilleas Koutsou
9fda1ff55f dnfjson: cache cleanup
Added CleanCache() method to the solver that deletes all the caches if
the total size grows above a certain (configurable) limit
(default: 500 MiB).

The function is called externally to handle errors (usually log or
ignore completely) and to avoid calling multiple times for multiple
depsolves of a single request.

The cleanup is extremely simple and is meant as a placeholder for more
sophisticated cache management.  The goal is to simply avoid ballooning
cache sizes that might cause issues for users or our own services.
2022-06-01 11:36:52 +01:00