From e5d191ca73eb9cd26465348b1e78679486293c3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Mon, 16 Oct 2023 12:00:00 +0800 Subject: [PATCH] Add retry for bbolt open --- experimental/clashapi/cachefile/cache.go | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/experimental/clashapi/cachefile/cache.go b/experimental/clashapi/cachefile/cache.go index 9acdadf2..0b96fa5d 100644 --- a/experimental/clashapi/cachefile/cache.go +++ b/experimental/clashapi/cachefile/cache.go @@ -1,6 +1,7 @@ package cachefile import ( + "errors" "net/netip" "os" "strings" @@ -11,6 +12,7 @@ import ( bboltErrors "github.com/sagernet/bbolt/errors" "github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing/common" + E "github.com/sagernet/sing/common/exceptions" ) var ( @@ -42,13 +44,25 @@ type CacheFile struct { func Open(path string, cacheID string) (*CacheFile, error) { const fileMode = 0o666 options := bbolt.Options{Timeout: time.Second} - db, err := bbolt.Open(path, fileMode, &options) - switch err { - case bboltErrors.ErrInvalid, bboltErrors.ErrChecksum, bboltErrors.ErrVersionMismatch: - if err = os.Remove(path); err != nil { + var ( + db *bbolt.DB + err error + ) + for i := 0; i < 10; i++ { + db, err = bbolt.Open(path, fileMode, &options) + if err == nil { break } - db, err = bbolt.Open(path, 0o666, &options) + if errors.Is(err, bboltErrors.ErrTimeout) { + continue + } + if E.IsMulti(err, bboltErrors.ErrInvalid, bboltErrors.ErrChecksum, bboltErrors.ErrVersionMismatch) { + rmErr := os.Remove(path) + if rmErr != nil { + return nil, err + } + } + time.Sleep(100 * time.Millisecond) } if err != nil { return nil, err