Count hits, misses, fetches and transforms as Prometheus counters (closes #311)
check / check (push) Canceled after 0s

The five counts the cache_stats table held are now Prometheus counters in
memory, in internal/imgcache/counters.go, on the default registry that
/metrics serves. The Increment methods add to them, so counting makes no
database call.

cache_stats, Cache.Stats, Service.Stats, CacheStats and the pending counts
are gone, with their tests. The background goroutine now writes only access
times, and its names say so: StartPendingAccessTimeWrites,
StopPendingAccessTimeWrites and pendingaccesstimes.go.

The counters count for the whole process, so the tests that check how much
they rose do not call t.Parallel. Two stop tests whose write under way was a
hit count now use an access time.

Model: opus-5-5
This commit is contained in:
2026-10-26 08:50:41 +00:00
parent 6b19e4c96c
commit c3a6799763
22 changed files with 672 additions and 1194 deletions
@@ -104,33 +104,24 @@ func writeConcurrently(t *testing.T, db *sql.DB) {
wg.Wait()
var hits, sources int
var sources int
err := db.QueryRowContext(ctx, `
SELECT hit_count, (SELECT COUNT(*) FROM source_content)
FROM cache_stats WHERE id = 1
`).Scan(&hits, &sources)
err := db.QueryRowContext(ctx, `SELECT COUNT(*) FROM source_content`).
Scan(&sources)
if err != nil {
t.Fatalf("failed to count the writes: %v", err)
}
if hits != totalRequests || sources != totalRequests {
t.Errorf("hit_count = %d and %d source_content rows, want %d of each",
hits, sources, totalRequests)
if sources != totalRequests {
t.Errorf("%d source_content rows, want %d", sources, totalRequests)
}
}
// writeLikeOneRequest makes the writes one request and the eviction pass
// make: it counts a cache hit, stores a source, records a transformed image
// and deletes that record again.
// make: it stores a source, records a transformed image and deletes that
// record again.
func writeLikeOneRequest(ctx context.Context, db *sql.DB, key string) error {
_, err := db.ExecContext(ctx,
`UPDATE cache_stats SET hit_count = hit_count + 1 WHERE id = 1`)
if err != nil {
return fmt.Errorf("counting a cache hit: %w", err)
}
_, err = db.ExecContext(ctx, `INSERT INTO source_content
_, err := db.ExecContext(ctx, `INSERT INTO source_content
(source_key, size_bytes) VALUES (?, 1)`, key)
if err != nil {
return fmt.Errorf("storing a source: %w", err)