From b15ff42d5208ddd49726382edcf43f36fa52b1e8 Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Sat, 25 Jul 2026 09:43:22 +0200 Subject: [PATCH] chore: remove ignore file caching entirely (#10813) Effectively nobody uses it, it cost more than it was worth, the code doesn't carry its weight. Remove it and let any similar mechanism in the future be an internal implementation detail. Closes #10812 Signed-off-by: Jakob Borg --- lib/api/testdata/config/config.xml | 1 - lib/config/config_test.go | 2 - lib/config/migrations.go | 4 - lib/config/optionsconfiguration.go | 1 - lib/config/testdata/example.xml | 1 - lib/config/testdata/overridenvalues.xml | 1 - lib/ignore/cache.go | 66 ------- lib/ignore/cache_test.go | 94 ---------- lib/ignore/ignore.go | 55 +----- lib/ignore/ignore_test.go | 239 ++++-------------------- lib/model/model.go | 20 +- lib/model/model_test.go | 6 +- lib/model/testutils_test.go | 2 +- lib/scanner/walk_test.go | 6 +- lib/ur/contract/contract.go | 1 - lib/ur/usage_report.go | 1 - test/h1/config.xml | 1 - test/h2/config.xml | 1 - test/h3/config.xml | 1 - test/h4/config.xml | 1 - 20 files changed, 52 insertions(+), 452 deletions(-) delete mode 100644 lib/ignore/cache.go delete mode 100644 lib/ignore/cache_test.go diff --git a/lib/api/testdata/config/config.xml b/lib/api/testdata/config/config.xml index 3f547e0e9..4aa0f6e39 100644 --- a/lib/api/testdata/config/config.xml +++ b/lib/api/testdata/config/config.xml @@ -116,7 +116,6 @@ 12 false 24 - false 5 false 1 diff --git a/lib/config/config_test.go b/lib/config/config_test.go index aa44bd6db..a82d8e90d 100644 --- a/lib/config/config_test.go +++ b/lib/config/config_test.go @@ -72,7 +72,6 @@ func TestDefaultValues(t *testing.T) { NATTimeoutS: 10, AutoUpgradeIntervalH: 12, KeepTemporariesH: 24, - CacheIgnoredFiles: false, ProgressUpdateIntervalS: 5, LimitBandwidthInLan: false, MinHomeDiskFree: Size{1, "%"}, @@ -278,7 +277,6 @@ func TestOverriddenValues(t *testing.T) { NATTimeoutS: 15, AutoUpgradeIntervalH: 24, KeepTemporariesH: 48, - CacheIgnoredFiles: true, ProgressUpdateIntervalS: 10, LimitBandwidthInLan: true, MinHomeDiskFree: Size{5.2, "%"}, diff --git a/lib/config/migrations.go b/lib/config/migrations.go index d237e8a00..a6377de22 100644 --- a/lib/config/migrations.go +++ b/lib/config/migrations.go @@ -320,10 +320,6 @@ func migrateToConfigV15(cfg *Configuration) { } func migrateToConfigV14(cfg *Configuration) { - // Not using the ignore cache is the new default. Disable it on existing - // configurations. - cfg.Options.CacheIgnoredFiles = false - // Migrate UPnP -> NAT options cfg.Options.NATEnabled = cfg.Options.DeprecatedUPnPEnabled cfg.Options.DeprecatedUPnPEnabled = false diff --git a/lib/config/optionsconfiguration.go b/lib/config/optionsconfiguration.go index 283c4aaa8..7d7f306b2 100644 --- a/lib/config/optionsconfiguration.go +++ b/lib/config/optionsconfiguration.go @@ -45,7 +45,6 @@ type OptionsConfiguration struct { AutoUpgradeIntervalH int `json:"autoUpgradeIntervalH" xml:"autoUpgradeIntervalH" default:"12"` UpgradeToPreReleases bool `json:"upgradeToPreReleases" xml:"upgradeToPreReleases"` KeepTemporariesH int `json:"keepTemporariesH" xml:"keepTemporariesH" default:"24"` - CacheIgnoredFiles bool `json:"cacheIgnoredFiles" xml:"cacheIgnoredFiles" default:"false"` ProgressUpdateIntervalS int `json:"progressUpdateIntervalS" xml:"progressUpdateIntervalS" default:"5"` LimitBandwidthInLan bool `json:"limitBandwidthInLan" xml:"limitBandwidthInLan" default:"false"` MinHomeDiskFree Size `json:"minHomeDiskFree" xml:"minHomeDiskFree" default:"1 %"` diff --git a/lib/config/testdata/example.xml b/lib/config/testdata/example.xml index 6b59457ea..27828e7f9 100644 --- a/lib/config/testdata/example.xml +++ b/lib/config/testdata/example.xml @@ -42,7 +42,6 @@ true 0 24 - true 5 true false diff --git a/lib/config/testdata/overridenvalues.xml b/lib/config/testdata/overridenvalues.xml index fbaf88337..ee25aab4e 100644 --- a/lib/config/testdata/overridenvalues.xml +++ b/lib/config/testdata/overridenvalues.xml @@ -22,7 +22,6 @@ false 24 48 - true 10 false true diff --git a/lib/ignore/cache.go b/lib/ignore/cache.go deleted file mode 100644 index a5e771c17..000000000 --- a/lib/ignore/cache.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2014 The Syncthing Authors. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at https://mozilla.org/MPL/2.0/. - -package ignore - -import ( - "time" - - "github.com/syncthing/syncthing/lib/ignore/ignoreresult" -) - -type nower interface { - Now() time.Time -} - -var clock = nower(defaultClock{}) - -type cache struct { - entries map[string]cacheEntry -} - -type cacheEntry struct { - result ignoreresult.R - access int64 // Unix nanosecond count. Sufficient until the year 2262. -} - -func newCache() *cache { - return &cache{ - entries: make(map[string]cacheEntry), - } -} - -func (c *cache) clean(d time.Duration) { - for k, v := range c.entries { - if clock.Now().Sub(time.Unix(0, v.access)) > d { - delete(c.entries, k) - } - } -} - -func (c *cache) get(key string) (ignoreresult.R, bool) { - entry, ok := c.entries[key] - if ok { - entry.access = clock.Now().UnixNano() - c.entries[key] = entry - } - return entry.result, ok -} - -func (c *cache) set(key string, result ignoreresult.R) { - c.entries[key] = cacheEntry{result, time.Now().UnixNano()} -} - -func (c *cache) len() int { - l := len(c.entries) - return l -} - -type defaultClock struct{} - -func (defaultClock) Now() time.Time { - return time.Now() -} diff --git a/lib/ignore/cache_test.go b/lib/ignore/cache_test.go deleted file mode 100644 index 4cceec1d2..000000000 --- a/lib/ignore/cache_test.go +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (C) 2014 The Syncthing Authors. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at https://mozilla.org/MPL/2.0/. - -package ignore - -import ( - "testing" - "time" - - "github.com/syncthing/syncthing/lib/ignore/ignoreresult" -) - -func TestCache(t *testing.T) { - fc := new(fakeClock) - oldClock := clock - clock = fc - defer func() { - clock = oldClock - }() - - c := newCache() - - res, ok := c.get("nonexistent") - if res.IsIgnored() || res.IsDeletable() || ok { - t.Errorf("res %v, ok %v for nonexistent item", res, ok) - } - - // Set and check some items - - c.set("true", ignoreresult.IgnoredDeletable) - c.set("false", 0) - - res, ok = c.get("true") - if !res.IsIgnored() || !res.IsDeletable() || !ok { - t.Errorf("res %v, ok %v for true item", res, ok) - } - - res, ok = c.get("false") - if res.IsIgnored() || res.IsDeletable() || !ok { - t.Errorf("res %v, ok %v for false item", res, ok) - } - - // Don't clean anything - - c.clean(time.Second) - - // Same values should exist - - res, ok = c.get("true") - if !res.IsIgnored() || !res.IsDeletable() || !ok { - t.Errorf("res %v, ok %v for true item", res, ok) - } - - res, ok = c.get("false") - if res.IsIgnored() || res.IsDeletable() || !ok { - t.Errorf("res %v, ok %v for false item", res, ok) - } - - // Sleep and access, to get some data for clean - - *fc += 500 // milliseconds - - c.get("true") - - *fc += 100 // milliseconds - - // "false" was accessed ~600 ms ago, "true" was accessed ~100 ms ago. - // This should clean out "false" but not "true" - - c.clean(300 * time.Millisecond) - - // Same values should exist - - _, ok = c.get("true") - if !ok { - t.Error("item should still exist") - } - - _, ok = c.get("false") - if ok { - t.Errorf("item should have been cleaned") - } -} - -type fakeClock int64 // milliseconds - -func (f *fakeClock) Now() time.Time { - t := time.Unix(int64(*f)/1000, (int64(*f)%1000)*int64(time.Millisecond)) - *f++ - return t -} diff --git a/lib/ignore/ignore.go b/lib/ignore/ignore.go index 1c8978c78..683ff8f1f 100644 --- a/lib/ignore/ignore.go +++ b/lib/ignore/ignore.go @@ -124,10 +124,7 @@ type Matcher struct { fs fs.Filesystem lines []string // exact lines read from .stignore patterns []Pattern // patterns including those from included files - withCache bool - matches *cache curHash string - stop chan struct{} changeDetector ChangeDetector mut sync.Mutex } @@ -135,13 +132,6 @@ type Matcher struct { // An Option can be passed to New() type Option func(*Matcher) -// WithCache enables or disables lookup caching. The default is disabled. -func WithCache(v bool) Option { - return func(m *Matcher) { - m.withCache = v - } -} - // WithChangeDetector sets a custom ChangeDetector. The default is to simply // use the on disk modtime for comparison. func WithChangeDetector(cd ChangeDetector) Option { @@ -152,8 +142,7 @@ func WithChangeDetector(cd ChangeDetector) Option { func New(fs fs.Filesystem, opts ...Option) *Matcher { m := &Matcher{ - fs: fs, - stop: make(chan struct{}), + fs: fs, } for _, opt := range opts { opt(m) @@ -161,9 +150,6 @@ func New(fs fs.Filesystem, opts ...Option) *Matcher { if m.changeDetector == nil { m.changeDetector = newModtimeChecker() } - if m.withCache { - go m.clean(2 * time.Hour) - } return m } @@ -219,9 +205,6 @@ func (m *Matcher) parseLocked(r io.Reader, file string) error { m.curHash = newHash m.patterns = patterns - if m.withCache { - m.matches = newCache() - } return err } @@ -232,7 +215,7 @@ func (m *Matcher) parseLocked(r io.Reader, file string) error { // NFC everywhere else). This is always the case in real usage in syncthing, as // we ensure native unicode normalisation on all entry points (scanning and from // protocol) - so no need to normalize when calling this, except e.g. in tests. -func (m *Matcher) Match(file string) (result ignoreresult.R) { +func (m *Matcher) Match(file string) ignoreresult.R { switch { case fs.IsTemporary(file): return ignoreresult.IgnoreAndSkip @@ -254,19 +237,6 @@ func (m *Matcher) Match(file string) (result ignoreresult.R) { // Change backslashes to slashes (on Windows only) file = filepath.ToSlash(file) - if m.matches != nil { - // Check the cache for a known result. - res, ok := m.matches.get(file) - if ok { - return res - } - - // Update the cache with the result at return time - defer func() { - m.matches.set(file, result) - }() - } - // Check all the patterns for a match. Track whether the patterns so far // allow skipping matched directories or not. As soon as we hit an // exclude pattern (with some exceptions), we can't skip directories @@ -327,27 +297,6 @@ func (m *Matcher) Hash() string { return m.curHash } -func (m *Matcher) Stop() { - close(m.stop) -} - -func (m *Matcher) clean(d time.Duration) { - t := time.NewTimer(d / 2) - for { - select { - case <-m.stop: - return - case <-t.C: - m.mut.Lock() - if m.matches != nil { - m.matches.clean(d) - } - t.Reset(d / 2) - m.mut.Unlock() - } - } -} - func hashPatterns(patterns []Pattern) string { h := sha256.New() for _, pat := range patterns { diff --git a/lib/ignore/ignore_test.go b/lib/ignore/ignore_test.go index 09c2b06e9..bdd90b985 100644 --- a/lib/ignore/ignore_test.go +++ b/lib/ignore/ignore_test.go @@ -52,7 +52,7 @@ func newTestFS() fs.Filesystem { func TestIgnore(t *testing.T) { testFs := newTestFS() - pats := New(testFs, WithCache(true)) + pats := New(testFs) err := pats.Load(".stignore") if err != nil { t.Fatal(err) @@ -104,7 +104,7 @@ func TestExcludes(t *testing.T) { i*2 !ign2 ` - pats := New(testFs, WithCache(true)) + pats := New(testFs) err := pats.Parse(bytes.NewBufferString(stignore), ".stignore") if err != nil { t.Fatal(err) @@ -151,7 +151,7 @@ func TestFlagOrder(t *testing.T) { (?i)(?d)(?d)!ign9 (?d)(?d)!ign10 ` - pats := New(testFs, WithCache(true)) + pats := New(testFs) err := pats.Parse(bytes.NewBufferString(stignore), ".stignore") if err != nil { t.Fatal(err) @@ -188,7 +188,7 @@ func TestDeletables(t *testing.T) { ign7 (?i)ign8 ` - pats := New(testFs, WithCache(true)) + pats := New(testFs) err := pats.Parse(bytes.NewBufferString(stignore), ".stignore") if err != nil { t.Fatal(err) @@ -229,7 +229,7 @@ func TestBadPatterns(t *testing.T) { } for _, pat := range badPatterns { - err := New(testFs, WithCache(true)).Parse(bytes.NewBufferString(pat), ".stignore") + err := New(testFs).Parse(bytes.NewBufferString(pat), ".stignore") if err == nil { t.Errorf("No error for pattern %q", pat) } @@ -247,7 +247,7 @@ func TestBadPatterns(t *testing.T) { func TestCaseSensitivity(t *testing.T) { testFs := newTestFS() - ign := New(testFs, WithCache(true)) + ign := New(testFs) err := ign.Parse(bytes.NewBufferString("test"), ".stignore") if err != nil { t.Error(err) @@ -275,126 +275,6 @@ func TestCaseSensitivity(t *testing.T) { } } -func TestCaching(t *testing.T) { - fs := fs.NewFilesystem(fs.FilesystemTypeFake, rand.String(32)+"?content=true") - - fd1, err := osutil.TempFile(fs, "", "") - if err != nil { - t.Fatal(err) - } - - fd2, err := osutil.TempFile(fs, "", "") - if err != nil { - t.Fatal(err) - } - - defer fd1.Close() - defer fd2.Close() - defer fs.Remove(fd1.Name()) - defer fs.Remove(fd2.Name()) - - _, err = fd1.Write([]byte("/x/\n#include " + filepath.Base(fd2.Name()) + "\n")) - if err != nil { - t.Fatal(err) - } - - fd2.Write([]byte("/y/\n")) - - pats := New(fs, WithCache(true)) - err = pats.Load(fd1.Name()) - if err != nil { - t.Fatal(err) - } - - if pats.matches.len() != 0 { - t.Fatal("Expected empty cache") - } - - // Cache some outcomes - - for _, letter := range []string{"a", "b", "x", "y"} { - pats.Match(letter) - } - - if pats.matches.len() != 4 { - t.Fatal("Expected 4 cached results") - } - - // Reload file, expect old outcomes to be preserved - - err = pats.Load(fd1.Name()) - if err != nil { - t.Fatal(err) - } - if pats.matches.len() != 4 { - t.Fatal("Expected 4 cached results") - } - - // Modify the include file, expect empty cache. Ensure the timestamp on - // the file changes. - - fd2.Write([]byte("/z/\n")) - fd2.Sync() - fakeTime := time.Now().Add(5 * time.Second) - fs.Chtimes(fd2.Name(), fakeTime, fakeTime) - - err = pats.Load(fd1.Name()) - if err != nil { - t.Fatal(err) - } - - if pats.matches.len() != 0 { - t.Fatal("Expected 0 cached results") - } - - // Cache some outcomes again - - for _, letter := range []string{"b", "x", "y"} { - pats.Match(letter) - } - - // Verify that outcomes preserved on next load - - err = pats.Load(fd1.Name()) - if err != nil { - t.Fatal(err) - } - if pats.matches.len() != 3 { - t.Fatal("Expected 3 cached results") - } - - // Modify the root file, expect cache to be invalidated - - fd1.Write([]byte("/a/\n")) - fd1.Sync() - fakeTime = time.Now().Add(5 * time.Second) - fs.Chtimes(fd1.Name(), fakeTime, fakeTime) - - err = pats.Load(fd1.Name()) - if err != nil { - t.Fatal(err) - } - if pats.matches.len() != 0 { - t.Fatal("Expected cache invalidation") - } - - // Cache some outcomes again - - for _, letter := range []string{"b", "x", "y"} { - pats.Match(letter) - } - - // Verify that outcomes provided on next load - - err = pats.Load(fd1.Name()) - if err != nil { - t.Fatal(err) - } - if pats.matches.len() != 3 { - t.Fatal("Expected 3 cached results") - } -} - func TestCommentsAndBlankLines(t *testing.T) { testFs := newTestFS() @@ -409,7 +289,7 @@ func TestCommentsAndBlankLines(t *testing.T) { ` - pats := New(testFs, WithCache(true)) + pats := New(testFs) err := pats.Parse(bytes.NewBufferString(stignore), ".stignore") if err != nil { t.Error(err) @@ -451,59 +331,6 @@ flamingo } } -func BenchmarkMatchCached(b *testing.B) { - stignore := ` -.frog -.frog* -.frogfox -.whale -.whale/* -.dolphin -.dolphin/* -~ferret~.* -.ferret.* -flamingo.* -flamingo -*.crow -*.crow - ` - // Caches per file, hence write the patterns to a file. - - fs := fs.NewFilesystem(fs.FilesystemTypeFake, rand.String(32)+"?content=true") - - fd, err := osutil.TempFile(fs, "", "") - if err != nil { - b.Fatal(err) - } - - _, err = fd.Write([]byte(stignore)) - defer fd.Close() - defer fs.Remove(fd.Name()) - if err != nil { - b.Fatal(err) - } - - // Load the patterns - pats := New(fs, WithCache(true)) - err = pats.Load(fd.Name()) - if err != nil { - b.Fatal(err) - } - // Cache the outcome for "filename" - pats.Match("filename") - - // This load should now load the cached outcomes as the set of patterns - // has not changed. - err = pats.Load(fd.Name()) - if err != nil { - b.Fatal(err) - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - result = pats.Match("filename") - } -} - func TestCacheReload(t *testing.T) { fs := fs.NewFilesystem(fs.FilesystemTypeFake, rand.String(32)+"?content=true") @@ -522,7 +349,7 @@ func TestCacheReload(t *testing.T) { t.Fatal(err) } - pats := New(fs, WithCache(true)) + pats := New(fs) err = pats.Load(fd.Name()) if err != nil { t.Fatal(err) @@ -579,7 +406,7 @@ func TestCacheReload(t *testing.T) { func TestHash(t *testing.T) { testFs := newTestFS() - p1 := New(testFs, WithCache(true)) + p1 := New(testFs) err := p1.Load(".stignore") if err != nil { t.Fatal(err) @@ -595,7 +422,7 @@ func TestHash(t *testing.T) { /ffile lost+found ` - p2 := New(testFs, WithCache(true)) + p2 := New(testFs) err = p2.Parse(bytes.NewBufferString(stignore), ".stignore") if err != nil { t.Fatal(err) @@ -610,7 +437,7 @@ func TestHash(t *testing.T) { /ffile lost+found ` - p3 := New(testFs, WithCache(true)) + p3 := New(testFs) err = p3.Parse(bytes.NewBufferString(stignore), ".stignore") if err != nil { t.Fatal(err) @@ -636,7 +463,7 @@ func TestHash(t *testing.T) { func TestHashOfEmpty(t *testing.T) { testFs := newTestFS() - p1 := New(testFs, WithCache(true)) + p1 := New(testFs) err := p1.Load(".stignore") if err != nil { @@ -678,7 +505,7 @@ func TestWindowsPatterns(t *testing.T) { a/b c\d ` - pats := New(testFs, WithCache(true)) + pats := New(testFs) err := pats.Parse(bytes.NewBufferString(stignore), ".stignore") if err != nil { @@ -706,7 +533,7 @@ func TestAutomaticCaseInsensitivity(t *testing.T) { A/B c/d ` - pats := New(testFs, WithCache(true)) + pats := New(testFs) err := pats.Parse(bytes.NewBufferString(stignore), ".stignore") if err != nil { @@ -728,7 +555,7 @@ func TestCommas(t *testing.T) { foo,bar.txt {baz,quux}.txt ` - pats := New(testFs, WithCache(true)) + pats := New(testFs) err := pats.Parse(bytes.NewBufferString(stignore), ".stignore") if err != nil { @@ -762,7 +589,7 @@ func TestIssue3164(t *testing.T) { (?d)(?i)/foo (?d)(?i)**/bar ` - pats := New(testFs, WithCache(true)) + pats := New(testFs) err := pats.Parse(bytes.NewBufferString(stignore), ".stignore") if err != nil { @@ -801,7 +628,7 @@ func TestIssue3174(t *testing.T) { stignore := ` *ä* ` - pats := New(testFs, WithCache(true)) + pats := New(testFs) err := pats.Parse(bytes.NewBufferString(stignore), ".stignore") if err != nil { @@ -822,7 +649,7 @@ func TestIssue3639(t *testing.T) { stignore := ` foo/ ` - pats := New(testFs, WithCache(true)) + pats := New(testFs) err := pats.Parse(bytes.NewBufferString(stignore), ".stignore") if err != nil { @@ -858,7 +685,7 @@ func TestIssue3674(t *testing.T) { {"as/dc", true}, } - pats := New(testFs, WithCache(true)) + pats := New(testFs) err := pats.Parse(bytes.NewBufferString(stignore), ".stignore") if err != nil { @@ -893,7 +720,7 @@ func TestGobwasGlobIssue18(t *testing.T) { {"bbaa", false}, } - pats := New(testFs, WithCache(true)) + pats := New(testFs) err := pats.Parse(bytes.NewBufferString(stignore), ".stignore") if err != nil { @@ -925,7 +752,7 @@ func TestRoot(t *testing.T) { {"b", true}, } - pats := New(testFs, WithCache(true)) + pats := New(testFs) err := pats.Parse(bytes.NewBufferString(stignore), ".stignore") if err != nil { @@ -951,7 +778,7 @@ func TestLines(t *testing.T) { !/a ` - pats := New(testFs, WithCache(true)) + pats := New(testFs) err := pats.Parse(bytes.NewBufferString(stignore), ".stignore") if err != nil { @@ -992,7 +819,7 @@ func TestDuplicateLines(t *testing.T) { /* ` - pats := New(testFs, WithCache(true)) + pats := New(testFs) err := pats.Parse(bytes.NewBufferString(stignore), ".stignore") if err != nil { @@ -1025,7 +852,7 @@ func TestIssue4680(t *testing.T) { {"#snapshot/foo", true}, } - pats := New(testFs, WithCache(true)) + pats := New(testFs) err := pats.Parse(bytes.NewBufferString(stignore), ".stignore") if err != nil { @@ -1045,7 +872,7 @@ func TestIssue4689(t *testing.T) { stignore := `// orig` - pats := New(testFs, WithCache(true)) + pats := New(testFs) err := pats.Parse(bytes.NewBufferString(stignore), ".stignore") if err != nil { @@ -1076,7 +903,7 @@ func TestIssue4901(t *testing.T) { puppy ` - pats := New(testFs, WithCache(true)) + pats := New(testFs) fd, err := pats.fs.Create(".stignore") if err != nil { @@ -1119,7 +946,7 @@ func TestIssue4901(t *testing.T) { func TestIssue5009(t *testing.T) { testFs := newTestFS() - pats := New(testFs, WithCache(true)) + pats := New(testFs) stignore := ` ign1 @@ -1152,7 +979,7 @@ func TestIssue5009(t *testing.T) { func TestSpecialChars(t *testing.T) { testFs := newTestFS() - pats := New(testFs, WithCache(true)) + pats := New(testFs) stignore := `(?i)/#recycle (?i)/#nosync @@ -1179,7 +1006,7 @@ func TestSpecialChars(t *testing.T) { func TestIntlWildcards(t *testing.T) { testFs := newTestFS() - pats := New(testFs, WithCache(true)) + pats := New(testFs) stignore := `1000春 200?春 @@ -1208,7 +1035,7 @@ func TestPartialIncludeLine(t *testing.T) { // Loading a partial #include line (no file mentioned) should error but not crash. - pats := New(testFs, WithCache(true)) + pats := New(testFs) cases := []string{ "#include", @@ -1267,7 +1094,7 @@ func TestSkipIgnoredDirs(t *testing.T) { } } - pats := New(testFs, WithCache(true)) + pats := New(testFs) stignore := ` /foo/ign* @@ -1711,7 +1538,7 @@ func testEscape(t *testing.T, tests []escapeTest, noErrors bool) { for name, content := range testEscapeFiles { fs.WriteFile(testFS, name, []byte(content), 0o666) } - pats := New(testFS, WithCache(true)) + pats := New(testFS) err := pats.Parse(bytes.NewBufferString(test.pattern), ".stignore") if noErrors { @@ -1753,7 +1580,7 @@ func TestIgnoreThroughSymlink(t *testing.T) { t.Fatal(err) } - pats := New(testFS, WithCache(true)) + pats := New(testFS) if err := pats.Load(".stignore"); err != nil { t.Fatal(err) } diff --git a/lib/model/model.go b/lib/model/model.go index 7ba426aea..3b35a4a64 100644 --- a/lib/model/model.go +++ b/lib/model/model.go @@ -300,7 +300,7 @@ func (m *model) initFolders(cfg config.Configuration) error { folderCfg.CreateRoot() continue } - err := m.newFolder(folderCfg, cfg.Options.CacheIgnoredFiles) + err := m.newFolder(folderCfg) if err != nil { return err } @@ -335,8 +335,8 @@ func (m *model) fatal(err error) { } // Need to hold lock on m.mut when calling this. -func (m *model) addAndStartFolderLocked(cfg config.FolderConfiguration, cacheIgnoredFiles bool) { - ignores := ignore.New(cfg.Filesystem(), ignore.WithCache(cacheIgnoredFiles)) +func (m *model) addAndStartFolderLocked(cfg config.FolderConfiguration) { + ignores := ignore.New(cfg.Filesystem()) if cfg.Type != config.FolderTypeReceiveEncrypted { if err := ignores.Load(".stignore"); err != nil && !fs.IsNotExist(err) { slog.Error("Failed to load ignores", slogutil.Error(err)) @@ -509,7 +509,7 @@ func (m *model) cleanupFolderLocked(cfg config.FolderConfiguration) { delete(m.folderEncryptionFailures, cfg.ID) } -func (m *model) restartFolder(from, to config.FolderConfiguration, cacheIgnoredFiles bool) error { +func (m *model) restartFolder(from, to config.FolderConfiguration) error { if to.ID == "" { panic("bug: cannot restart empty folder ID") } @@ -539,7 +539,7 @@ func (m *model) restartFolder(from, to config.FolderConfiguration, cacheIgnoredF m.cleanupFolderLocked(from) if !to.Paused { - m.addAndStartFolderLocked(to, cacheIgnoredFiles) + m.addAndStartFolderLocked(to) } runner, _ := m.folderRunners.Get(to.ID) @@ -560,11 +560,11 @@ func (m *model) restartFolder(from, to config.FolderConfiguration, cacheIgnoredF return nil } -func (m *model) newFolder(cfg config.FolderConfiguration, cacheIgnoredFiles bool) error { +func (m *model) newFolder(cfg config.FolderConfiguration) error { m.mut.Lock() defer m.mut.Unlock() - m.addAndStartFolderLocked(cfg, cacheIgnoredFiles) + m.addAndStartFolderLocked(cfg) // Cluster configs might be received and processed before reaching this // point, i.e. before the folder is started. If that's the case, start @@ -2972,7 +2972,7 @@ func (m *model) CommitConfiguration(from, to config.Configuration) bool { slog.Info("Paused folder", cfg.LogAttr()) } else { slog.Info("Adding folder", cfg.LogAttr()) - if err := m.newFolder(cfg, to.Options.CacheIgnoredFiles); err != nil { + if err := m.newFolder(cfg); err != nil { m.fatal(err) return true } @@ -2998,8 +2998,8 @@ func (m *model) CommitConfiguration(from, to config.Configuration) bool { // This folder exists on both sides. Settings might have changed. // Check if anything differs that requires a restart. - if !reflect.DeepEqual(fromCfg.RequiresRestartOnly(), toCfg.RequiresRestartOnly()) || from.Options.CacheIgnoredFiles != to.Options.CacheIgnoredFiles { - if err := m.restartFolder(fromCfg, toCfg, to.Options.CacheIgnoredFiles); err != nil { + if !reflect.DeepEqual(fromCfg.RequiresRestartOnly(), toCfg.RequiresRestartOnly()) { + if err := m.restartFolder(fromCfg, toCfg); err != nil { m.fatal(err) return true } diff --git a/lib/model/model_test.go b/lib/model/model_test.go index 54da73943..1964c05ff 100644 --- a/lib/model/model_test.go +++ b/lib/model/model_test.go @@ -1603,7 +1603,7 @@ func TestIgnores(t *testing.T) { ID: "fresh", Path: "XXX", FilesystemType: config.FilesystemTypeFake, } - ignores := ignore.New(fcfg.Filesystem(), ignore.WithCache(m.cfg.Options().CacheIgnoredFiles)) + ignores := ignore.New(fcfg.Filesystem()) m.mut.Lock() m.folderCfgs[fcfg.ID] = fcfg m.folderIgnores[fcfg.ID] = ignores @@ -1618,7 +1618,7 @@ func TestIgnores(t *testing.T) { pausedDefaultFolderConfig := defaultFolderConfig pausedDefaultFolderConfig.Paused = true - m.restartFolder(defaultFolderConfig, pausedDefaultFolderConfig, false) + m.restartFolder(defaultFolderConfig, pausedDefaultFolderConfig) // Here folder initialization is not an issue as a paused folder isn't // added to the model and thus there is no initial scan happening. @@ -2216,7 +2216,7 @@ func TestIndexesForUnknownDevicesDropped(t *testing.T) { t.Error("expected two devices") } - m.newFolder(defaultFolderConfig, false) + m.newFolder(defaultFolderConfig) defer cleanupModel(m) if devs, err := m.sdb.ListDevicesForFolder("default"); err != nil || len(devs) != 1 { diff --git a/lib/model/testutils_test.go b/lib/model/testutils_test.go index bd9de3078..b9f6376c7 100644 --- a/lib/model/testutils_test.go +++ b/lib/model/testutils_test.go @@ -250,7 +250,7 @@ func (*alwaysChanged) Changed() bool { func folderIgnoresAlwaysReload(t testing.TB, m *testModel, fcfg config.FolderConfiguration) { t.Helper() m.removeFolder(fcfg) - ignores := ignore.New(fcfg.Filesystem(), ignore.WithCache(true), ignore.WithChangeDetector(newAlwaysChanged())) + ignores := ignore.New(fcfg.Filesystem(), ignore.WithChangeDetector(newAlwaysChanged())) m.mut.Lock() m.addAndStartFolderLockedWithIgnores(fcfg, ignores) m.mut.Unlock() diff --git a/lib/scanner/walk_test.go b/lib/scanner/walk_test.go index 699772f97..c669a4457 100644 --- a/lib/scanner/walk_test.go +++ b/lib/scanner/walk_test.go @@ -749,7 +749,7 @@ func TestRecurseInclude(t *testing.T) { * ` testFs := newTestFs() - ignores := ignore.New(testFs, ignore.WithCache(true)) + ignores := ignore.New(testFs) if err := ignores.Parse(bytes.NewBufferString(stignore), ".stignore"); err != nil { t.Fatal(err) } @@ -859,7 +859,7 @@ func TestSkipIgnoredDirs(t *testing.T) { w := &walker{} - pats := ignore.New(fss, ignore.WithCache(true)) + pats := ignore.New(fss) stignore := ` /foo/ign* @@ -892,7 +892,7 @@ func TestIncludedSubdir(t *testing.T) { t.Fatal(err) } - pats := ignore.New(fss, ignore.WithCache(true)) + pats := ignore.New(fss) stignore := ` !/foo/bar diff --git a/lib/ur/contract/contract.go b/lib/ur/contract/contract.go index 15b52420c..37cebf331 100644 --- a/lib/ur/contract/contract.go +++ b/lib/ur/contract/contract.go @@ -91,7 +91,6 @@ type Report struct { NATType string `json:"natType,omitempty" metric:"nat_detection,gaugeVec:type" since:"3"` AlwaysLocalNets bool `json:"alwaysLocalNets,omitempty" metric:"feature_count{feature=AlwaysLocalNets},gauge" since:"3"` - CacheIgnoredFiles bool `json:"cacheIgnoredFiles,omitempty" metric:"feature_count{feature=CacheIgnoredFiles},gauge" since:"3"` OverwriteRemoteDeviceNames bool `json:"overwriteRemoteDeviceNames,omitempty" metric:"feature_count{feature=OverwriteRemoteDeviceNames},gauge" since:"3"` ProgressEmitterEnabled bool `json:"progressEmitterEnabled,omitempty" metric:"feature_count{feature=ProgressEmitterEnabled},gauge" since:"3"` CustomDefaultFolderPath bool `json:"customDefaultFolderPath,omitempty" metric:"feature_count{feature=CustomDefaultFolderPath},gauge" since:"3"` diff --git a/lib/ur/usage_report.go b/lib/ur/usage_report.go index 4d3c1f342..71c38fd85 100644 --- a/lib/ur/usage_report.go +++ b/lib/ur/usage_report.go @@ -217,7 +217,6 @@ func (s *Service) reportData(ctx context.Context, urVersion int, preview bool) ( report.Uptime = s.UptimeS() report.NATType = s.connectionsService.NATType() report.AlwaysLocalNets = len(opts.AlwaysLocalNets) > 0 - report.CacheIgnoredFiles = opts.CacheIgnoredFiles report.OverwriteRemoteDeviceNames = opts.OverwriteRemoteDevNames report.ProgressEmitterEnabled = opts.ProgressUpdateIntervalS > -1 report.CustomDefaultFolderPath = defaultFolder.Path != "~" diff --git a/test/h1/config.xml b/test/h1/config.xml index 40a8c947d..0853c8630 100644 --- a/test/h1/config.xml +++ b/test/h1/config.xml @@ -101,7 +101,6 @@ 12 false 24 - false 5 false 1 diff --git a/test/h2/config.xml b/test/h2/config.xml index 123eac79c..b2acd6efa 100644 --- a/test/h2/config.xml +++ b/test/h2/config.xml @@ -99,7 +99,6 @@ 12 false 24 - false 5 true 1 diff --git a/test/h3/config.xml b/test/h3/config.xml index 440c15b0d..5021b89c2 100644 --- a/test/h3/config.xml +++ b/test/h3/config.xml @@ -117,7 +117,6 @@ 12 false 24 - false 5 false 1 diff --git a/test/h4/config.xml b/test/h4/config.xml index 8347f39c6..19b3fddd5 100644 --- a/test/h4/config.xml +++ b/test/h4/config.xml @@ -69,7 +69,6 @@ 12 false 24 - false 5 false 1