feat: update dependencies and improve caching mechanism
Some checks failed
PR Check / check-and-test (pull_request) Failing after 2m11s
Some checks failed
PR Check / check-and-test (pull_request) Failing after 2m11s
- Added Prometheus client library for metrics collection. - Refactored garbage collection strategy from random deletion to LRU (Least Recently Used) deletion. - Introduced per-key locking in cache to prevent race conditions. - Enhanced logging with structured log messages for cache hits and misses. - Implemented a retry mechanism for upstream requests with exponential backoff. - Updated Go modules and indirect dependencies for better compatibility and performance. - Removed unused sync filesystem implementation. - Added version initialization to ensure a default version string.
This commit is contained in:
@@ -25,6 +25,8 @@ type DiskFS struct {
|
||||
capacity int64
|
||||
mu sync.Mutex
|
||||
sg sync.WaitGroup
|
||||
|
||||
bytePool sync.Pool // Pool for []byte slices
|
||||
}
|
||||
|
||||
// New creates a new DiskFS.
|
||||
@@ -42,6 +44,11 @@ func new(root string, capacity int64, skipinit bool) *DiskFS {
|
||||
if !os.IsNotExist(err) {
|
||||
panic(err) // panic if the error is something other than not found
|
||||
}
|
||||
os.Mkdir(root, 0755) // create the root directory if it does not exist
|
||||
fi, err = os.Stat(root) // re-stat to get the file info
|
||||
if err != nil {
|
||||
panic(err) // panic if the re-stat fails
|
||||
}
|
||||
}
|
||||
if !fi.IsDir() {
|
||||
panic("disk root must be a directory") // panic if the root is not a directory
|
||||
@@ -53,6 +60,9 @@ func new(root string, capacity int64, skipinit bool) *DiskFS {
|
||||
capacity: capacity,
|
||||
mu: sync.Mutex{},
|
||||
sg: sync.WaitGroup{},
|
||||
bytePool: sync.Pool{
|
||||
New: func() interface{} { return make([]byte, 0) }, // Initial capacity for pooled slices is 0, will grow as needed
|
||||
},
|
||||
}
|
||||
|
||||
os.MkdirAll(dfs.root, 0755)
|
||||
@@ -73,8 +83,6 @@ func NewSkipInit(root string, capacity int64) *DiskFS {
|
||||
}
|
||||
|
||||
func (d *DiskFS) init() {
|
||||
// logger.Logger.Info().Str("name", d.Name()).Str("root", d.root).Str("capacity", units.HumanSize(float64(d.capacity))).Msg("init")
|
||||
|
||||
tstart := time.Now()
|
||||
|
||||
d.walk(d.root)
|
||||
@@ -110,11 +118,9 @@ func (d *DiskFS) walk(path string) {
|
||||
|
||||
d.mu.Lock()
|
||||
k := strings.ReplaceAll(npath[len(d.root)+1:], "\\", "/")
|
||||
logger.Logger.Debug().Str("name", k).Str("root", d.root).Msg("walk")
|
||||
d.info[k] = vfs.NewFileInfoFromOS(info, k)
|
||||
d.mu.Unlock()
|
||||
|
||||
// logger.Logger.Debug().Str("name", d.Name()).Str("root", d.root).Str("capacity", units.HumanSize(float64(d.capacity))).Str("path", npath).Msg("init")
|
||||
return nil
|
||||
})
|
||||
}()
|
||||
@@ -153,10 +159,7 @@ func (d *DiskFS) Set(key string, src []byte) error {
|
||||
}
|
||||
}
|
||||
|
||||
logger.Logger.Debug().Str("name", key).Str("root", d.root).Msg("set")
|
||||
|
||||
if _, err := d.Stat(key); err == nil {
|
||||
logger.Logger.Debug().Str("name", key).Str("root", d.root).Msg("delete")
|
||||
d.Delete(key)
|
||||
}
|
||||
|
||||
@@ -224,7 +227,16 @@ func (d *DiskFS) Get(key string) ([]byte, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return data, nil
|
||||
// Use pooled slice for return if possible, but since ReadFile allocates new, copy to pool if beneficial
|
||||
dst := d.bytePool.Get().([]byte)
|
||||
if cap(dst) < len(data) {
|
||||
dst = make([]byte, len(data)) // create a new slice if the pool slice is too small
|
||||
} else {
|
||||
dst = dst[:len(data)] // reuse the pool slice, but resize it to fit
|
||||
}
|
||||
dst = dst[:len(data)]
|
||||
copy(dst, data)
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
// Stat returns the FileInfo of key. If key is not found in the cache, it will stat the file on disk. If the file is not found on disk, it will return vfs.ErrNotFound.
|
||||
@@ -236,8 +248,6 @@ func (d *DiskFS) Stat(key string) (*vfs.FileInfo, error) {
|
||||
return nil, vfserror.ErrInvalidKey
|
||||
}
|
||||
|
||||
logger.Logger.Debug().Str("name", key).Str("root", d.root).Msg("stat")
|
||||
|
||||
d.mu.Lock()
|
||||
defer d.mu.Unlock()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user