From 1a1d52ef9fdc2001c634c29f832e347ef8dd9a42 Mon Sep 17 00:00:00 2001 From: Sydonian <794346190@qq.com> Date: Thu, 24 Apr 2025 15:36:28 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E6=AD=BB=E9=94=81=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/internal/mount/vfs/cache/file.go | 50 ++++++++++++++++--------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/client/internal/mount/vfs/cache/file.go b/client/internal/mount/vfs/cache/file.go index a5536d0..04bd678 100644 --- a/client/internal/mount/vfs/cache/file.go +++ b/client/internal/mount/vfs/cache/file.go @@ -107,7 +107,8 @@ type CacheFile struct { readers []*CacheFileHandle writers []*CacheFileHandle saveMetaChan chan any - stopSaveChan chan any + saveMetaLock *sync.Mutex + stopSaveMeta *bool isDeleted bool level CacheLevel @@ -170,7 +171,8 @@ func createNewCacheFile(cache *Cache, pathComps []string) (*CacheFile, error) { info: info, rwLock: &sync.RWMutex{}, saveMetaChan: make(chan any, 1), - stopSaveChan: make(chan any), + saveMetaLock: &sync.Mutex{}, + stopSaveMeta: new(bool), level: LevelComplete, metaFile: metaFile, dataFile: dataFile, @@ -178,7 +180,7 @@ func createNewCacheFile(cache *Cache, pathComps []string) (*CacheFile, error) { state: cacheState{}, } - go ch.serving(ch.saveMetaChan, ch.stopSaveChan) + go ch.serving(ch.saveMetaChan, ch.stopSaveMeta) return ch, nil } @@ -242,7 +244,8 @@ func loadCacheFile(cache *Cache, pathComps []string) (*CacheFile, error) { info: *info, rwLock: &sync.RWMutex{}, saveMetaChan: make(chan any, 1), - stopSaveChan: make(chan any), + saveMetaLock: &sync.Mutex{}, + stopSaveMeta: new(bool), level: LevelComplete, metaFile: metaFile, dataFile: dataFile, @@ -250,7 +253,7 @@ func loadCacheFile(cache *Cache, pathComps []string) (*CacheFile, error) { state: cacheState{}, } - go ch.serving(ch.saveMetaChan, ch.stopSaveChan) + go ch.serving(ch.saveMetaChan, ch.stopSaveMeta) return ch, nil } @@ -300,7 +303,8 @@ func newCacheFileFromObject(cache *Cache, pathComps []string, obj *clitypes.Obje remoteObj: obj, rwLock: &sync.RWMutex{}, saveMetaChan: make(chan any, 1), - stopSaveChan: make(chan any), + saveMetaLock: &sync.Mutex{}, + stopSaveMeta: new(bool), level: LevelComplete, metaFile: metaFile, dataFile: dataFile, @@ -308,7 +312,7 @@ func newCacheFileFromObject(cache *Cache, pathComps []string, obj *clitypes.Obje state: cacheState{}, } - go ch.serving(ch.saveMetaChan, ch.stopSaveChan) + go ch.serving(ch.saveMetaChan, ch.stopSaveMeta) return ch, nil } @@ -366,6 +370,12 @@ func (f *CacheFile) Release() { } func (f *CacheFile) LevelDown(level CacheLevel) bool { + if level <= LevelReadOnly { + // 如果降级到不需要保存元数据的级别,就要先暂停保存元数据的操作 + f.saveMetaLock.Lock() + defer f.saveMetaLock.Unlock() + } + f.rwLock.Lock() defer f.rwLock.Unlock() @@ -393,10 +403,11 @@ func (f *CacheFile) LevelDown(level CacheLevel) bool { // TODO 日志 f.saveMeta(f.info) } - // 这里会等待直到saveMeta线程退出 - f.stopSaveChan <- nil f.saveMetaChan = nil - f.stopSaveChan = nil + // 由于已经获取了saveMetaLock,所以这里设置true之后调用metaFile.Close不会导致saveMeta线程的保存失败 + // 因为saveMeta线程会先检查stopSaveMete的值 + *f.stopSaveMeta = true + f.stopSaveMeta = nil f.metaFile.Close() f.level = LevelReadOnly @@ -447,11 +458,11 @@ func (f *CacheFile) LevelUp(level CacheLevel) bool { } f.saveMetaChan = make(chan any, 1) - f.stopSaveChan = make(chan any) + f.stopSaveMeta = new(bool) f.metaFile = metaFile f.level = LevelMetaLoaded - go f.serving(f.saveMetaChan, f.stopSaveChan) + go f.serving(f.saveMetaChan, f.stopSaveMeta) if level <= f.level { break @@ -654,8 +665,8 @@ func (f *CacheFile) Truncate(size int64) error { return nil } -func (f *CacheFile) serving(saveMetaChan chan any, stopSaveChan chan any) { - ticker := time.NewTicker(time.Second * 5) +func (f *CacheFile) serving(saveMetaChan chan any, stopSaveMeta *bool) { + ticker := time.NewTicker(time.Second * 30) defer ticker.Stop() for { @@ -665,17 +676,21 @@ func (f *CacheFile) serving(saveMetaChan chan any, stopSaveChan chan any) { return } - case <-stopSaveChan: - return - case <-ticker.C: } + f.saveMetaLock.Lock() + if *stopSaveMeta { + f.saveMetaLock.Unlock() + break + } + f.rwLock.RLock() info := f.info.Clone() // 如果文件已被删除,则不能再保存元数据,防止覆盖掉新创建的同名文件 if f.isDeleted { f.rwLock.RUnlock() + f.saveMetaLock.Unlock() break } @@ -684,6 +699,7 @@ func (f *CacheFile) serving(saveMetaChan chan any, stopSaveChan chan any) { // TODO 错误日志 f.saveMeta(info) f.metaFile.Sync() + f.saveMetaLock.Unlock() } }