folderscanner.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. // Copyright (C) 2016 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at https://mozilla.org/MPL/2.0/.
  6. package model
  7. import (
  8. "github.com/syncthing/syncthing/lib/config"
  9. "math/rand"
  10. "time"
  11. )
  12. type rescanRequest struct {
  13. subdirs []string
  14. err chan error
  15. }
  16. // bundle all folder scan activity
  17. type folderScanner struct {
  18. interval time.Duration
  19. timer *time.Timer
  20. now chan rescanRequest
  21. delay chan time.Duration
  22. }
  23. func newFolderScanner(config config.FolderConfiguration) folderScanner {
  24. return folderScanner{
  25. interval: time.Duration(config.RescanIntervalS) * time.Second,
  26. timer: time.NewTimer(time.Millisecond), // The first scan should be done immediately.
  27. now: make(chan rescanRequest),
  28. delay: make(chan time.Duration),
  29. }
  30. }
  31. func (f *folderScanner) Reschedule() {
  32. if f.interval == 0 {
  33. return
  34. }
  35. // Sleep a random time between 3/4 and 5/4 of the configured interval.
  36. sleepNanos := (f.interval.Nanoseconds()*3 + rand.Int63n(2*f.interval.Nanoseconds())) / 4
  37. interval := time.Duration(sleepNanos) * time.Nanosecond
  38. l.Debugln(f, "next rescan in", interval)
  39. f.timer.Reset(interval)
  40. }
  41. func (f *folderScanner) Scan(subdirs []string) error {
  42. req := rescanRequest{
  43. subdirs: subdirs,
  44. err: make(chan error),
  45. }
  46. f.now <- req
  47. return <-req.err
  48. }
  49. func (f *folderScanner) Delay(next time.Duration) {
  50. f.delay <- next
  51. }
  52. func (f *folderScanner) HasNoInterval() bool {
  53. return f.interval == 0
  54. }