From f19ab21b7d7dcddb3de0536c272cb22d581eb8d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Guillot?= Date: Sat, 19 May 2018 16:40:24 -0700 Subject: [PATCH] Archive read entries automatically after 60 days --- config/config.go | 30 +++++++++++++++--------------- daemon/daemon.go | 2 +- scheduler/scheduler.go | 10 +++++++--- storage/entry.go | 13 +++++++++++++ 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/config/config.go b/config/config.go index aae1d98e..bc4fc605 100644 --- a/config/config.go +++ b/config/config.go @@ -13,18 +13,18 @@ import ( ) const ( - defaultBaseURL = "http://localhost" - defaultDatabaseURL = "postgres://postgres:postgres@localhost/miniflux2?sslmode=disable" - defaultWorkerPoolSize = 5 - defaultPollingFrequency = 60 - defaultBatchSize = 10 - defaultDatabaseMaxConns = 20 - defaultListenAddr = "127.0.0.1:8080" - defaultCertFile = "" - defaultKeyFile = "" - defaultCertDomain = "" - defaultCertCache = "/tmp/cert_cache" - defaultSessionCleanupFrequency = 24 + defaultBaseURL = "http://localhost" + defaultDatabaseURL = "postgres://postgres:postgres@localhost/miniflux2?sslmode=disable" + defaultWorkerPoolSize = 5 + defaultPollingFrequency = 60 + defaultBatchSize = 10 + defaultDatabaseMaxConns = 20 + defaultListenAddr = "127.0.0.1:8080" + defaultCertFile = "" + defaultKeyFile = "" + defaultCertDomain = "" + defaultCertCache = "/tmp/cert_cache" + defaultCleanupFrequency = 24 ) // Config manages configuration parameters. @@ -137,9 +137,9 @@ func (c *Config) CertCache() string { return c.get("CERT_CACHE", defaultCertCache) } -// SessionCleanupFrequency returns the interval for session cleanup. -func (c *Config) SessionCleanupFrequency() int { - return c.getInt("SESSION_CLEANUP_FREQUENCY", defaultSessionCleanupFrequency) +// CleanupFrequency returns the interval for cleanup jobs. +func (c *Config) CleanupFrequency() int { + return c.getInt("CLEANUP_FREQUENCY", defaultCleanupFrequency) } // WorkerPoolSize returns the number of background worker. diff --git a/daemon/daemon.go b/daemon/daemon.go index cf64a1f9..fb759482 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -50,7 +50,7 @@ func Run(cfg *config.Config, store *storage.Storage) { cfg.BatchSize(), ) - scheduler.NewSessionScheduler(store, cfg.SessionCleanupFrequency()) + scheduler.NewCleanupScheduler(store, cfg.CleanupFrequency()) <-stop logger.Info("Shutting down the server...") diff --git a/scheduler/scheduler.go b/scheduler/scheduler.go index 5d6836ef..e354c09e 100644 --- a/scheduler/scheduler.go +++ b/scheduler/scheduler.go @@ -27,14 +27,18 @@ func NewFeedScheduler(store *storage.Storage, workerPool *WorkerPool, frequency, }() } -// NewSessionScheduler starts a new scheduler that clean old sessions. -func NewSessionScheduler(store *storage.Storage, frequency int) { +// NewCleanupScheduler starts a new scheduler that clean old sessions and archive read items. +func NewCleanupScheduler(store *storage.Storage, frequency int) { go func() { c := time.Tick(time.Duration(frequency) * time.Hour) for range c { nbSessions := store.CleanOldSessions() nbUserSessions := store.CleanOldUserSessions() - logger.Info("[SessionScheduler] cleaned %d sessions and %d user sessions", nbSessions, nbUserSessions) + logger.Info("[CleanupScheduler] Cleaned %d sessions and %d user sessions", nbSessions, nbUserSessions) + + if err := store.ArchiveEntries(); err != nil { + logger.Error("[CleanupScheduler] %v", err) + } } }() } diff --git a/storage/entry.go b/storage/entry.go index fb1fb593..65c02200 100644 --- a/storage/entry.go +++ b/storage/entry.go @@ -176,6 +176,19 @@ func (s *Storage) cleanupEntries(feedID int64, entryHashes []string) error { return nil } +// ArchiveEntries changes the status of read items to "removed" after 60 days. +func (s *Storage) ArchiveEntries() error { + query := ` + UPDATE entries SET status='removed' + WHERE id=ANY(SELECT id FROM entries WHERE status='read' AND starred is false AND published_at < now () - '60 days'::interval LIMIT 500) + ` + if _, err := s.db.Exec(query); err != nil { + return fmt.Errorf("unable to archive read entries: %v", err) + } + + return nil +} + // SetEntriesStatus update the status of the given list of entries. func (s *Storage) SetEntriesStatus(userID int64, entryIDs []int64, status string) error { defer timer.ExecutionTime(time.Now(), fmt.Sprintf("[Storage:SetEntriesStatus] userID=%d, entryIDs=%v, status=%s", userID, entryIDs, status))