From 6b188ebcf34f7c82e636c7bec772537a839f1a2d Mon Sep 17 00:00:00 2001 From: Simon Frei Date: Thu, 20 Apr 2017 00:20:34 +0000 Subject: [PATCH] lib/model: Mark initial scan as finished even if failed and refactor (fixes #4103) The mechanism to disallow manual scans before the initial scan completed (#3996) , had the side effect, that if the initial scan failed, no further scans are allowed. So this marks the initial scan as finished regardless of whether it succeeded or not. There was also redundant code in rofolder and a pointless check for folder health in scanSubsIfHealthy (happens in internalScanFolderSubdirs as well). This also moves logging from folder.go to ro/rw-folder.go to include the information about whether it is send-only or send-receive GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/4104 --- lib/model/folder.go | 17 ++++++---------- lib/model/rofolder.go | 41 ++++++++++++++------------------------ lib/model/rwfolder.go | 30 +++++++++++++++------------- lib/model/rwfolder_test.go | 8 ++++---- 4 files changed, 41 insertions(+), 55 deletions(-) diff --git a/lib/model/folder.go b/lib/model/folder.go index 49e20b87..8db0e1d1 100644 --- a/lib/model/folder.go +++ b/lib/model/folder.go @@ -11,10 +11,10 @@ import "time" type folder struct { stateTracker - scan folderScanner - model *Model - stop chan struct{} - initialScanCompleted chan struct{} + scan folderScanner + model *Model + stop chan struct{} + initialScanFinished chan struct{} } func (f *folder) IndexUpdated() { @@ -25,7 +25,7 @@ func (f *folder) DelayScan(next time.Duration) { } func (f *folder) Scan(subdirs []string) error { - <-f.initialScanCompleted + <-f.initialScanFinished return f.scan.Scan(subdirs) } func (f *folder) Stop() { @@ -38,12 +38,7 @@ func (f *folder) Jobs() ([]string, []string) { func (f *folder) BringToFront(string) {} -func (f *folder) scanSubdirsIfHealthy(subDirs []string) error { - if err := f.model.CheckFolderHealth(f.folderID); err != nil { - l.Infoln("Skipping folder", f.folderID, "scan due to folder error:", err) - return err - } - l.Debugln(f, "Scanning subdirectories") +func (f *folder) scanSubdirs(subDirs []string) error { if err := f.model.internalScanFolderSubdirs(f.folderID, subDirs); err != nil { // Potentially sets the error twice, once in the scanner just // by doing a check, and once here, if the error returned is diff --git a/lib/model/rofolder.go b/lib/model/rofolder.go index 2cbb9938..537595a3 100644 --- a/lib/model/rofolder.go +++ b/lib/model/rofolder.go @@ -26,11 +26,11 @@ type sendOnlyFolder struct { func newSendOnlyFolder(model *Model, cfg config.FolderConfiguration, _ versioner.Versioner, _ *fs.MtimeFS) service { return &sendOnlyFolder{ folder: folder{ - stateTracker: newStateTracker(cfg.ID), - scan: newFolderScanner(cfg), - stop: make(chan struct{}), - model: model, - initialScanCompleted: make(chan struct{}), + stateTracker: newStateTracker(cfg.ID), + scan: newFolderScanner(cfg), + stop: make(chan struct{}), + model: model, + initialScanFinished: make(chan struct{}), }, FolderConfiguration: cfg, } @@ -50,29 +50,18 @@ func (f *sendOnlyFolder) Serve() { return case <-f.scan.timer.C: - if err := f.model.CheckFolderHealth(f.folderID); err != nil { - l.Infoln("Skipping scan of", f.Description(), "due to folder error:", err) - f.scan.Reschedule() - continue - } - - l.Debugln(f, "rescan") - - if err := f.model.internalScanFolderSubdirs(f.folderID, nil); err != nil { - // Potentially sets the error twice, once in the scanner just - // by doing a check, and once here, if the error returned is - // the same one as returned by CheckFolderHealth, though - // duplicate set is handled by setError. - f.setError(err) - f.scan.Reschedule() - continue - } + l.Debugln(f, "Scanning subdirectories") + err := f.scanSubdirs(nil) select { - case <-f.initialScanCompleted: + case <-f.initialScanFinished: default: - l.Infoln("Completed initial scan (ro) of", f.Description()) - close(f.initialScanCompleted) + status := "Completed" + if err != nil { + status = "Failed" + } + l.Infoln(status, "initial scan (ro) of", f.Description()) + close(f.initialScanFinished) } if f.scan.HasNoInterval() { @@ -82,7 +71,7 @@ func (f *sendOnlyFolder) Serve() { f.scan.Reschedule() case req := <-f.scan.now: - req.err <- f.scanSubdirsIfHealthy(req.subdirs) + req.err <- f.scanSubdirs(req.subdirs) case next := <-f.scan.delay: f.scan.timer.Reset(next) diff --git a/lib/model/rwfolder.go b/lib/model/rwfolder.go index 31419f7f..5df9bae1 100644 --- a/lib/model/rwfolder.go +++ b/lib/model/rwfolder.go @@ -101,11 +101,11 @@ type sendReceiveFolder struct { func newSendReceiveFolder(model *Model, cfg config.FolderConfiguration, ver versioner.Versioner, mtimeFS *fs.MtimeFS) service { f := &sendReceiveFolder{ folder: folder{ - stateTracker: newStateTracker(cfg.ID), - scan: newFolderScanner(cfg), - stop: make(chan struct{}), - model: model, - initialScanCompleted: make(chan struct{}), + stateTracker: newStateTracker(cfg.ID), + scan: newFolderScanner(cfg), + stop: make(chan struct{}), + model: model, + initialScanFinished: make(chan struct{}), }, FolderConfiguration: cfg, @@ -181,7 +181,7 @@ func (f *sendReceiveFolder) Serve() { case <-f.pullTimer.C: select { - case <-f.initialScanCompleted: + case <-f.initialScanFinished: default: // We don't start pulling files until a scan has been completed. l.Debugln(f, "skip (initial)") @@ -275,20 +275,22 @@ func (f *sendReceiveFolder) Serve() { // this is the easiest way to make sure we are not doing both at the // same time. case <-f.scan.timer.C: - err := f.scanSubdirsIfHealthy(nil) + l.Debugln(f, "Scanning subdirectories") + err := f.scanSubdirs(nil) f.scan.Reschedule() - if err != nil { - continue - } select { - case <-f.initialScanCompleted: + case <-f.initialScanFinished: default: - l.Infoln("Completed initial scan (rw) of", f.Description()) - close(f.initialScanCompleted) + close(f.initialScanFinished) + status := "Completed" + if err != nil { + status = "Failed" + } + l.Infoln(status, "initial scan (rw) of", f.Description()) } case req := <-f.scan.now: - req.err <- f.scanSubdirsIfHealthy(req.subdirs) + req.err <- f.scanSubdirs(req.subdirs) case next := <-f.scan.delay: f.scan.timer.Reset(next) diff --git a/lib/model/rwfolder_test.go b/lib/model/rwfolder_test.go index 13a2fa7c..90830d17 100644 --- a/lib/model/rwfolder_test.go +++ b/lib/model/rwfolder_test.go @@ -80,9 +80,9 @@ func setUpModel(file protocol.FileInfo) *Model { func setUpSendReceiveFolder(model *Model) *sendReceiveFolder { f := &sendReceiveFolder{ folder: folder{ - stateTracker: newStateTracker("default"), - model: model, - initialScanCompleted: make(chan struct{}), + stateTracker: newStateTracker("default"), + model: model, + initialScanFinished: make(chan struct{}), }, mtimeFS: fs.NewMtimeFS(fs.DefaultFilesystem, db.NewNamespacedKV(model.db, "mtime")), @@ -93,7 +93,7 @@ func setUpSendReceiveFolder(model *Model) *sendReceiveFolder { } // Folders are never actually started, so no initial scan will be done - close(f.initialScanCompleted) + close(f.initialScanFinished) return f }