cache: handle errors when bolt tries to start

This commit is contained in:
remusb 2017-11-30 12:27:59 +02:00
parent 639e812789
commit 47450ba326
3 changed files with 18 additions and 20 deletions

4
cache/cache.go vendored
View File

@ -330,9 +330,9 @@ func NewFs(name, rpath string) (fs.Fs, error) {
dbPath = filepath.Join(dbPath, name+".db") dbPath = filepath.Join(dbPath, name+".db")
fs.Infof(name, "Storage DB path: %v", dbPath) fs.Infof(name, "Storage DB path: %v", dbPath)
f.cache = GetPersistent(dbPath, *cacheDbPurge) f.cache, err = GetPersistent(dbPath, *cacheDbPurge)
if err != nil { if err != nil {
return nil, err return nil, errors.Wrapf(err, "failed to start cache db")
} }
// Trap SIGINT and SIGTERM to close the DB handle gracefully // Trap SIGINT and SIGTERM to close the DB handle gracefully
c := make(chan os.Signal, 1) c := make(chan os.Signal, 1)

View File

@ -44,7 +44,8 @@ func TestInternalInit(t *testing.T) {
// delete the default path // delete the default path
dbPath := filepath.Join(fs.CacheDir, "cache-backend", *RemoteName+".db") dbPath := filepath.Join(fs.CacheDir, "cache-backend", *RemoteName+".db")
boltDb = cache.GetPersistent(dbPath, true) boltDb, err = cache.GetPersistent(dbPath, true)
require.NoError(t, err)
fstest.Initialise() fstest.Initialise()
if len(*WrapRemote) == 0 { if len(*WrapRemote) == 0 {

View File

@ -30,27 +30,23 @@ const (
) )
var boltMap = make(map[string]*Persistent) var boltMap = make(map[string]*Persistent)
var boltMapMx sync.RWMutex var boltMapMx sync.Mutex
// GetPersistent returns a single instance for the specific store // GetPersistent returns a single instance for the specific store
func GetPersistent(dbPath string, refreshDb bool) *Persistent { func GetPersistent(dbPath string, refreshDb bool) (*Persistent, error) {
// read lock to check if it exists // write lock to create one
boltMapMx.RLock()
if b, ok := boltMap[dbPath]; ok {
boltMapMx.RUnlock()
return b
}
boltMapMx.RUnlock()
// write lock to create one but let's check a 2nd time
boltMapMx.Lock() boltMapMx.Lock()
defer boltMapMx.Unlock() defer boltMapMx.Unlock()
if b, ok := boltMap[dbPath]; ok { if b, ok := boltMap[dbPath]; ok {
return b return b, nil
} }
boltMap[dbPath] = newPersistent(dbPath, refreshDb) bb, err := newPersistent(dbPath, refreshDb)
return boltMap[dbPath] if err != nil {
return nil, err
}
boltMap[dbPath] = bb
return boltMap[dbPath], nil
} }
// Persistent is a wrapper of persistent storage for a bolt.DB file // Persistent is a wrapper of persistent storage for a bolt.DB file
@ -64,7 +60,7 @@ type Persistent struct {
} }
// newPersistent builds a new wrapper and connects to the bolt.DB file // newPersistent builds a new wrapper and connects to the bolt.DB file
func newPersistent(dbPath string, refreshDb bool) *Persistent { func newPersistent(dbPath string, refreshDb bool) (*Persistent, error) {
dataPath := strings.TrimSuffix(dbPath, filepath.Ext(dbPath)) dataPath := strings.TrimSuffix(dbPath, filepath.Ext(dbPath))
b := &Persistent{ b := &Persistent{
@ -74,10 +70,11 @@ func newPersistent(dbPath string, refreshDb bool) *Persistent {
err := b.Connect(refreshDb) err := b.Connect(refreshDb)
if err != nil { if err != nil {
fs.Errorf(dbPath, "error opening storage cache: %v", err) fs.Errorf(dbPath, "Error opening storage cache. Is there another rclone running on the same remote? %v", err)
return nil, err
} }
return b return b, nil
} }
// String will return a human friendly string for this DB (currently the dbPath) // String will return a human friendly string for this DB (currently the dbPath)