2018-05-17 17:24:00 +00:00
|
|
|
package mailserver
|
|
|
|
|
|
|
|
import (
|
2019-01-23 13:32:45 +00:00
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
|
2024-10-28 20:54:17 +00:00
|
|
|
"go.uber.org/zap"
|
|
|
|
|
2024-09-26 22:37:32 +00:00
|
|
|
"github.com/status-im/status-go/common"
|
2024-10-28 20:54:17 +00:00
|
|
|
"github.com/status-im/status-go/logutils"
|
2018-05-17 17:24:00 +00:00
|
|
|
)
|
|
|
|
|
2019-01-23 13:32:45 +00:00
|
|
|
const (
|
|
|
|
dbCleanerBatchSize = 1000
|
|
|
|
dbCleanerPeriod = time.Hour
|
|
|
|
)
|
|
|
|
|
|
|
|
// dbCleaner removes old messages from a db.
|
|
|
|
type dbCleaner struct {
|
|
|
|
sync.RWMutex
|
2018-05-17 17:24:00 +00:00
|
|
|
|
2019-05-13 09:25:46 +00:00
|
|
|
db DB
|
2018-05-17 17:24:00 +00:00
|
|
|
batchSize int
|
2019-01-23 13:32:45 +00:00
|
|
|
retention time.Duration
|
|
|
|
|
|
|
|
period time.Duration
|
|
|
|
cancel chan struct{}
|
2018-05-17 17:24:00 +00:00
|
|
|
}
|
|
|
|
|
2019-01-23 13:32:45 +00:00
|
|
|
// newDBCleaner returns a new cleaner for db.
|
2019-05-13 09:25:46 +00:00
|
|
|
func newDBCleaner(db DB, retention time.Duration) *dbCleaner {
|
2019-01-23 13:32:45 +00:00
|
|
|
return &dbCleaner{
|
2018-05-17 17:24:00 +00:00
|
|
|
db: db,
|
2019-01-23 13:32:45 +00:00
|
|
|
retention: retention,
|
|
|
|
|
|
|
|
batchSize: dbCleanerBatchSize,
|
|
|
|
period: dbCleanerPeriod,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Start starts a loop that cleans up old messages.
|
|
|
|
func (c *dbCleaner) Start() {
|
2024-10-28 20:54:17 +00:00
|
|
|
logutils.ZapLogger().Info("Starting cleaning envelopes", zap.Duration("period", c.period), zap.Duration("retention", c.retention))
|
2019-01-23 13:32:45 +00:00
|
|
|
|
|
|
|
cancel := make(chan struct{})
|
|
|
|
|
|
|
|
c.Lock()
|
|
|
|
c.cancel = cancel
|
|
|
|
c.Unlock()
|
|
|
|
|
|
|
|
go c.schedule(c.period, cancel)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Stops stops the cleaning loop.
|
|
|
|
func (c *dbCleaner) Stop() {
|
|
|
|
c.Lock()
|
|
|
|
defer c.Unlock()
|
|
|
|
|
|
|
|
if c.cancel == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
close(c.cancel)
|
|
|
|
c.cancel = nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *dbCleaner) schedule(period time.Duration, cancel <-chan struct{}) {
|
2024-09-26 22:37:32 +00:00
|
|
|
defer common.LogOnPanic()
|
2019-01-23 13:32:45 +00:00
|
|
|
t := time.NewTicker(period)
|
|
|
|
defer t.Stop()
|
|
|
|
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case <-t.C:
|
|
|
|
count, err := c.PruneEntriesOlderThan(time.Now().Add(-c.retention))
|
|
|
|
if err != nil {
|
2024-10-28 20:54:17 +00:00
|
|
|
logutils.ZapLogger().Error("failed to prune data", zap.Error(err))
|
2019-01-23 13:32:45 +00:00
|
|
|
}
|
2024-10-28 20:54:17 +00:00
|
|
|
logutils.ZapLogger().Info("Prunned some some messages successfully", zap.Int("count", count))
|
2019-01-23 13:32:45 +00:00
|
|
|
case <-cancel:
|
|
|
|
return
|
|
|
|
}
|
2018-05-17 17:24:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-23 13:32:45 +00:00
|
|
|
// PruneEntriesOlderThan removes messages sent between lower and upper timestamps
|
|
|
|
// and returns how many have been removed.
|
|
|
|
func (c *dbCleaner) PruneEntriesOlderThan(t time.Time) (int, error) {
|
2019-05-10 10:26:57 +00:00
|
|
|
return c.db.Prune(t, c.batchSize)
|
2018-05-17 17:24:00 +00:00
|
|
|
}
|