2020-04-15 20:20:16 +01:00
// Copyright (C) 2020 Storj Labs, Inc.
// See LICENSE for copying information.
package expireddeletion
import (
"context"
"time"
"github.com/spacemonkeygo/monkit/v3"
"github.com/zeebo/errs"
"go.uber.org/zap"
"storj.io/common/sync2"
2021-04-21 13:42:57 +01:00
"storj.io/storj/satellite/metabase"
2020-04-15 20:20:16 +01:00
)
var (
2020-08-11 15:50:01 +01:00
// Error defines the expireddeletion chore errors class.
2021-04-28 09:06:17 +01:00
Error = errs . Class ( "expired deletion" )
2020-04-15 20:20:16 +01:00
mon = monkit . Package ( )
)
2020-07-16 15:18:02 +01:00
// Config contains configurable values for expired segment cleanup.
2020-04-15 20:20:16 +01:00
type Config struct {
2023-05-15 12:48:03 +01:00
Interval time . Duration ` help:"the time between each attempt to go through the db and clean up expired segments" releaseDefault:"24h" devDefault:"10s" testDefault:"$TESTINTERVAL" `
Enabled bool ` help:"set if expired segment cleanup is enabled or not" releaseDefault:"true" devDefault:"true" `
ListLimit int ` help:"how many expired objects to query in a batch" default:"100" `
AsOfSystemInterval time . Duration ` help:"as of system interval" releaseDefault:"-5m" devDefault:"-1us" testDefault:"-1us" hidden:"true" `
2020-04-15 20:20:16 +01:00
}
2020-12-05 16:01:42 +00:00
// Chore implements the expired segment cleanup chore.
2020-04-15 20:20:16 +01:00
//
// architecture: Chore
type Chore struct {
2020-11-30 12:33:06 +00:00
log * zap . Logger
config Config
2021-05-13 09:14:18 +01:00
metabase * metabase . DB
2020-04-15 20:20:16 +01:00
2020-11-30 12:33:06 +00:00
nowFn func ( ) time . Time
Loop * sync2 . Cycle
2020-04-15 20:20:16 +01:00
}
2020-07-16 15:18:02 +01:00
// NewChore creates a new instance of the expireddeletion chore.
2021-05-13 09:14:18 +01:00
func NewChore ( log * zap . Logger , config Config , metabase * metabase . DB ) * Chore {
2020-04-15 20:20:16 +01:00
return & Chore {
2020-11-30 12:33:06 +00:00
log : log ,
config : config ,
metabase : metabase ,
nowFn : time . Now ,
Loop : sync2 . NewCycle ( config . Interval ) ,
2020-04-15 20:20:16 +01:00
}
}
2020-07-16 15:18:02 +01:00
// Run starts the expireddeletion loop service.
2020-04-15 20:20:16 +01:00
func ( chore * Chore ) Run ( ctx context . Context ) ( err error ) {
defer mon . Task ( ) ( & ctx ) ( & err )
if ! chore . config . Enabled {
return nil
}
2020-11-30 12:33:06 +00:00
return chore . Loop . Run ( ctx , chore . deleteExpiredObjects )
}
2020-04-15 20:20:16 +01:00
2020-11-30 12:33:06 +00:00
// Close stops the expireddeletion chore.
func ( chore * Chore ) Close ( ) error {
chore . Loop . Close ( )
return nil
}
2020-04-15 20:20:16 +01:00
2020-11-30 12:33:06 +00:00
// SetNow allows tests to have the server act as if the current time is whatever they want.
func ( chore * Chore ) SetNow ( nowFn func ( ) time . Time ) {
chore . nowFn = nowFn
}
func ( chore * Chore ) deleteExpiredObjects ( ctx context . Context ) ( err error ) {
defer mon . Task ( ) ( & ctx ) ( & err )
chore . log . Debug ( "deleting expired objects" )
2021-03-15 15:00:20 +00:00
// TODO log error instead of crashing core until we will be sure
// that queries for deleting expired objects are stable
2021-03-16 11:54:40 +00:00
err = chore . metabase . DeleteExpiredObjects ( ctx , metabase . DeleteExpiredObjects {
2023-05-15 12:48:03 +01:00
ExpiredBefore : chore . nowFn ( ) ,
BatchSize : chore . config . ListLimit ,
AsOfSystemInterval : chore . config . AsOfSystemInterval ,
2021-03-16 11:54:40 +00:00
} )
2021-03-15 15:00:20 +00:00
if err != nil {
chore . log . Error ( "deleting expired objects failed" , zap . Error ( err ) )
}
return nil
2020-04-15 20:20:16 +01:00
}