2019-11-26 16:25:21 +00:00
|
|
|
// Copyright (C) 2019 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package pieces
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"go.uber.org/zap"
|
|
|
|
"golang.org/x/sync/errgroup"
|
|
|
|
|
2019-12-27 11:48:47 +00:00
|
|
|
"storj.io/common/sync2"
|
2019-11-26 16:25:21 +00:00
|
|
|
"storj.io/storj/storagenode/trust"
|
|
|
|
)
|
|
|
|
|
2020-07-16 15:18:02 +01:00
|
|
|
// TrashChore is the chore that periodically empties the trash.
|
2019-11-26 16:25:21 +00:00
|
|
|
type TrashChore struct {
|
|
|
|
log *zap.Logger
|
|
|
|
interval time.Duration
|
|
|
|
trashExpiryInterval time.Duration
|
|
|
|
store *Store
|
|
|
|
trust *trust.Pool
|
|
|
|
cycle *sync2.Cycle
|
|
|
|
started sync2.Fence
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewTrashChore instantiates a new TrashChore. choreInterval is how often this
|
|
|
|
// chore runs, and trashExpiryInterval is passed into the EmptyTrash method to
|
2020-07-16 15:18:02 +01:00
|
|
|
// determine which trashed pieces should be deleted.
|
2019-11-26 16:25:21 +00:00
|
|
|
func NewTrashChore(log *zap.Logger, choreInterval, trashExpiryInterval time.Duration, trust *trust.Pool, store *Store) *TrashChore {
|
|
|
|
return &TrashChore{
|
|
|
|
log: log,
|
|
|
|
interval: choreInterval,
|
|
|
|
trashExpiryInterval: trashExpiryInterval,
|
|
|
|
store: store,
|
|
|
|
trust: trust,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-16 15:18:02 +01:00
|
|
|
// Run starts the cycle.
|
2019-11-26 16:25:21 +00:00
|
|
|
func (chore *TrashChore) Run(ctx context.Context) (err error) {
|
|
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
|
|
|
|
chore.cycle = sync2.NewCycle(chore.interval)
|
|
|
|
chore.cycle.Start(ctx, &errgroup.Group{}, func(ctx context.Context) error {
|
2020-01-06 12:34:54 +00:00
|
|
|
chore.log.Debug("starting emptying trash")
|
2019-11-26 16:25:21 +00:00
|
|
|
|
|
|
|
for _, satelliteID := range chore.trust.GetSatellites(ctx) {
|
|
|
|
trashedBefore := time.Now().Add(-chore.trashExpiryInterval)
|
|
|
|
err := chore.store.EmptyTrash(ctx, satelliteID, trashedBefore)
|
|
|
|
if err != nil {
|
2020-01-06 12:34:54 +00:00
|
|
|
chore.log.Error("emptying trash failed", zap.Error(err))
|
2019-11-26 16:25:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
chore.started.Release()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// TriggerWait ensures that the cycle is done at least once and waits for
|
|
|
|
// completion. If the cycle is currently running it waits for the previous to
|
|
|
|
// complete and then runs.
|
|
|
|
func (chore *TrashChore) TriggerWait(ctx context.Context) {
|
|
|
|
chore.started.Wait(ctx)
|
|
|
|
chore.cycle.TriggerWait()
|
|
|
|
}
|
|
|
|
|
2020-07-16 15:18:02 +01:00
|
|
|
// Close the chore.
|
2019-11-26 16:25:21 +00:00
|
|
|
func (chore *TrashChore) Close() error {
|
|
|
|
if chore.cycle != nil {
|
|
|
|
chore.cycle.Close()
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|