Pārlūkot izejas kodu

lib/model: Refactor folderScanner into folder

The functionality was anyway mostly implemented there and not isolated
in the folderScanner type. The attempt to refactor it out in the other
direction wouldn't work given that the event loop and stuff is on
`folder`.
Jakob Borg 7 gadi atpakaļ
vecāks
revīzija
370a3549e7
2 mainītis faili ar 43 papildinājumiem un 70 dzēšanām
  1. 43 11
      lib/model/folder.go
  2. 0 59
      lib/model/folderscanner.go

+ 43 - 11
lib/model/folder.go

@@ -9,6 +9,7 @@ package model
 import (
 	"context"
 	"errors"
+	"math/rand"
 	"time"
 
 	"github.com/syncthing/syncthing/lib/config"
@@ -18,7 +19,7 @@ import (
 	"github.com/syncthing/syncthing/lib/watchaggregator"
 )
 
-var errWatchNotStarted error = errors.New("not started")
+var errWatchNotStarted = errors.New("not started")
 
 type folder struct {
 	stateTracker
@@ -29,7 +30,10 @@ type folder struct {
 	ctx     context.Context
 	cancel  context.CancelFunc
 
-	scan                folderScanner
+	scanInterval        time.Duration
+	scanTimer           *time.Timer
+	scanNow             chan rescanRequest
+	scanDelay           chan time.Duration
 	initialScanFinished chan struct{}
 
 	pullScheduled chan struct{}
@@ -43,6 +47,11 @@ type folder struct {
 	puller puller
 }
 
+type rescanRequest struct {
+	subdirs []string
+	err     chan error
+}
+
 type puller interface {
 	pull() bool // true when successfull and should not be retried
 }
@@ -59,7 +68,10 @@ func newFolder(model *Model, cfg config.FolderConfiguration) folder {
 		ctx:     ctx,
 		cancel:  cancel,
 
-		scan:                newFolderScanner(cfg),
+		scanInterval:        time.Duration(cfg.RescanIntervalS) * time.Second,
+		scanTimer:           time.NewTimer(time.Millisecond), // The first scan should be done immediately.
+		scanNow:             make(chan rescanRequest),
+		scanDelay:           make(chan time.Duration),
 		initialScanFinished: make(chan struct{}),
 
 		pullScheduled: make(chan struct{}, 1), // This needs to be 1-buffered so that we queue a pull if we're busy when it comes.
@@ -75,7 +87,7 @@ func (f *folder) Serve() {
 	defer l.Debugln(f, "exiting")
 
 	defer func() {
-		f.scan.timer.Stop()
+		f.scanTimer.Stop()
 		f.setState(FolderIdle)
 	}()
 
@@ -133,15 +145,15 @@ func (f *folder) Serve() {
 		// The reason for running the scanner from within the puller is that
 		// this is the easiest way to make sure we are not doing both at the
 		// same time.
-		case <-f.scan.timer.C:
+		case <-f.scanTimer.C:
 			l.Debugln(f, "Scanning subdirectories")
 			f.scanTimerFired()
 
-		case req := <-f.scan.now:
+		case req := <-f.scanNow:
 			req.err <- f.scanSubdirs(req.subdirs)
 
-		case next := <-f.scan.delay:
-			f.scan.timer.Reset(next)
+		case next := <-f.scanDelay:
+			f.scanTimer.Reset(next)
 
 		case fsEvents := <-f.watchChan:
 			l.Debugln(f, "filesystem notification rescan")
@@ -156,7 +168,7 @@ func (f *folder) Serve() {
 func (f *folder) BringToFront(string) {}
 
 func (f *folder) DelayScan(next time.Duration) {
-	f.scan.Delay(next)
+	f.Delay(next)
 }
 
 func (f *folder) IgnoresUpdated() {
@@ -182,7 +194,27 @@ func (f *folder) Jobs() ([]string, []string) {
 
 func (f *folder) Scan(subdirs []string) error {
 	<-f.initialScanFinished
-	return f.scan.Scan(subdirs)
+	req := rescanRequest{
+		subdirs: subdirs,
+		err:     make(chan error),
+	}
+	f.scanNow <- req
+	return <-req.err
+}
+
+func (f *folder) Reschedule() {
+	if f.scanInterval == 0 {
+		return
+	}
+	// Sleep a random time between 3/4 and 5/4 of the configured interval.
+	sleepNanos := (f.scanInterval.Nanoseconds()*3 + rand.Int63n(2*f.scanInterval.Nanoseconds())) / 4
+	interval := time.Duration(sleepNanos) * time.Nanosecond
+	l.Debugln(f, "next rescan in", interval)
+	f.scanTimer.Reset(interval)
+}
+
+func (f *folder) Delay(next time.Duration) {
+	f.scanDelay <- next
 }
 
 func (f *folder) Stop() {
@@ -242,7 +274,7 @@ func (f *folder) scanTimerFired() {
 		close(f.initialScanFinished)
 	}
 
-	f.scan.Reschedule()
+	f.Reschedule()
 }
 
 func (f *folder) WatchError() error {

+ 0 - 59
lib/model/folderscanner.go

@@ -1,59 +0,0 @@
-// Copyright (C) 2016 The Syncthing Authors.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at https://mozilla.org/MPL/2.0/.
-
-package model
-
-import (
-	"github.com/syncthing/syncthing/lib/config"
-	"math/rand"
-	"time"
-)
-
-type rescanRequest struct {
-	subdirs []string
-	err     chan error
-}
-
-// bundle all folder scan activity
-type folderScanner struct {
-	interval time.Duration
-	timer    *time.Timer
-	now      chan rescanRequest
-	delay    chan time.Duration
-}
-
-func newFolderScanner(config config.FolderConfiguration) folderScanner {
-	return folderScanner{
-		interval: time.Duration(config.RescanIntervalS) * time.Second,
-		timer:    time.NewTimer(time.Millisecond), // The first scan should be done immediately.
-		now:      make(chan rescanRequest),
-		delay:    make(chan time.Duration),
-	}
-}
-
-func (f *folderScanner) Reschedule() {
-	if f.interval == 0 {
-		return
-	}
-	// Sleep a random time between 3/4 and 5/4 of the configured interval.
-	sleepNanos := (f.interval.Nanoseconds()*3 + rand.Int63n(2*f.interval.Nanoseconds())) / 4
-	interval := time.Duration(sleepNanos) * time.Nanosecond
-	l.Debugln(f, "next rescan in", interval)
-	f.timer.Reset(interval)
-}
-
-func (f *folderScanner) Scan(subdirs []string) error {
-	req := rescanRequest{
-		subdirs: subdirs,
-		err:     make(chan error),
-	}
-	f.now <- req
-	return <-req.err
-}
-
-func (f *folderScanner) Delay(next time.Duration) {
-	f.delay <- next
-}