Perform initial scan asynchronously (fixes #509, fixes #464)

This commit is contained in:
Jakob Borg 2014-09-30 17:34:31 +02:00
parent 3eb000fa60
commit 2091e12e82
4 changed files with 18 additions and 48 deletions

View File

@ -522,13 +522,6 @@ nextFolder:
}
}
// Walk the folder and update the local model before establishing any
// connections to other devices.
m.CleanFolders()
l.Infoln("Performing initial folder scan")
m.ScanFolders()
// Remove all .idx* files that don't belong to an active folder.
validIndexes := make(map[string]bool)

View File

@ -171,10 +171,9 @@ func (m *Model) StartFolderRW(folder string) {
// pull in any external changes.
func (m *Model) StartFolderRO(folder string) {
intv := time.Duration(m.folderCfgs[folder].RescanIntervalS) * time.Second
initialScanCompleted := false
go func() {
for {
time.Sleep(intv)
if debug {
l.Debugln(m, "rescan", folder)
}
@ -185,6 +184,11 @@ func (m *Model) StartFolderRO(folder string) {
return
}
m.setState(folder, FolderIdle)
if !initialScanCompleted {
l.Infoln("Completed initial scan (ro) of folder", folder)
initialScanCompleted = true
}
time.Sleep(intv)
}
}()
}
@ -959,29 +963,6 @@ func (m *Model) ScanFolders() {
wg.Wait()
}
func (m *Model) CleanFolders() {
m.fmut.RLock()
var dirs = make([]string, 0, len(m.folderCfgs))
for _, cfg := range m.folderCfgs {
dirs = append(dirs, cfg.Path)
}
m.fmut.RUnlock()
var wg sync.WaitGroup
wg.Add(len(dirs))
for _, dir := range dirs {
w := &scanner.Walker{
Dir: dir,
TempNamer: defTempNamer,
}
go func() {
w.CleanTempFiles()
wg.Done()
}()
}
wg.Wait()
}
func (m *Model) ScanFolder(folder string) error {
return m.ScanFolderSub(folder, "")
}

View File

@ -70,7 +70,7 @@ func (p *Puller) Serve() {
p.stop = make(chan struct{})
pullTimer := time.NewTimer(checkPullIntv)
scanTimer := time.NewTimer(p.scanIntv)
scanTimer := time.NewTimer(time.Millisecond) // The first scan should be done immediately.
defer func() {
pullTimer.Stop()
@ -84,6 +84,9 @@ func (p *Puller) Serve() {
// Clean out old temporaries before we start pulling
p.clean()
// We don't start pulling files until a scan has been completed.
initialScanCompleted := false
loop:
for {
select {
@ -96,6 +99,10 @@ loop:
// repeatable benchmark of how long it takes to sync a change from
// device A to device B, so we have something to work against.
case <-pullTimer.C:
if !initialScanCompleted {
continue
}
// RemoteLocalVersion() is a fast call, doesn't touch the database.
curVer := p.model.RemoteLocalVersion(p.folder)
if curVer == prevVer {
@ -163,6 +170,10 @@ loop:
}
p.model.setState(p.folder, FolderIdle)
scanTimer.Reset(p.scanIntv)
if !initialScanCompleted {
l.Infoln("Completed initial scan (rw) of folder", p.folder)
initialScanCompleted = true
}
}
}
}

View File

@ -73,11 +73,6 @@ func (w *Walker) Walk() (chan protocol.FileInfo, error) {
return hashedFiles, nil
}
// CleanTempFiles removes all files that match the temporary filename pattern.
func (w *Walker) CleanTempFiles() {
filepath.Walk(w.Dir, w.cleanTempFile)
}
func (w *Walker) walkAndHashFiles(fchan chan protocol.FileInfo) filepath.WalkFunc {
return func(p string, info os.FileInfo, err error) error {
if err != nil {
@ -181,16 +176,6 @@ func (w *Walker) walkAndHashFiles(fchan chan protocol.FileInfo) filepath.WalkFun
}
}
func (w *Walker) cleanTempFile(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.Mode()&os.ModeType == 0 && w.TempNamer.IsTemporary(path) {
os.Remove(path)
}
return nil
}
func checkDir(dir string) error {
if info, err := os.Lstat(dir); err != nil {
return err