From 119335930c9257ef59aa534f7e73855d5ab86b02 Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Mon, 21 May 2018 08:56:24 +0200 Subject: [PATCH] lib/model: Refactor override implementation into sendOnlyFolder I'm trying to slowly clean this up a bit, and moving functionality out into the folder types and having those methods not reach into model is part of it. That can mean takign some odd arguments in the meantime, some of those should probably become interfaces or properties on folder in the long term. --- lib/model/folder.go | 3 +++ lib/model/folder_sendonly.go | 40 +++++++++++++++++++++++++++++++ lib/model/model.go | 46 +++++++----------------------------- 3 files changed, 52 insertions(+), 37 deletions(-) diff --git a/lib/model/folder.go b/lib/model/folder.go index c90b9e3b..a0a7bb75 100644 --- a/lib/model/folder.go +++ b/lib/model/folder.go @@ -13,6 +13,7 @@ import ( "time" "github.com/syncthing/syncthing/lib/config" + "github.com/syncthing/syncthing/lib/db" "github.com/syncthing/syncthing/lib/ignore" "github.com/syncthing/syncthing/lib/protocol" "github.com/syncthing/syncthing/lib/sync" @@ -167,6 +168,8 @@ func (f *folder) Serve() { func (f *folder) BringToFront(string) {} +func (f *folder) Override(fs *db.FileSet, updateFn func([]protocol.FileInfo)) {} + func (f *folder) DelayScan(next time.Duration) { f.Delay(next) } diff --git a/lib/model/folder_sendonly.go b/lib/model/folder_sendonly.go index 4a5f9111..448ad09a 100644 --- a/lib/model/folder_sendonly.go +++ b/lib/model/folder_sendonly.go @@ -100,3 +100,43 @@ func (f *sendOnlyFolder) pull() bool { return true } + +func (f *sendOnlyFolder) Override(fs *db.FileSet, updateFn func([]protocol.FileInfo)) { + f.setState(FolderScanning) + batch := make([]protocol.FileInfo, 0, maxBatchSizeFiles) + batchSizeBytes := 0 + fs.WithNeed(protocol.LocalDeviceID, func(fi db.FileIntf) bool { + need := fi.(protocol.FileInfo) + if len(batch) == maxBatchSizeFiles || batchSizeBytes > maxBatchSizeBytes { + updateFn(batch) + batch = batch[:0] + batchSizeBytes = 0 + } + + have, ok := fs.Get(protocol.LocalDeviceID, need.Name) + // Don't override files that are in a bad state (ignored, + // unsupported, must rescan, ...). + if ok && have.IsInvalid() { + return true + } + if !ok || have.Name != need.Name { + // We are missing the file + need.Deleted = true + need.Blocks = nil + need.Version = need.Version.Update(f.shortID) + need.Size = 0 + } else { + // We have the file, replace with our version + have.Version = have.Version.Merge(need.Version).Update(f.shortID) + need = have + } + need.Sequence = 0 + batch = append(batch, need) + batchSizeBytes += need.ProtoSize() + return true + }) + if len(batch) > 0 { + updateFn(batch) + } + f.setState(FolderIdle) +} diff --git a/lib/model/model.go b/lib/model/model.go index 15861347..70f6c511 100644 --- a/lib/model/model.go +++ b/lib/model/model.go @@ -56,6 +56,7 @@ const ( type service interface { BringToFront(string) + Override(*db.FileSet, func([]protocol.FileInfo)) DelayScan(d time.Duration) IgnoresUpdated() // ignore matcher was updated notification SchedulePull() // something relevant changed, we should try a pull @@ -2300,50 +2301,21 @@ func (m *Model) WatchError(folder string) error { } func (m *Model) Override(folder string) { + // Grab the runner and the file set. + m.fmut.RLock() - fs, ok := m.folderFiles[folder] - runner := m.folderRunners[folder] + fs, fsOK := m.folderFiles[folder] + runner, runnerOK := m.folderRunners[folder] m.fmut.RUnlock() - if !ok { + if !fsOK || !runnerOK { return } - runner.setState(FolderScanning) - batch := make([]protocol.FileInfo, 0, maxBatchSizeFiles) - batchSizeBytes := 0 - fs.WithNeed(protocol.LocalDeviceID, func(fi db.FileIntf) bool { - need := fi.(protocol.FileInfo) - if len(batch) == maxBatchSizeFiles || batchSizeBytes > maxBatchSizeBytes { - m.updateLocalsFromScanning(folder, batch) - batch = batch[:0] - batchSizeBytes = 0 - } + // Run the override, taking updates as if they came from scanning. - have, ok := fs.Get(protocol.LocalDeviceID, need.Name) - // Don't override invalid (e.g. ignored) files - if ok && have.Invalid { - return true - } - if !ok || have.Name != need.Name { - // We are missing the file - need.Deleted = true - need.Blocks = nil - need.Version = need.Version.Update(m.shortID) - need.Size = 0 - } else { - // We have the file, replace with our version - have.Version = have.Version.Merge(need.Version).Update(m.shortID) - need = have - } - need.Sequence = 0 - batch = append(batch, need) - batchSizeBytes += need.ProtoSize() - return true + runner.Override(fs, func(files []protocol.FileInfo) { + m.updateLocalsFromScanning(folder, files) }) - if len(batch) > 0 { - m.updateLocalsFromScanning(folder, batch) - } - runner.setState(FolderIdle) } // CurrentSequence returns the change version for the given folder.