Files
sbt/main
Mai Huy Hoàng 94acc76830 [2.x] fix: Populate the in-memory cache on a read (#9657)
**Problem**
InMemoryCacheStore.CacheStoreImpl.read returns cacheStore.read[T]() on a miss
without putting the value in the cache, so the only thing that ever fills the
cache is write. A task whose stored output is already up to date never writes,
so it re-reads and re-deserialises that output on every invocation for the life of
the server, and the cache can never warm up for it.

update is the costly instance: transitiveUpdate runs it once per project in
the dependency closure, and every call goes through
UpdateReportPersistence.readFrom.

**Solution**
Put the value in the cache after a successful disk read. The keying is unchanged
-- an entry is still (path, lastModified), read re-stats the file on every
call, and write still invalidates before rewriting -- so a populated read is
sound for the same reason a populated write is.

Measured on an 81-module workspace, no-op build, real output files (no
cache-restored symlinks), exportJars=true, alternating the two builds over 8
runs each:

    update task    398ms across 82 projects -> 30ms across 29
    task total     4797ms -> 4623ms
    wall (median)  5.15s -> 4.97s

This makes maximumWeight bind where it could not before: reads now admit
entries, so a build whose working set exceeds sbt.file.cache.size will evict
rather than never cache at all. That is the intended behaviour of a bounded cache.

Generated-by: Claude Opus 5
2026-08-21 14:24:05 -04:00
..
2023-06-20 16:39:07 +02:00