github.com/status-im/status-go@v1.1.0/mailserver/cleaner.go (about)

     1  package mailserver
     2  
     3  import (
     4  	"sync"
     5  	"time"
     6  
     7  	"github.com/ethereum/go-ethereum/log"
     8  )
     9  
    10  const (
    11  	dbCleanerBatchSize = 1000
    12  	dbCleanerPeriod    = time.Hour
    13  )
    14  
    15  // dbCleaner removes old messages from a db.
    16  type dbCleaner struct {
    17  	sync.RWMutex
    18  
    19  	db        DB
    20  	batchSize int
    21  	retention time.Duration
    22  
    23  	period time.Duration
    24  	cancel chan struct{}
    25  }
    26  
    27  // newDBCleaner returns a new cleaner for db.
    28  func newDBCleaner(db DB, retention time.Duration) *dbCleaner {
    29  	return &dbCleaner{
    30  		db:        db,
    31  		retention: retention,
    32  
    33  		batchSize: dbCleanerBatchSize,
    34  		period:    dbCleanerPeriod,
    35  	}
    36  }
    37  
    38  // Start starts a loop that cleans up old messages.
    39  func (c *dbCleaner) Start() {
    40  	log.Info("Starting cleaning envelopes", "period", c.period, "retention", c.retention)
    41  
    42  	cancel := make(chan struct{})
    43  
    44  	c.Lock()
    45  	c.cancel = cancel
    46  	c.Unlock()
    47  
    48  	go c.schedule(c.period, cancel)
    49  }
    50  
    51  // Stops stops the cleaning loop.
    52  func (c *dbCleaner) Stop() {
    53  	c.Lock()
    54  	defer c.Unlock()
    55  
    56  	if c.cancel == nil {
    57  		return
    58  	}
    59  	close(c.cancel)
    60  	c.cancel = nil
    61  }
    62  
    63  func (c *dbCleaner) schedule(period time.Duration, cancel <-chan struct{}) {
    64  	t := time.NewTicker(period)
    65  	defer t.Stop()
    66  
    67  	for {
    68  		select {
    69  		case <-t.C:
    70  			count, err := c.PruneEntriesOlderThan(time.Now().Add(-c.retention))
    71  			if err != nil {
    72  				log.Error("failed to prune data", "err", err)
    73  			}
    74  			log.Info("Prunned some some messages successfully", "count", count)
    75  		case <-cancel:
    76  			return
    77  		}
    78  	}
    79  }
    80  
    81  // PruneEntriesOlderThan removes messages sent between lower and upper timestamps
    82  // and returns how many have been removed.
    83  func (c *dbCleaner) PruneEntriesOlderThan(t time.Time) (int, error) {
    84  	return c.db.Prune(t, c.batchSize)
    85  }