Documentation
¶
Overview ¶
Package gocache holds a Go build cache under a size: least recently used entries go first, never one used in the last Recent, never anything that is not a cache entry.
Go itself removes an entry only after five days unused, with no bound on size; a day of sprint cards grew one shared cache past 50 GiB, and a friend's per-job caches reached 9.3 GiB (ideas#833). Two callers hold a cache with it: the member's lazy round (cmd/nova-swarm/lazyclean.go), a few subdirectories at a time on its own clock, and nova-sprint friend clean (Hold), once a night over a friend's whole cache.
Index ¶
Constants ¶
const ( Limit int64 = 20 * gib Slack int64 = Limit / 5 )
Limit is the size a cache is held under by default; once over it, a trim removes, oldest first, down to the low-water mark Slack under it (a fifth: 80% of the limit), and then removes nothing until the size passes the limit again. It was 10 GiB until 2026-10-04, when a busy 24-slot member wrote 13-14 GiB in three hours: every entry was under three hours old and the trim removed entries running builds still read, every round, and those builds failed (could not import ... go-build/...-d: no such file or directory). A busy machine names its own (nova-swarm member --gocache-limit, disk-guard --cache-max-gb).
const Recent = 2 * time.Hour
Recent is the default floor (Bounds.Floor): how recently used an entry is never removed, whatever the size. Go marks an entry used by setting its modification time, and only when that is over an hour old (the go command's cache package, its mtimeInterval), so an entry whose time is two hours old has not been used in the last hour: a build that just looked it up never finds it gone.
const SayEvery = time.Hour
SayEvery is how often a cache over its limit with every entry younger than the floor is said (Count.InUse): once an hour, never once a round.
const Subdirs = 256
Subdirs is the number of subdirectories of a Go build cache: two hex digits.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Bounds ¶
Bounds are a trim's limits. Floor is how recently used an entry is never removed (0: Recent); Dirs is how many subdirectories a round reads, Remove the most entries it removes; Dry counts what a round would remove and removes nothing.
type Count ¶
Count is what one round did: entries removed (or, dry, that would be), removals failed (Why the first one's path and reason), the bytes freed and the cache's measured size. InUse says the cache is over its limit and every entry is younger than the floor, so nothing was removed: the limit is under the machine's working set. It is set at most once every SayEvery, so its caller says it then and never once a round.
func Hold ¶
Hold measures the whole cache in one round and trims it in a second: a one-shot caller's trim, Dirs ignored. The measurement round runs first, over every subdirectory; the trim round re-reads them and suppresses re-reporting a failure the measurement already recorded (`t.failed[sub]`). That would swallow a shard that could not be read, so Hold carries the measurement round's failure count and first diagnostic into the returned Count. Removed and Freed still come from the trim round alone (the measurement round removes nothing: cutoff is math.MinInt64 until the cache is measured), and Size is the final measurement (docs/STANDARD.md, the silent rule; SPEC-CI.md, `silent`).
type Trim ¶
type Trim struct {
// contains filtered or unexported fields
}
Trim is the running measure of a cache and its trim. sizes and hours are each subdirectory's bytes, in all and by the hour (unix) of each entry's last use, as last read; measured counts the subdirectories read at least once (they are read in order from 00, so the first 256 reads measure them all); over is set when the measured size passed the limit and cleared when it fell to the limit less the slack.
func (*Trim) Round ¶
Round reads b.Dirs of the cache's subdirectories, the next ones in turn, and, once the whole cache has been measured and its size is over the limit, removes from those subdirectories the entries last used before the cutoff (cutoff) and at least the floor ago (b.Floor, else Recent), at most b.Remove a round, until the size is down to the low-water mark (the limit less the slack); then nothing until it passes the limit again. Oldest first, to the hour: Go records a use to the hour (Recent), so an entry's time is no finer than that. A missing entry is a cache miss that Go rebuilds, so removing an unused one costs at most a rebuild; removing one a running build still reads fails that build, so no entry younger than the floor is ever removed, whatever the size. A cache over its limit with every entry younger than the floor loses nothing, and the round says so (InUse) at most once every SayEvery.