allow configuring scanner cycles dynamically (#11931)

This allows us to speed up or slow down sleeps
between multiple scanner cycles, helps in testing
as well as some deployments might want to run
scanner more frequently.

This change is also dynamic can be applied on
a running cluster, subsequent cycles pickup
the newly set value.
This commit is contained in:
Harshavardhana
2021-03-30 13:59:02 -07:00
committed by GitHub
parent e9fede88b3
commit 014edd3462
4 changed files with 49 additions and 11 deletions

View File

@@ -44,7 +44,6 @@ import (
const (
dataScannerSleepPerFolder = time.Millisecond // Time to wait between folders.
dataScannerStartDelay = 1 * time.Minute // Time to wait on startup and between cycles.
dataUsageUpdateDirCycles = 16 // Visit all folders every n cycles.
healDeleteDangling = true
@@ -59,6 +58,7 @@ var (
dataScannerLeaderLockTimeout = newDynamicTimeout(30*time.Second, 10*time.Second)
// Sleeper values are updated when config is loaded.
scannerSleeper = newDynamicSleeper(10, 10*time.Second)
scannerCycle = &safeDuration{}
)
// initDataScanner will start the scanner in the background.
@@ -66,6 +66,23 @@ func initDataScanner(ctx context.Context, objAPI ObjectLayer) {
go runDataScanner(ctx, objAPI)
}
type safeDuration struct {
sync.Mutex
t time.Duration
}
func (s *safeDuration) Update(t time.Duration) {
s.Lock()
defer s.Unlock()
s.t = t
}
func (s *safeDuration) Get() time.Duration {
s.Lock()
defer s.Unlock()
return s.t
}
// runDataScanner will start a data scanner.
// The function will block until the context is canceled.
// There should only ever be one scanner running per cluster.
@@ -77,7 +94,7 @@ func runDataScanner(ctx context.Context, objAPI ObjectLayer) {
for {
ctx, err = locker.GetLock(ctx, dataScannerLeaderLockTimeout)
if err != nil {
time.Sleep(time.Duration(r.Float64() * float64(dataScannerStartDelay)))
time.Sleep(time.Duration(r.Float64() * float64(scannerCycle.Get())))
continue
}
break
@@ -101,7 +118,7 @@ func runDataScanner(ctx context.Context, objAPI ObjectLayer) {
br.Close()
}
scannerTimer := time.NewTimer(dataScannerStartDelay)
scannerTimer := time.NewTimer(scannerCycle.Get())
defer scannerTimer.Stop()
for {
@@ -110,7 +127,7 @@ func runDataScanner(ctx context.Context, objAPI ObjectLayer) {
return
case <-scannerTimer.C:
// Reset the timer for next cycle.
scannerTimer.Reset(dataScannerStartDelay)
scannerTimer.Reset(scannerCycle.Get())
if intDataUpdateTracker.debug {
console.Debugln("starting scanner cycle")