MCPcopy
hub / github.com/syncthing/syncthing / monitorWatch

Method monitorWatch

lib/model/folder.go:1056–1136  ·  view source on GitHub ↗

monitorWatch starts the filesystem watching and retries every minute on failure. It should not be used except in startWatch.

(ctx context.Context)

Source from the content-addressed store, hash-verified

1054// monitorWatch starts the filesystem watching and retries every minute on failure.
1055// It should not be used except in startWatch.
1056func (f *folder) monitorWatch(ctx context.Context) {
1057 failTimer := time.NewTimer(0)
1058 aggrCtx, aggrCancel := context.WithCancel(ctx)
1059 var err error
1060 var eventChan <-chan fs.Event
1061 var errChan <-chan error
1062 warnedOutside := false
1063 var lastWatch time.Time
1064 pause := time.Minute
1065 // Subscribe to folder summaries only on kqueue systems, to warn about potential high resource usage
1066 var summarySub events.Subscription
1067 var summaryChan <-chan events.Event
1068 if fs.WatchKqueue && !f.warnedKqueue {
1069 summarySub = f.evLogger.Subscribe(events.FolderSummary)
1070 summaryChan = summarySub.C()
1071 }
1072 defer func() {
1073 aggrCancel() // aggrCancel might e re-assigned -> call within closure
1074 if summaryChan != nil {
1075 summarySub.Unsubscribe()
1076 }
1077 }()
1078 for {
1079 select {
1080 case <-failTimer.C:
1081 eventChan, errChan, err = f.mtimefs.Watch(".", f.ignores, ctx, f.IgnorePerms)
1082 // We do this once per minute initially increased to
1083 // max one hour in case of repeat failures.
1084 f.scanOnWatchErr()
1085 f.setWatchError(err, pause)
1086 if err != nil {
1087 failTimer.Reset(pause)
1088 if pause < 60*time.Minute {
1089 pause *= 2
1090 }
1091 continue
1092 }
1093 lastWatch = time.Now()
1094 watchaggregator.Aggregate(aggrCtx, eventChan, f.watchChan, f.FolderConfiguration, f.model.cfg, f.evLogger)
1095 f.sl.DebugContext(ctx, "Started filesystem watcher")
1096 case err = <-errChan:
1097 var next time.Duration
1098 if dur := time.Since(lastWatch); dur > pause {
1099 pause = time.Minute
1100 next = 0
1101 } else {
1102 next = pause - dur
1103 if pause < 60*time.Minute {
1104 pause *= 2
1105 }
1106 }
1107 failTimer.Reset(next)
1108 f.setWatchError(err, next)
1109 // This error was previously a panic and should never occur, so generate
1110 // a warning, but don't do it repetitively.
1111 var errOutside *fs.WatchEventOutsideRootError
1112 if errors.As(err, &errOutside) {
1113 if !warnedOutside {

Callers 1

startWatchMethod · 0.95

Calls 14

CMethod · 0.95
UnsubscribeMethod · 0.95
scanOnWatchErrMethod · 0.95
setWatchErrorMethod · 0.95
AggregateFunction · 0.92
DoneMethod · 0.80
SubscribeMethod · 0.65
WatchMethod · 0.65
ResetMethod · 0.65
NowMethod · 0.65
SinceMethod · 0.65
ErrorMethod · 0.65

Tested by

no test coverage detected