lib/model: Don't include iolimiter wait into sync duration (#6593)

This commit is contained in:
Simon Frei 2020-05-04 08:43:35 +02:00 committed by GitHub
parent f560e8c850
commit 914eb77ca4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 39 additions and 36 deletions

View File

@ -56,6 +56,8 @@ type folder struct {
scanErrorsMut sync.Mutex scanErrorsMut sync.Mutex
pullScheduled chan struct{} pullScheduled chan struct{}
pullPause time.Duration
pullFailTimer *time.Timer
doInSyncChan chan syncRequest doInSyncChan chan syncRequest
@ -82,7 +84,7 @@ type puller interface {
} }
func newFolder(model *model, fset *db.FileSet, ignores *ignore.Matcher, cfg config.FolderConfiguration, evLogger events.Logger, ioLimiter *byteSemaphore) folder { func newFolder(model *model, fset *db.FileSet, ignores *ignore.Matcher, cfg config.FolderConfiguration, evLogger events.Logger, ioLimiter *byteSemaphore) folder {
return folder{ f := folder{
stateTracker: newStateTracker(cfg.ID, evLogger), stateTracker: newStateTracker(cfg.ID, evLogger),
FolderConfiguration: cfg, FolderConfiguration: cfg,
FolderStatisticsReference: stats.NewFolderStatisticsReference(model.db, cfg.ID), FolderStatisticsReference: stats.NewFolderStatisticsReference(model.db, cfg.ID),
@ -111,6 +113,10 @@ func newFolder(model *model, fset *db.FileSet, ignores *ignore.Matcher, cfg conf
restartWatchChan: make(chan struct{}, 1), restartWatchChan: make(chan struct{}, 1),
watchMut: sync.NewMutex(), watchMut: sync.NewMutex(),
} }
f.pullPause = f.pullBasePause()
f.pullFailTimer = time.NewTimer(0)
<-f.pullFailTimer.C
return f
} }
func (f *folder) serve(ctx context.Context) { func (f *folder) serve(ctx context.Context) {
@ -127,56 +133,27 @@ func (f *folder) serve(ctx context.Context) {
f.setState(FolderIdle) f.setState(FolderIdle)
}() }()
pause := f.basePause()
pullFailTimer := time.NewTimer(0)
<-pullFailTimer.C
if f.FSWatcherEnabled && f.getHealthErrorAndLoadIgnores() == nil { if f.FSWatcherEnabled && f.getHealthErrorAndLoadIgnores() == nil {
f.startWatch() f.startWatch()
} }
initialCompleted := f.initialScanFinished initialCompleted := f.initialScanFinished
pull := func() {
startTime := time.Now()
if f.pull() {
// We're good. Don't schedule another pull and reset
// the pause interval.
pause = f.basePause()
return
}
// Pulling failed, try again later.
delay := pause + time.Since(startTime)
l.Infof("Folder %v isn't making sync progress - retrying in %v.", f.Description(), delay)
pullFailTimer.Reset(delay)
if pause < 60*f.basePause() {
pause *= 2
}
}
for { for {
select { select {
case <-f.ctx.Done(): case <-f.ctx.Done():
return return
case <-f.pullScheduled: case <-f.pullScheduled:
pullFailTimer.Stop() f.pull()
select {
case <-pullFailTimer.C:
default:
}
pull()
case <-pullFailTimer.C: case <-f.pullFailTimer.C:
pull() f.pull()
case <-initialCompleted: case <-initialCompleted:
// Initial scan has completed, we should do a pull // Initial scan has completed, we should do a pull
initialCompleted = nil // never hit this case again initialCompleted = nil // never hit this case again
if !f.pull() { f.pull()
// Pulling failed, try again later.
pullFailTimer.Reset(pause)
}
case <-f.forcedRescanRequested: case <-f.forcedRescanRequested:
f.handleForcedRescans() f.handleForcedRescans()
@ -300,6 +277,12 @@ func (f *folder) getHealthErrorWithoutIgnores() error {
} }
func (f *folder) pull() bool { func (f *folder) pull() bool {
f.pullFailTimer.Stop()
select {
case <-f.pullFailTimer.C:
default:
}
select { select {
case <-f.initialScanFinished: case <-f.initialScanFinished:
default: default:
@ -327,7 +310,27 @@ func (f *folder) pull() bool {
} }
defer f.ioLimiter.give(1) defer f.ioLimiter.give(1)
return f.puller.pull() startTime := time.Now()
success := f.puller.pull()
basePause := f.pullBasePause()
if success {
// We're good. Don't schedule another pull and reset
// the pause interval.
f.pullPause = basePause
return true
}
// Pulling failed, try again later.
delay := f.pullPause + time.Since(startTime)
l.Infof("Folder %v isn't making sync progress - retrying in %v.", f.Description(), delay)
f.pullFailTimer.Reset(delay)
if f.pullPause < 60*basePause {
f.pullPause *= 2
}
return false
} }
func (f *folder) scanSubdirs(subDirs []string) error { func (f *folder) scanSubdirs(subDirs []string) error {
@ -806,7 +809,7 @@ func (f *folder) setError(err error) {
f.stateTracker.setError(err) f.stateTracker.setError(err)
} }
func (f *folder) basePause() time.Duration { func (f *folder) pullBasePause() time.Duration {
if f.PullerPauseS == 0 { if f.PullerPauseS == 0 {
return defaultPullerPause return defaultPullerPause
} }