all: Pass db intervals as args not env vars (#6448)

This commit is contained in:
Simon Frei 2020-03-24 13:53:20 +01:00 committed by GitHub
parent ca89f12be6
commit 7f23de4f03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 34 deletions

View File

@ -670,6 +670,12 @@ func syncthingMain(runtimeOptions RuntimeOptions) {
secs, _ := strconv.Atoi(t)
appOpts.DeadlockTimeoutS = secs
}
if dur, err := time.ParseDuration(os.Getenv("STRECHECKDBEVERY")); err == nil {
appOpts.DBRecheckInterval = dur
}
if dur, err := time.ParseDuration(os.Getenv("STGCINDIRECTEVERY")); err == nil {
appOpts.DBIndirectGCInterval = dur
}
app := syncthing.New(cfg, ldb, evLogger, cert, appOpts)

View File

@ -9,7 +9,6 @@ package db
import (
"bytes"
"encoding/binary"
"os"
"time"
"github.com/syncthing/syncthing/lib/db/backend"
@ -31,16 +30,10 @@ const (
// Use indirection for the block list when it exceeds this many entries
blocksIndirectionCutoff = 3
recheckDefaultInterval = 30 * 24 * time.Hour
)
var indirectGCInterval = indirectGCDefaultInterval
func init() {
if dur, err := time.ParseDuration(os.Getenv("STGCINDIRECTEVERY")); err == nil {
indirectGCInterval = dur
}
}
// Lowlevel is the lowest level database interface. It has a very simple
// purpose: hold the actual backend database, and the in-memory state
// that belong to that database. In the same way that a single on disk
@ -48,27 +41,55 @@ func init() {
// any given backend.
type Lowlevel struct {
backend.Backend
folderIdx *smallIndex
deviceIdx *smallIndex
keyer keyer
gcMut sync.RWMutex
gcKeyCount int
gcStop chan struct{}
folderIdx *smallIndex
deviceIdx *smallIndex
keyer keyer
gcMut sync.RWMutex
gcKeyCount int
gcStop chan struct{}
indirectGCInterval time.Duration
recheckInterval time.Duration
}
func NewLowlevel(backend backend.Backend) *Lowlevel {
func NewLowlevel(backend backend.Backend, opts ...Option) *Lowlevel {
db := &Lowlevel{
Backend: backend,
folderIdx: newSmallIndex(backend, []byte{KeyTypeFolderIdx}),
deviceIdx: newSmallIndex(backend, []byte{KeyTypeDeviceIdx}),
gcMut: sync.NewRWMutex(),
gcStop: make(chan struct{}),
Backend: backend,
folderIdx: newSmallIndex(backend, []byte{KeyTypeFolderIdx}),
deviceIdx: newSmallIndex(backend, []byte{KeyTypeDeviceIdx}),
gcMut: sync.NewRWMutex(),
gcStop: make(chan struct{}),
indirectGCInterval: indirectGCDefaultInterval,
recheckInterval: recheckDefaultInterval,
}
for _, opt := range opts {
opt(db)
}
db.keyer = newDefaultKeyer(db.folderIdx, db.deviceIdx)
go db.gcRunner()
return db
}
type Option func(*Lowlevel)
// WithRecheckInterval sets the time interval in between metadata recalculations
// and consistency checks.
func WithRecheckInterval(dur time.Duration) Option {
return func(db *Lowlevel) {
if dur > 0 {
db.recheckInterval = dur
}
}
}
// WithIndirectGCInterval sets the time interval in between GC runs.
func WithIndirectGCInterval(dur time.Duration) Option {
return func(db *Lowlevel) {
if dur > 0 {
db.indirectGCInterval = dur
}
}
}
func (db *Lowlevel) Close() error {
close(db.gcStop)
return db.Backend.Close()
@ -498,7 +519,7 @@ func (db *Lowlevel) gcRunner() {
// directly, give the system a while to get up and running and do other
// stuff first. (We might have migrations and stuff which would be
// better off running before GC.)
next := db.timeUntil(indirectGCTimeKey, indirectGCInterval)
next := db.timeUntil(indirectGCTimeKey, db.indirectGCInterval)
if next < time.Minute {
next = time.Minute
}
@ -515,7 +536,7 @@ func (db *Lowlevel) gcRunner() {
l.Warnln("Database indirection GC failed:", err)
}
db.recordTime(indirectGCTimeKey)
t.Reset(db.timeUntil(indirectGCTimeKey, indirectGCInterval))
t.Reset(db.timeUntil(indirectGCTimeKey, db.indirectGCInterval))
}
}
}
@ -669,7 +690,7 @@ func (db *Lowlevel) loadMetadataTracker(folder string) *metadataTracker {
return db.getMetaAndCheck(folder)
}
if age := time.Since(meta.Created()); age > databaseRecheckInterval {
if age := time.Since(meta.Created()); age > db.recheckInterval {
l.Infof("Stored folder metadata for %q is %v old; recalculating", folder, age)
return db.getMetaAndCheck(folder)
}

View File

@ -13,7 +13,6 @@
package db
import (
"os"
"time"
"github.com/syncthing/syncthing/lib/db/backend"
@ -62,14 +61,6 @@ type FileIntf interface {
// continue iteration, false to stop.
type Iterator func(f FileIntf) bool
var databaseRecheckInterval = 30 * 24 * time.Hour
func init() {
if dur, err := time.ParseDuration(os.Getenv("STRECHECKDBEVERY")); err == nil {
databaseRecheckInterval = dur
}
}
func NewFileSet(folder string, fs fs.Filesystem, db *Lowlevel) *FileSet {
return &FileSet{
folder: folder,

View File

@ -70,6 +70,9 @@ type Options struct {
ProfilerURL string
ResetDeltaIdxs bool
Verbose bool
// null duration means use default value
DBRecheckInterval time.Duration
DBIndirectGCInterval time.Duration
}
type App struct {
@ -90,7 +93,7 @@ type App struct {
func New(cfg config.Wrapper, dbBackend backend.Backend, evLogger events.Logger, cert tls.Certificate, opts Options) *App {
a := &App{
cfg: cfg,
ll: db.NewLowlevel(dbBackend),
ll: db.NewLowlevel(dbBackend, db.WithRecheckInterval(opts.DBRecheckInterval), db.WithIndirectGCInterval(opts.DBIndirectGCInterval)),
evLogger: evLogger,
opts: opts,
cert: cert,