mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-08 22:31:04 +00:00
lib/model: Do Revert/Override synchronously (#6460)
This commit is contained in:
parent
c7cf3ef899
commit
79a758be3c
@ -50,7 +50,6 @@ type folder struct {
|
||||
|
||||
scanInterval time.Duration
|
||||
scanTimer *time.Timer
|
||||
scanNow chan rescanRequest
|
||||
scanDelay chan time.Duration
|
||||
initialScanFinished chan struct{}
|
||||
scanErrors []FileError
|
||||
@ -58,6 +57,8 @@ type folder struct {
|
||||
|
||||
pullScheduled chan struct{}
|
||||
|
||||
doInSyncChan chan syncRequest
|
||||
|
||||
watchCancel context.CancelFunc
|
||||
watchChan chan []string
|
||||
restartWatchChan chan struct{}
|
||||
@ -67,8 +68,8 @@ type folder struct {
|
||||
puller puller
|
||||
}
|
||||
|
||||
type rescanRequest struct {
|
||||
subdirs []string
|
||||
type syncRequest struct {
|
||||
fn func() error
|
||||
err chan error
|
||||
}
|
||||
|
||||
@ -90,13 +91,14 @@ func newFolder(model *model, fset *db.FileSet, ignores *ignore.Matcher, cfg conf
|
||||
|
||||
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{}),
|
||||
scanErrorsMut: sync.NewMutex(),
|
||||
|
||||
pullScheduled: make(chan struct{}, 1), // This needs to be 1-buffered so that we queue a pull if we're busy when it comes.
|
||||
|
||||
doInSyncChan: make(chan syncRequest),
|
||||
|
||||
watchCancel: func() {},
|
||||
restartWatchChan: make(chan struct{}, 1),
|
||||
watchMut: sync.NewMutex(),
|
||||
@ -172,9 +174,9 @@ func (f *folder) serve(ctx context.Context) {
|
||||
l.Debugln(f, "Scanning due to timer")
|
||||
f.scanTimerFired()
|
||||
|
||||
case req := <-f.scanNow:
|
||||
l.Debugln(f, "Scanning due to request")
|
||||
req.err <- f.scanSubdirs(req.subdirs)
|
||||
case req := <-f.doInSyncChan:
|
||||
l.Debugln(f, "Running something due to request")
|
||||
req.err <- req.fn()
|
||||
|
||||
case next := <-f.scanDelay:
|
||||
l.Debugln(f, "Delaying scan")
|
||||
@ -224,13 +226,19 @@ func (f *folder) Jobs(_, _ int) ([]string, []string, int) {
|
||||
|
||||
func (f *folder) Scan(subdirs []string) error {
|
||||
<-f.initialScanFinished
|
||||
req := rescanRequest{
|
||||
subdirs: subdirs,
|
||||
err: make(chan error),
|
||||
return f.doInSync(func() error { return f.scanSubdirs(subdirs) })
|
||||
}
|
||||
|
||||
// doInSync allows to run functions synchronously in folder.serve from exported,
|
||||
// asynchronously called methods.
|
||||
func (f *folder) doInSync(fn func() error) error {
|
||||
req := syncRequest{
|
||||
fn: fn,
|
||||
err: make(chan error, 1),
|
||||
}
|
||||
|
||||
select {
|
||||
case f.scanNow <- req:
|
||||
case f.doInSyncChan <- req:
|
||||
return <-req.err
|
||||
case <-f.ctx.Done():
|
||||
return f.ctx.Err()
|
||||
|
@ -64,6 +64,10 @@ func newReceiveOnlyFolder(model *model, fset *db.FileSet, ignores *ignore.Matche
|
||||
}
|
||||
|
||||
func (f *receiveOnlyFolder) Revert() {
|
||||
f.doInSync(func() error { f.revert(); return nil })
|
||||
}
|
||||
|
||||
func (f *receiveOnlyFolder) revert() {
|
||||
l.Infof("Reverting folder %v", f.Description)
|
||||
|
||||
f.setState(FolderScanning)
|
||||
|
@ -97,9 +97,15 @@ func (f *sendOnlyFolder) pull() bool {
|
||||
}
|
||||
|
||||
func (f *sendOnlyFolder) Override() {
|
||||
f.doInSync(func() error { f.override(); return nil })
|
||||
}
|
||||
|
||||
func (f *sendOnlyFolder) override() {
|
||||
l.Infof("Overriding global state on folder %v", f.Description)
|
||||
|
||||
f.setState(FolderScanning)
|
||||
defer f.setState(FolderIdle)
|
||||
|
||||
batch := make([]protocol.FileInfo, 0, maxBatchSizeFiles)
|
||||
batchSizeBytes := 0
|
||||
snap := f.fset.Snapshot()
|
||||
@ -134,5 +140,4 @@ func (f *sendOnlyFolder) Override() {
|
||||
if len(batch) > 0 {
|
||||
f.updateLocalsFromScanning(batch)
|
||||
}
|
||||
f.setState(FolderIdle)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user