Handle folder moves in Scanner

This commit is contained in:
Deluan 2020-01-18 11:00:20 -05:00
parent 8ae4fdd5b2
commit 58a080eded
2 changed files with 32 additions and 13 deletions

View File

@ -9,22 +9,28 @@ import (
"github.com/cloudsonic/sonic-server/log" "github.com/cloudsonic/sonic-server/log"
) )
type dirInfo struct {
mdate time.Time
maybe bool
}
type dirInfoMap map[string]dirInfo
type ChangeDetector struct { type ChangeDetector struct {
rootFolder string rootFolder string
dirMap map[string]time.Time dirMap dirInfoMap
} }
func NewChangeDetector(rootFolder string) *ChangeDetector { func NewChangeDetector(rootFolder string) *ChangeDetector {
return &ChangeDetector{ return &ChangeDetector{
rootFolder: rootFolder, rootFolder: rootFolder,
dirMap: map[string]time.Time{}, dirMap: dirInfoMap{},
} }
} }
func (s *ChangeDetector) Scan(lastModifiedSince time.Time) (changed []string, deleted []string, err error) { func (s *ChangeDetector) Scan(lastModifiedSince time.Time) (changed []string, deleted []string, err error) {
start := time.Now() start := time.Now()
newMap := make(map[string]time.Time) newMap := make(dirInfoMap)
err = s.loadMap(s.rootFolder, newMap) err = s.loadMap(newMap, s.rootFolder, lastModifiedSince, false)
if err != nil { if err != nil {
return return
} }
@ -67,20 +73,21 @@ func (s *ChangeDetector) loadDir(dirPath string) (children []string, lastUpdated
return return
} }
func (s *ChangeDetector) loadMap(rootPath string, dirMap map[string]time.Time) error { func (s *ChangeDetector) loadMap(dirMap dirInfoMap, rootPath string, since time.Time, maybe bool) error {
children, lastUpdated, err := s.loadDir(rootPath) children, lastUpdated, err := s.loadDir(rootPath)
if err != nil { if err != nil {
return err return err
} }
maybe = maybe || lastUpdated.After(since)
for _, c := range children { for _, c := range children {
err := s.loadMap(c, dirMap) err := s.loadMap(dirMap, c, since, maybe)
if err != nil { if err != nil {
return err return err
} }
} }
dir := s.getRelativePath(rootPath) dir := s.getRelativePath(rootPath)
dirMap[dir] = lastUpdated dirMap[dir] = dirInfo{mdate: lastUpdated, maybe: maybe}
return nil return nil
} }
@ -93,11 +100,16 @@ func (s *ChangeDetector) getRelativePath(subfolder string) string {
return dir return dir
} }
func (s *ChangeDetector) checkForUpdates(lastModifiedSince time.Time, newMap map[string]time.Time) (changed []string, deleted []string, err error) { func (s *ChangeDetector) checkForUpdates(lastModifiedSince time.Time, newMap dirInfoMap) (changed []string, deleted []string, err error) {
for dir, lastUpdated := range newMap { for dir, newEntry := range newMap {
oldLastUpdated, ok := s.dirMap[dir] lastUpdated := newEntry.mdate
if !ok { oldLastUpdated := lastModifiedSince
oldLastUpdated = lastModifiedSince if oldEntry, ok := s.dirMap[dir]; ok {
oldLastUpdated = oldEntry.mdate
} else {
if newEntry.maybe {
oldLastUpdated = time.Time{}
}
} }
if lastUpdated.After(oldLastUpdated) { if lastUpdated.After(oldLastUpdated) {
changed = append(changed, dir) changed = append(changed, dir)

View File

@ -33,6 +33,7 @@ var _ = Describe("ChangeDetector", func() {
Expect(changed).To(ConsistOf(".")) Expect(changed).To(ConsistOf("."))
// Add one subfolder // Add one subfolder
lastModifiedSince = time.Now()
err = os.MkdirAll(path.Join(testFolder, "a"), 0700) err = os.MkdirAll(path.Join(testFolder, "a"), 0700)
if err != nil { if err != nil {
panic(err) panic(err)
@ -43,6 +44,7 @@ var _ = Describe("ChangeDetector", func() {
Expect(changed).To(ConsistOf(".", "/a")) Expect(changed).To(ConsistOf(".", "/a"))
// Add more subfolders // Add more subfolders
lastModifiedSince = time.Now()
err = os.MkdirAll(path.Join(testFolder, "a", "b", "c"), 0700) err = os.MkdirAll(path.Join(testFolder, "a", "b", "c"), 0700)
if err != nil { if err != nil {
panic(err) panic(err)
@ -53,12 +55,14 @@ var _ = Describe("ChangeDetector", func() {
Expect(changed).To(ConsistOf("/a", "/a/b", "/a/b/c")) Expect(changed).To(ConsistOf("/a", "/a/b", "/a/b/c"))
// Scan with no changes // Scan with no changes
lastModifiedSince = time.Now()
changed, deleted, err = scanner.Scan(lastModifiedSince) changed, deleted, err = scanner.Scan(lastModifiedSince)
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(deleted).To(BeEmpty()) Expect(deleted).To(BeEmpty())
Expect(changed).To(BeEmpty()) Expect(changed).To(BeEmpty())
// New file in subfolder // New file in subfolder
lastModifiedSince = time.Now()
_, err = os.Create(path.Join(testFolder, "a", "b", "empty.txt")) _, err = os.Create(path.Join(testFolder, "a", "b", "empty.txt"))
if err != nil { if err != nil {
panic(err) panic(err)
@ -69,6 +73,7 @@ var _ = Describe("ChangeDetector", func() {
Expect(changed).To(ConsistOf("/a/b")) Expect(changed).To(ConsistOf("/a/b"))
// Delete file in subfolder // Delete file in subfolder
lastModifiedSince = time.Now()
err = os.Remove(path.Join(testFolder, "a", "b", "empty.txt")) err = os.Remove(path.Join(testFolder, "a", "b", "empty.txt"))
if err != nil { if err != nil {
panic(err) panic(err)
@ -79,6 +84,7 @@ var _ = Describe("ChangeDetector", func() {
Expect(changed).To(ConsistOf("/a/b")) Expect(changed).To(ConsistOf("/a/b"))
// Delete subfolder // Delete subfolder
lastModifiedSince = time.Now()
err = os.Remove(path.Join(testFolder, "a", "b", "c")) err = os.Remove(path.Join(testFolder, "a", "b", "c"))
if err != nil { if err != nil {
panic(err) panic(err)
@ -97,7 +103,8 @@ var _ = Describe("ChangeDetector", func() {
Expect(changed).To(BeEmpty()) Expect(changed).To(BeEmpty())
Expect(changed).To(BeEmpty()) Expect(changed).To(BeEmpty())
_, err = os.Create(path.Join(testFolder, "a", "b", "new.txt")) f, err := os.Create(path.Join(testFolder, "a", "b", "new.txt"))
f.Close()
changed, deleted, err = newScanner.Scan(lastModifiedSince) changed, deleted, err = newScanner.Scan(lastModifiedSince)
Expect(err).To(BeNil()) Expect(err).To(BeNil())
Expect(deleted).To(BeEmpty()) Expect(deleted).To(BeEmpty())