Browse Source

lib/model: Return empty summary on paused folders (ref #6272) (#6326)

Simon Frei 5 years ago
parent
commit
ce27780a4c
2 changed files with 32 additions and 13 deletions
  1. 19 13
      lib/model/folder_summary.go
  2. 13 0
      lib/model/model_test.go

+ 19 - 13
lib/model/folder_summary.go

@@ -15,6 +15,7 @@ import (
 	"github.com/thejerf/suture"
 
 	"github.com/syncthing/syncthing/lib/config"
+	"github.com/syncthing/syncthing/lib/db"
 	"github.com/syncthing/syncthing/lib/events"
 	"github.com/syncthing/syncthing/lib/protocol"
 	"github.com/syncthing/syncthing/lib/sync"
@@ -77,28 +78,37 @@ func (c *folderSummaryService) String() string {
 func (c *folderSummaryService) Summary(folder string) (map[string]interface{}, error) {
 	var res = make(map[string]interface{})
 
-	snap, err := c.model.DBSnapshot(folder)
-	if err != nil {
-		return nil, err
-	}
-
+	var local, global, need, ro db.Counts
+	var ourSeq, remoteSeq int64
 	errors, err := c.model.FolderErrors(folder)
+	if err == nil {
+		var snap *db.Snapshot
+		if snap, err = c.model.DBSnapshot(folder); err == nil {
+			global = snap.GlobalSize()
+			local = snap.LocalSize()
+			need = snap.NeedSize()
+			ro = snap.ReceiveOnlyChangedSize()
+			ourSeq = snap.Sequence(protocol.LocalDeviceID)
+			remoteSeq = snap.Sequence(protocol.GlobalDeviceID)
+			snap.Release()
+		}
+	}
+	// For API backwards compatibility (SyncTrayzor needs it) an empty folder
+	// summary is returned for not running folders, an error might actually be
+	// more appropriate
 	if err != nil && err != ErrFolderPaused && err != errFolderNotRunning {
-		// Stats from the db can still be obtained if the folder is just paused/being started
 		return nil, err
 	}
+
 	res["errors"] = len(errors)
 	res["pullErrors"] = len(errors) // deprecated
 
 	res["invalid"] = "" // Deprecated, retains external API for now
 
-	global := snap.GlobalSize()
 	res["globalFiles"], res["globalDirectories"], res["globalSymlinks"], res["globalDeleted"], res["globalBytes"], res["globalTotalItems"] = global.Files, global.Directories, global.Symlinks, global.Deleted, global.Bytes, global.TotalItems()
 
-	local := snap.LocalSize()
 	res["localFiles"], res["localDirectories"], res["localSymlinks"], res["localDeleted"], res["localBytes"], res["localTotalItems"] = local.Files, local.Directories, local.Symlinks, local.Deleted, local.Bytes, local.TotalItems()
 
-	need := snap.NeedSize()
 	need.Bytes -= c.model.FolderProgressBytesCompleted(folder)
 	// This may happen if we are in progress of pulling files that were
 	// deleted globally after the pull started.
@@ -116,7 +126,6 @@ func (c *folderSummaryService) Summary(folder string) (map[string]interface{}, e
 	if ok && fcfg.Type == config.FolderTypeReceiveOnly {
 		// Add statistics for things that have changed locally in a receive
 		// only folder.
-		ro := snap.ReceiveOnlyChangedSize()
 		res["receiveOnlyChangedFiles"] = ro.Files
 		res["receiveOnlyChangedDirectories"] = ro.Directories
 		res["receiveOnlyChangedSymlinks"] = ro.Symlinks
@@ -132,9 +141,6 @@ func (c *folderSummaryService) Summary(folder string) (map[string]interface{}, e
 		res["error"] = err.Error()
 	}
 
-	ourSeq := snap.Sequence(protocol.LocalDeviceID)
-	remoteSeq := snap.Sequence(protocol.GlobalDeviceID)
-
 	res["version"] = ourSeq + remoteSeq  // legacy
 	res["sequence"] = ourSeq + remoteSeq // new name
 

+ 13 - 0
lib/model/model_test.go

@@ -3480,6 +3480,19 @@ func TestNewLimitedRequestResponse(t *testing.T) {
 	}
 }
 
+func TestSummaryPausedNoError(t *testing.T) {
+	wcfg, fcfg := tmpDefaultWrapper()
+	fcfg.Paused = true
+	wcfg.SetFolder(fcfg)
+	m := setupModel(wcfg)
+	defer cleanupModel(m)
+
+	fss := NewFolderSummaryService(wcfg, m, myID, events.NoopLogger)
+	if _, err := fss.Summary(fcfg.ID); err != nil {
+		t.Error("Expected no error getting a summary for a paused folder:", err)
+	}
+}
+
 func TestFolderAPIErrors(t *testing.T) {
 	wcfg, fcfg := tmpDefaultWrapper()
 	fcfg.Paused = true