mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-09 14:50:56 +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
|
scanInterval time.Duration
|
||||||
scanTimer *time.Timer
|
scanTimer *time.Timer
|
||||||
scanNow chan rescanRequest
|
|
||||||
scanDelay chan time.Duration
|
scanDelay chan time.Duration
|
||||||
initialScanFinished chan struct{}
|
initialScanFinished chan struct{}
|
||||||
scanErrors []FileError
|
scanErrors []FileError
|
||||||
@ -58,6 +57,8 @@ type folder struct {
|
|||||||
|
|
||||||
pullScheduled chan struct{}
|
pullScheduled chan struct{}
|
||||||
|
|
||||||
|
doInSyncChan chan syncRequest
|
||||||
|
|
||||||
watchCancel context.CancelFunc
|
watchCancel context.CancelFunc
|
||||||
watchChan chan []string
|
watchChan chan []string
|
||||||
restartWatchChan chan struct{}
|
restartWatchChan chan struct{}
|
||||||
@ -67,8 +68,8 @@ type folder struct {
|
|||||||
puller puller
|
puller puller
|
||||||
}
|
}
|
||||||
|
|
||||||
type rescanRequest struct {
|
type syncRequest struct {
|
||||||
subdirs []string
|
fn func() error
|
||||||
err chan 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,
|
scanInterval: time.Duration(cfg.RescanIntervalS) * time.Second,
|
||||||
scanTimer: time.NewTimer(time.Millisecond), // The first scan should be done immediately.
|
scanTimer: time.NewTimer(time.Millisecond), // The first scan should be done immediately.
|
||||||
scanNow: make(chan rescanRequest),
|
|
||||||
scanDelay: make(chan time.Duration),
|
scanDelay: make(chan time.Duration),
|
||||||
initialScanFinished: make(chan struct{}),
|
initialScanFinished: make(chan struct{}),
|
||||||
scanErrorsMut: sync.NewMutex(),
|
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.
|
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() {},
|
watchCancel: func() {},
|
||||||
restartWatchChan: make(chan struct{}, 1),
|
restartWatchChan: make(chan struct{}, 1),
|
||||||
watchMut: sync.NewMutex(),
|
watchMut: sync.NewMutex(),
|
||||||
@ -172,9 +174,9 @@ func (f *folder) serve(ctx context.Context) {
|
|||||||
l.Debugln(f, "Scanning due to timer")
|
l.Debugln(f, "Scanning due to timer")
|
||||||
f.scanTimerFired()
|
f.scanTimerFired()
|
||||||
|
|
||||||
case req := <-f.scanNow:
|
case req := <-f.doInSyncChan:
|
||||||
l.Debugln(f, "Scanning due to request")
|
l.Debugln(f, "Running something due to request")
|
||||||
req.err <- f.scanSubdirs(req.subdirs)
|
req.err <- req.fn()
|
||||||
|
|
||||||
case next := <-f.scanDelay:
|
case next := <-f.scanDelay:
|
||||||
l.Debugln(f, "Delaying scan")
|
l.Debugln(f, "Delaying scan")
|
||||||
@ -224,13 +226,19 @@ func (f *folder) Jobs(_, _ int) ([]string, []string, int) {
|
|||||||
|
|
||||||
func (f *folder) Scan(subdirs []string) error {
|
func (f *folder) Scan(subdirs []string) error {
|
||||||
<-f.initialScanFinished
|
<-f.initialScanFinished
|
||||||
req := rescanRequest{
|
return f.doInSync(func() error { return f.scanSubdirs(subdirs) })
|
||||||
subdirs: subdirs,
|
}
|
||||||
err: make(chan error),
|
|
||||||
|
// 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 {
|
select {
|
||||||
case f.scanNow <- req:
|
case f.doInSyncChan <- req:
|
||||||
return <-req.err
|
return <-req.err
|
||||||
case <-f.ctx.Done():
|
case <-f.ctx.Done():
|
||||||
return f.ctx.Err()
|
return f.ctx.Err()
|
||||||
|
@ -64,6 +64,10 @@ func newReceiveOnlyFolder(model *model, fset *db.FileSet, ignores *ignore.Matche
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *receiveOnlyFolder) Revert() {
|
func (f *receiveOnlyFolder) Revert() {
|
||||||
|
f.doInSync(func() error { f.revert(); return nil })
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *receiveOnlyFolder) revert() {
|
||||||
l.Infof("Reverting folder %v", f.Description)
|
l.Infof("Reverting folder %v", f.Description)
|
||||||
|
|
||||||
f.setState(FolderScanning)
|
f.setState(FolderScanning)
|
||||||
|
@ -97,9 +97,15 @@ func (f *sendOnlyFolder) pull() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *sendOnlyFolder) Override() {
|
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)
|
l.Infof("Overriding global state on folder %v", f.Description)
|
||||||
|
|
||||||
f.setState(FolderScanning)
|
f.setState(FolderScanning)
|
||||||
|
defer f.setState(FolderIdle)
|
||||||
|
|
||||||
batch := make([]protocol.FileInfo, 0, maxBatchSizeFiles)
|
batch := make([]protocol.FileInfo, 0, maxBatchSizeFiles)
|
||||||
batchSizeBytes := 0
|
batchSizeBytes := 0
|
||||||
snap := f.fset.Snapshot()
|
snap := f.fset.Snapshot()
|
||||||
@ -134,5 +140,4 @@ func (f *sendOnlyFolder) Override() {
|
|||||||
if len(batch) > 0 {
|
if len(batch) > 0 {
|
||||||
f.updateLocalsFromScanning(batch)
|
f.updateLocalsFromScanning(batch)
|
||||||
}
|
}
|
||||||
f.setState(FolderIdle)
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user