chore(model): delay starting a pull while there are incoming index updates (#10041)

This adds a simple delay to the process for starting the pull, by
default one second. In practice this means we're likely to wait for
initial index transfer, or multiple messages sent as part of a larger
change. This is better because we're more likely to have the whole
change for the purpose of handling renames etc, and also it's more
efficient to do one larger puller iteration instead of multiple while
also processing changes.

It does however introduce a certain amount of delay into the sync
process, so it can be tuned down or turned off entirely.
This commit is contained in:
Jakob Borg
2025-04-06 14:31:02 +02:00
committed by GitHub
parent cf1cf85ce6
commit c9650fc7d5
4 changed files with 17 additions and 0 deletions
+2
View File
@@ -108,6 +108,7 @@ func TestDefaultValues(t *testing.T) {
FSWatcherEnabled: true,
FSWatcherDelayS: 10,
IgnorePerms: false,
PullerDelayS: 1,
AutoNormalize: true,
MinDiskFree: size,
Versioning: VersioningConfiguration{
@@ -184,6 +185,7 @@ func TestDeviceConfig(t *testing.T) {
FSWatcherDelayS: 10,
Copiers: 0,
Hashers: 0,
PullerDelayS: 1,
AutoNormalize: true,
MinDiskFree: Size{1, "%"},
MaxConflicts: -1,
+1
View File
@@ -68,6 +68,7 @@ type FolderConfiguration struct {
IgnoreDelete bool `json:"ignoreDelete" xml:"ignoreDelete"`
ScanProgressIntervalS int `json:"scanProgressIntervalS" xml:"scanProgressIntervalS"`
PullerPauseS int `json:"pullerPauseS" xml:"pullerPauseS"`
PullerDelayS float64 `json:"pullerDelayS" xml:"pullerDelayS" default:"1"`
MaxConflicts int `json:"maxConflicts" xml:"maxConflicts" default:"10"`
DisableSparseFiles bool `json:"disableSparseFiles" xml:"disableSparseFiles"`
DisableTempIndexes bool `json:"disableTempIndexes" xml:"disableTempIndexes"`
+13
View File
@@ -173,6 +173,8 @@ func (f *folder) Serve(ctx context.Context) error {
}
initialCompleted := f.initialScanFinished
pullTimer := time.NewTimer(0)
pullTimer.Stop()
for {
var err error
@@ -183,6 +185,17 @@ func (f *folder) Serve(ctx context.Context) error {
return nil
case <-f.pullScheduled:
if f.PullerDelayS > 0 {
// Wait for incoming updates to settle before doing the
// actual pull
f.setState(FolderSyncWaiting)
pullTimer.Reset(time.Duration(float64(time.Second) * f.PullerDelayS))
} else {
_, err = f.pull()
}
case <-pullTimer.C:
f.setState(FolderIdle)
_, err = f.pull()
case <-f.pullFailTimer.C:
+1
View File
@@ -103,6 +103,7 @@ func newDefaultCfgWrapper() (config.Wrapper, config.FolderConfiguration, context
func newFolderConfig() config.FolderConfiguration {
cfg := newFolderConfiguration(defaultCfgWrapper, "default", "default", config.FilesystemTypeFake, rand.String(32)+"?content=true")
cfg.FSWatcherEnabled = false
cfg.PullerDelayS = 0
cfg.Devices = append(cfg.Devices, config.FolderDeviceConfiguration{DeviceID: device1})
return cfg
}