diff --git a/cmd/syncthing/gui.go b/cmd/syncthing/gui.go index b0f5ac4c..cbf2da76 100644 --- a/cmd/syncthing/gui.go +++ b/cmd/syncthing/gui.go @@ -648,7 +648,7 @@ func restPostBump(m *model.Model, w http.ResponseWriter, r *http.Request) { qs := r.URL.Query() folder := qs.Get("folder") file := qs.Get("file") - m.Bump(folder, file) + m.BringToFront(folder, file) restGetNeed(m, w, r) } diff --git a/internal/model/model.go b/internal/model/model.go index 4c3ed84a..c17bc366 100644 --- a/internal/model/model.go +++ b/internal/model/model.go @@ -80,7 +80,7 @@ type service interface { Serve() Stop() Jobs() ([]string, []string) // In progress, Queued - Bump(string) + BringToFront(string) } type Model struct { @@ -191,6 +191,7 @@ func (m *Model) StartFolderRW(folder string) { copiers: cfg.Copiers, pullers: cfg.Pullers, finishers: cfg.Finishers, + queue: newJobQueue(), } m.folderRunners[folder] = p m.fmut.Unlock() @@ -1390,13 +1391,13 @@ func (m *Model) availability(folder, file string) []protocol.DeviceID { } // Bump the given files priority in the job queue -func (m *Model) Bump(folder, file string) { +func (m *Model) BringToFront(folder, file string) { m.pmut.RLock() defer m.pmut.RUnlock() runner, ok := m.folderRunners[folder] if ok { - runner.Bump(file) + runner.BringToFront(file) } } diff --git a/internal/model/puller.go b/internal/model/puller.go index 5468a7ae..e1d063dd 100644 --- a/internal/model/puller.go +++ b/internal/model/puller.go @@ -78,7 +78,7 @@ type Puller struct { copiers int pullers int finishers int - queue *JobQueue + queue *jobQueue } // Serve will run scans and pulls. It will return when Stop()ed or on a @@ -90,7 +90,6 @@ func (p *Puller) Serve() { } p.stop = make(chan struct{}) - p.queue = NewJobQueue() pullTimer := time.NewTimer(checkPullIntv) scanTimer := time.NewTimer(time.Millisecond) // The first scan should be done immediately. @@ -872,31 +871,14 @@ func (p *Puller) finisherRoutine(in <-chan *sharedPullerState) { } // Moves the given filename to the front of the job queue -func (p *Puller) Bump(filename string) { - p.queue.Bump(filename) +func (p *Puller) BringToFront(filename string) { + p.queue.BringToFront(filename) } func (p *Puller) Jobs() ([]string, []string) { return p.queue.Jobs() } -// clean deletes orphaned temporary files -func (p *Puller) clean() { - keep := time.Duration(p.model.cfg.Options().KeepTemporariesH) * time.Hour - now := time.Now() - filepath.Walk(p.dir, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - if info.Mode().IsRegular() && defTempNamer.IsTemporary(path) && info.ModTime().Add(keep).Before(now) { - os.Remove(path) - } - - return nil - }) -} - func invalidateFolder(cfg *config.Configuration, folderID string, err error) { for i := range cfg.Folders { folder := &cfg.Folders[i] diff --git a/internal/model/queue.go b/internal/model/queue.go index 24f10170..b2d7b1f8 100644 --- a/internal/model/queue.go +++ b/internal/model/queue.go @@ -17,23 +17,23 @@ package model import "sync" -type JobQueue struct { +type jobQueue struct { progress []string queued []string mut sync.Mutex } -func NewJobQueue() *JobQueue { - return &JobQueue{} +func newJobQueue() *jobQueue { + return &jobQueue{} } -func (q *JobQueue) Push(file string) { +func (q *jobQueue) Push(file string) { q.mut.Lock() q.queued = append(q.queued, file) q.mut.Unlock() } -func (q *JobQueue) Pop() (string, bool) { +func (q *jobQueue) Pop() (string, bool) { q.mut.Lock() defer q.mut.Unlock() @@ -49,7 +49,7 @@ func (q *JobQueue) Pop() (string, bool) { return f, true } -func (q *JobQueue) Bump(filename string) { +func (q *jobQueue) BringToFront(filename string) { q.mut.Lock() defer q.mut.Unlock() @@ -61,7 +61,7 @@ func (q *JobQueue) Bump(filename string) { } } -func (q *JobQueue) Done(file string) { +func (q *jobQueue) Done(file string) { q.mut.Lock() defer q.mut.Unlock() @@ -74,7 +74,7 @@ func (q *JobQueue) Done(file string) { } } -func (q *JobQueue) Jobs() ([]string, []string) { +func (q *jobQueue) Jobs() ([]string, []string) { q.mut.Lock() defer q.mut.Unlock() diff --git a/internal/model/queue_test.go b/internal/model/queue_test.go index cfe8be70..37456644 100644 --- a/internal/model/queue_test.go +++ b/internal/model/queue_test.go @@ -17,12 +17,13 @@ package model import ( "fmt" + "reflect" "testing" ) func TestJobQueue(t *testing.T) { // Some random actions - q := NewJobQueue() + q := newJobQueue() q.Push("f1") q.Push("f2") q.Push("f3") @@ -40,6 +41,8 @@ func TestJobQueue(t *testing.T) { } progress, queued = q.Jobs() if len(progress) != 1 || len(queued) != 3 { + t.Log(progress) + t.Log(queued) t.Fatal("Wrong length") } @@ -74,7 +77,7 @@ func TestJobQueue(t *testing.T) { s := fmt.Sprintf("f%d", i) - q.Bump(s) + q.BringToFront(s) progress, queued = q.Jobs() if len(progress) != 4-i || len(queued) != i { t.Fatal("Wrong length") @@ -116,7 +119,7 @@ func TestJobQueue(t *testing.T) { if len(progress) != 0 || len(queued) != 0 { t.Fatal("Wrong length") } - q.Bump("") + q.BringToFront("") q.Done("f5") // Does not exist progress, queued = q.Jobs() if len(progress) != 0 || len(queued) != 0 { @@ -124,59 +127,58 @@ func TestJobQueue(t *testing.T) { } } -/* -func BenchmarkJobQueuePush(b *testing.B) { - files := genFiles(b.N) +func TestBringToFront(t *testing.T) { + q := newJobQueue() + q.Push("f1") + q.Push("f2") + q.Push("f3") + q.Push("f4") - q := NewJobQueue() + _, queued := q.Jobs() + if !reflect.DeepEqual(queued, []string{"f1", "f2", "f3", "f4"}) { + t.Errorf("Incorrect order %v at start", queued) + } - b.ResetTimer() - for i := 0; i < b.N; i++ { - q.Push(&files[i]) + q.BringToFront("f1") // corner case: does nothing + + _, queued = q.Jobs() + if !reflect.DeepEqual(queued, []string{"f1", "f2", "f3", "f4"}) { + t.Errorf("Incorrect order %v", queued) + } + + q.BringToFront("f3") + + _, queued = q.Jobs() + if !reflect.DeepEqual(queued, []string{"f3", "f1", "f2", "f4"}) { + t.Errorf("Incorrect order %v", queued) + } + + q.BringToFront("f2") + + _, queued = q.Jobs() + if !reflect.DeepEqual(queued, []string{"f2", "f3", "f1", "f4"}) { + t.Errorf("Incorrect order %v", queued) + } + + q.BringToFront("f4") // corner case: last element + + _, queued = q.Jobs() + if !reflect.DeepEqual(queued, []string{"f4", "f2", "f3", "f1"}) { + t.Errorf("Incorrect order %v", queued) } } -func BenchmarkJobQueuePop(b *testing.B) { - files := genFiles(b.N) - - q := NewJobQueue() - for j := range files { - q.Push(&files[j]) - } - - b.ResetTimer() - for i := 0; i < b.N; i++ { - q.Pop() - } -} - -func BenchmarkJobQueuePopDone(b *testing.B) { - files := genFiles(b.N) - - q := NewJobQueue() - for j := range files { - q.Push(&files[j]) - } - - b.ResetTimer() - for i := 0; i < b.N; i++ { - n := q.Pop() - q.Done(n) - } -} -*/ - func BenchmarkJobQueueBump(b *testing.B) { files := genFiles(b.N) - q := NewJobQueue() + q := newJobQueue() for _, f := range files { q.Push(f.Name) } b.ResetTimer() for i := 0; i < b.N; i++ { - q.Bump(files[i].Name) + q.BringToFront(files[i].Name) } } @@ -185,7 +187,7 @@ func BenchmarkJobQueuePushPopDone10k(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - q := NewJobQueue() + q := newJobQueue() for _, f := range files { q.Push(f.Name) } diff --git a/internal/model/scanner.go b/internal/model/scanner.go index 12b4853c..c2824b60 100644 --- a/internal/model/scanner.go +++ b/internal/model/scanner.go @@ -76,7 +76,7 @@ func (s *Scanner) String() string { return fmt.Sprintf("scanner/%s@%p", s.folder, s) } -func (s *Scanner) Bump(string) {} +func (s *Scanner) BringToFront(string) {} func (s *Scanner) Jobs() ([]string, []string) { return nil, nil