MCPcopy Create free account
hub / github.com/devnullvoid/pvetui / NewBadgerCache

Function NewBadgerCache

internal/cache/badger_cache.go:23–89  ·  view source on GitHub ↗

NewBadgerCache creates a new Badger-based cache.

(dir string)

Source from the content-addressed store, hash-verified

21
22// NewBadgerCache creates a new Badger-based cache.
23func NewBadgerCache(dir string) (*BadgerCache, error) {
24 // Ensure the directory exists
25 if err := os.MkdirAll(dir, 0o750); err != nil {
26 return nil, fmt.Errorf("failed to create badger directory: %w", err)
27 }
28
29 // If there's a lock file but no process using it, remove it
30 lockFilePath := dir + "/LOCK"
31 if _, err := os.Stat(lockFilePath); err == nil {
32 // Lock file exists, check if it's stale
33 if isStale, err := isLockFileStale(lockFilePath); err != nil {
34 getCacheLogger().Debug("Failed to check if lock file is stale: %v", err)
35 } else if isStale {
36 getCacheLogger().Debug("Removing stale lock file")
37
38 if err := os.Remove(lockFilePath); err != nil {
39 return nil, fmt.Errorf("failed to remove stale lock file: %w", err)
40 }
41 }
42 }
43
44 // Open the Badger database with default options
45 opts := badger.DefaultOptions(dir)
46 // Reduce logging noise
47 opts.Logger = nil
48 // Use a smaller value size to reduce memory usage
49 opts.ValueLogFileSize = 1 << 20 // 1MB
50 // Use memory mapping for values to improve performance
51 // Note: In badger v4, these options may have been renamed or removed
52 // opts.ValueLogLoadingMode = badger.MemoryMap
53
54 db, err := badger.Open(opts)
55 if err != nil {
56 // Check if the error is due to resource temporarily unavailable
57 if os.IsExist(err) || isErrorTemporarilyUnavailable(err) {
58 return nil, fmt.Errorf("failed to open badger database (likely another process is using it): %w", err)
59 }
60
61 return nil, fmt.Errorf("failed to open badger database: %w", err)
62 }
63
64 cache := &BadgerCache{
65 db: db,
66 stopGC: make(chan struct{}),
67 }
68
69 // Run garbage collection in the background with proper cleanup
70 go func() {
71 ticker := time.NewTicker(5 * time.Minute)
72 defer ticker.Stop()
73
74 for {
75 select {
76 case <-ticker.C:
77 err := db.RunValueLogGC(0.5) // Run GC if 50% or more space can be reclaimed
78 if err != nil && err != badger.ErrNoRewrite {
79 getCacheLogger().Debug("Badger value log GC failed: %v", err)
80 }

Calls 5

isLockFileStaleFunction · 0.85
getCacheLoggerFunction · 0.85
DebugMethod · 0.65
StopMethod · 0.45