Fix mutexes in the cacher

This commit is contained in:
2026-02-12 02:28:23 +03:00
parent 2fbc12d770
commit f22111aa43
5 changed files with 36 additions and 11 deletions

View File

@@ -20,17 +20,18 @@ type Cacher struct {
transcoder domains.Transcoder
cacheDir string
cacheMutex sync.RWMutex
currentSize int64
maxSize int64
items map[string]*models.CacheItem
itemsMutex sync.RWMutex
stat map[string]*models.CacherStat
statMutex sync.RWMutex
}
func New(app *application.App) *Cacher {
return &Cacher{
app: app,
cacheDir: app.Config().Paths.Destination + "./.cache",
cacheDir: app.Config().Paths.Destination + "/.cache",
maxSize: app.Config().FakeTunes.CacheSize * 1024 * 1024,
items: make(map[string]*models.CacheItem, 0),
stat: make(map[string]*models.CacherStat, 0),

View File

@@ -18,6 +18,8 @@ func (c *Cacher) GetFileDTO(sourcePath string) (*dto.CacheItem, error) {
return nil, fmt.Errorf("%w: %w (%w)", ErrCacher, ErrFailedToGetSourceFile, err)
}
c.app.Logger().WithField("item", item).Debug("Retrieved cache item")
return models.CacheItemModelToDTO(item), nil
}
@@ -32,8 +34,8 @@ func (c *Cacher) getFile(sourcePath string) (*models.CacheItem, error) {
cacheKey := fmt.Sprintf("%x", hash)
cacheFilePath := filepath.Join(c.cacheDir, cacheKey+".m4a")
c.cacheMutex.Lock()
defer c.cacheMutex.Unlock()
c.itemsMutex.Lock()
defer c.itemsMutex.Unlock()
// Check if file information exists in cache
if item, ok := c.items[cacheKey]; ok {
@@ -92,7 +94,7 @@ func (c *Cacher) getFile(sourcePath string) (*models.CacheItem, error) {
c.updateCachedStat(sourcePath, size)
// TODO: run cleanup on inotify events.
c.cleanup()
// c.cleanup()
return item, nil
}

View File

@@ -12,6 +12,9 @@ import (
// getStat returns file size without triggering conversion (for ls/stat)
func (c *Cacher) GetStat(sourcePath string) (int64, error) {
c.statMutex.RLock()
defer c.statMutex.RUnlock()
// First check cache
if size, ok := c.getCachedStat(sourcePath); ok {
return size, nil
@@ -43,8 +46,8 @@ func (c *Cacher) GetStat(sourcePath string) (int64, error) {
// updateCachedStat updates the stat cache
func (c *Cacher) updateCachedStat(sourcePath string, size int64) {
c.cacheMutex.Lock()
defer c.cacheMutex.Unlock()
c.statMutex.Lock()
defer c.statMutex.Unlock()
c.stat[sourcePath] = &models.CacherStat{
Size: size,
@@ -54,8 +57,8 @@ func (c *Cacher) updateCachedStat(sourcePath string, size int64) {
// getCachedStat returns cached file stats
func (c *Cacher) getCachedStat(sourcePath string) (int64, bool) {
c.cacheMutex.RLock()
defer c.cacheMutex.RUnlock()
c.statMutex.RLock()
defer c.statMutex.RUnlock()
if stat, ok := c.stat[sourcePath]; ok {
return stat.Size, true

View File

@@ -2,7 +2,6 @@ package filesystem
import (
"context"
"log"
"os"
"path/filepath"
"syscall"
@@ -123,11 +122,14 @@ func (f *MusicFile) Open(ctx context.Context, flags uint32) (fh fs.FileHandle, f
entry, err := f.f.cacher.GetFileDTO(f.sourcePath)
if err != nil {
log.Printf("Failed to convert %s to ALAC: %v", filepath.Base(f.sourcePath), err)
f.f.app.Logger().WithError(err).WithField("source file", f.sourcePath).
WithError(err).Error("Failed to convert file to cache")
return nil, 0, syscall.EIO
}
f.f.app.Logger().WithField("path", entry.Path).Debug("Opening cached file")
file, err := os.Open(entry.Path)
if err != nil {
return nil, 0, syscall.EIO