This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / spindle / engine / cache_prune.go
1.9 kB 85 lines
1package engine 2 3import ( 4 "context" 5 "log/slog" 6 "time" 7 8 "tangled.org/core/spindle/db" 9 "tangled.org/core/spindle/storage" 10) 11 12const ( 13 cachePruneBatch = 100 14 cachePendingMaxAge = time.Hour 15) 16 17func StartCachePruner(ctx context.Context, l *slog.Logger, index *db.DB, store storage.Storage, retention, interval time.Duration) { 18 if store == nil || interval <= 0 { 19 return 20 } 21 go func() { 22 prune := func() { 23 total := 0 24 for { 25 n, err := PruneCaches(ctx, index, store, time.Now(), retention, cachePendingMaxAge, cachePruneBatch) 26 total += n 27 if err != nil { 28 l.Warn("cache prune failed", "count", total, "err", err) 29 return 30 } 31 if n < cachePruneBatch { 32 if total > 0 { 33 l.Info("pruned cache entries", "count", total) 34 } 35 return 36 } 37 } 38 } 39 prune() 40 ticker := time.NewTicker(interval) 41 defer ticker.Stop() 42 for { 43 select { 44 case <-ctx.Done(): 45 return 46 case <-ticker.C: 47 prune() 48 } 49 } 50 }() 51} 52 53func PruneCaches(ctx context.Context, index *db.DB, store storage.Storage, now time.Time, retention, pendingMaxAge time.Duration, limit int) (int, error) { 54 readyBefore := time.Unix(0, 0) 55 if retention > 0 { 56 readyBefore = now.Add(-retention) 57 } 58 entries, err := index.ExpiredCacheEntries(ctx, readyBefore, now.Add(-pendingMaxAge), limit) 59 if err != nil { 60 return 0, err 61 } 62 pruned := 0 63 for _, entry := range entries { 64 if entry.State != "deleting" { 65 claimed, err := index.ClaimCacheEntry(ctx, entry.ID, entry.State, entry.LastUsedAt) 66 if err != nil { 67 return pruned, err 68 } 69 if !claimed { 70 continue 71 } 72 } 73 if err := store.Delete(ctx, entry.StorageKey); err != nil { 74 if entry.State != "deleting" { 75 _ = index.RestoreCacheEntryState(context.WithoutCancel(ctx), entry.ID, entry.State) 76 } 77 return pruned, err 78 } 79 if err := index.DeleteCacheEntry(ctx, entry.ID); err != nil { 80 return pruned, err 81 } 82 pruned++ 83 } 84 return pruned, nil 85}