Browse Source

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.
Jakob Borg 7 years ago
parent
commit
119335930c
3 changed files with 52 additions and 37 deletions
  1. 3 0
      lib/model/folder.go
  2. 40 0
      lib/model/folder_sendonly.go
  3. 9 37
      lib/model/model.go

+ 3 - 0
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)
 }

+ 40 - 0
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)
+}

+ 9 - 37
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.