From c407994dd3aeb2c5a8e5f3fa070e7436fe308fc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20=27Necoro=27=20Neumann?= Date: Sat, 27 Feb 2021 23:39:51 +0100 Subject: Remove obsolete feeds from cache after 180 days --- CHANGELOG.md | 1 + internal/feed/cache/cache.go | 1 + internal/feed/cache/state.go | 9 +++++++-- internal/feed/cache/v1.go | 16 ++++++++++++++++ internal/feed/cache/v2.go | 4 ++++ pkg/util/util.go | 5 +++++ 6 files changed, 34 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bbc284..4608d88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Support for JSON v1.1 feed (via [gofeed](https://github.com/mmcdole/gofeed/pull/169)) ### Changed - Caches store now 1000 old entries (i.e., not included in the last fetch) at maximum. This will clean obsolete cruft and drastically reduce cache size. +- Feeds not updated (and not part of the config) for 180 days are now automatically removed from the cache. ## [0.7.0] - 2021-02-21 ### Changed diff --git a/internal/feed/cache/cache.go b/internal/feed/cache/cache.go index 171d0cb..311e871 100644 --- a/internal/feed/cache/cache.go +++ b/internal/feed/cache/cache.go @@ -24,6 +24,7 @@ const ( type Impl interface { cachedFeed(*feed.Feed) CachedFeed transformTo(Version) (Impl, error) + cleanup(knownDescriptors map[feed.Descriptor]bool) load(io.Reader) error store(io.Writer) error Version() Version diff --git a/internal/feed/cache/state.go b/internal/feed/cache/state.go index 2df0c74..ce6723a 100644 --- a/internal/feed/cache/state.go +++ b/internal/feed/cache/state.go @@ -11,6 +11,7 @@ import ( type State struct { feeds map[string]*feed.Feed cachedFeeds map[string]CachedFeed + knownFeeds map[feed.Descriptor]bool cache Cache cfg *config.Config } @@ -55,6 +56,7 @@ func (state *State) LoadCache(fileName string, forceNew bool) error { for name, feed := range state.feeds { state.cachedFeeds[name] = cache.cachedFeed(feed) + state.knownFeeds[feed.Descriptor()] = true } // state.feeds should not be used after loading the cache --> enforce a panic @@ -64,6 +66,7 @@ func (state *State) LoadCache(fileName string, forceNew bool) error { } func (state *State) StoreCache(fileName string) error { + state.cache.cleanup(state.knownFeeds) return state.cache.store(fileName) } @@ -115,9 +118,11 @@ func (state *State) Filter() { } func NewState(cfg *config.Config) (*State, error) { + numFeeds := len(cfg.Feeds) state := State{ - feeds: map[string]*feed.Feed{}, - cachedFeeds: map[string]CachedFeed{}, + feeds: make(map[string]*feed.Feed, numFeeds), + cachedFeeds: make(map[string]CachedFeed, numFeeds), + knownFeeds: make(map[feed.Descriptor]bool, numFeeds), cache: Cache{}, // loaded later on cfg: cfg, } diff --git a/internal/feed/cache/v1.go b/internal/feed/cache/v1.go index 0363303..5675db5 100644 --- a/internal/feed/cache/v1.go +++ b/internal/feed/cache/v1.go @@ -23,6 +23,7 @@ const ( v1Version Version = 1 startFeedId uint64 = 1 maxCacheSize = 1000 + maxCacheDays = 180 ) type feedId uint64 @@ -376,6 +377,21 @@ func filterItems(items []cachedItem) []cachedItem { return copiedItems } +func (cache *v1Cache) cleanup(knownDescriptors map[feed.Descriptor]bool) { + for descr, id := range cache.Ids { + if knownDescriptors[descr] { + // do not delete stuff still known to us + continue + } + + cf := cache.Feeds[id] + if cf.LastCheck.IsZero() || util.Days(time.Since(cf.LastCheck)) > maxCacheDays { + delete(cache.Feeds, id) + delete(cache.Ids, descr) + } + } +} + func (cache *v1Cache) load(reader io.Reader) error { decoder := gob.NewDecoder(reader) return decoder.Decode(cache) diff --git a/internal/feed/cache/v2.go b/internal/feed/cache/v2.go index 87636b6..2abf2a8 100644 --- a/internal/feed/cache/v2.go +++ b/internal/feed/cache/v2.go @@ -29,6 +29,10 @@ func (cache *v2Cache) transformTo(v Version) (Impl, error) { return nil, fmt.Errorf("Transformation not supported") } +func (cache *v2Cache) cleanup(knownDescriptors map[feed.Descriptor]bool) { + cache.asV1().cleanup(knownDescriptors) +} + func (cache *v2Cache) Version() Version { return v2Version } diff --git a/pkg/util/util.go b/pkg/util/util.go index 88d04c0..bacb494 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -21,3 +21,8 @@ func TimeFormat(t time.Time) string { return t.Format(time.ANSIC) } + +// Days returns the number of days in a duration. Fraction of days are discarded. +func Days(d time.Duration) int { + return int(d.Hours() / 24) +} -- cgit v1.2.3