diff options
-rw-r--r-- | worker/imap/cache.go | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/worker/imap/cache.go b/worker/imap/cache.go index c5d3dcc0..cc97b922 100644 --- a/worker/imap/cache.go +++ b/worker/imap/cache.go @@ -4,9 +4,11 @@ import ( "bufio" "bytes" "encoding/gob" + "errors" "fmt" "os" "path" + "reflect" "time" "git.sr.ht/~rjarry/aerc/lib/parse" @@ -29,6 +31,14 @@ type CachedHeader struct { Created time.Time } +var ( + // cacheTag should be updated when changing the cache + // structure; this will ensure that the user's cache is cleared and + // reloaded when the underlying cache structure changes + cacheTag = []byte("0000") + cacheTagKey = []byte("cache.tag") +) + // initCacheDb opens (or creates) the database for the cache. One database is // created per account func (w *IMAPWorker) initCacheDb(acct string) { @@ -47,8 +57,26 @@ func (w *IMAPWorker) initCacheDb(acct string) { } w.cache = db log.Debugf("cache db opened: %s", p) - if w.config.cacheMaxAge.Hours() > 0 { - go w.cleanCache(p) + + tag, err := w.cache.Get(cacheTagKey, nil) + clearCache := errors.Is(err, leveldb.ErrNotFound) || + !reflect.DeepEqual(tag, cacheTag) + switch { + case clearCache: + log.Infof("current cache tag is '%s' but found '%s'", + cacheTag, tag) + log.Warnf("tag mismatch: clear cache") + w.clearCache() + if err = w.cache.Put(cacheTagKey, cacheTag, nil); err != nil { + log.Errorf("could not set the current cache tag") + } + case err != nil: + log.Errorf("could not get the cache tag from db") + default: + log.Tracef("cache version match") + if w.config.cacheMaxAge.Hours() > 0 { + go w.cleanCache(p) + } } } @@ -172,3 +200,14 @@ func (w *IMAPWorker) cleanCache(path string) { log.Debugf("%s: removed %d/%d expired entries in %s", path, removed, scanned, elapsed) } + +// clearCache clears the entire cache +func (w *IMAPWorker) clearCache() { + iter := w.cache.NewIterator(nil, nil) + for iter.Next() { + if err := w.cache.Delete(iter.Key(), nil); err != nil { + log.Errorf("error clearing cache: %v", err) + } + } + iter.Release() +} |