@@ -12,6 +12,7 @@ import (
12
12
"io"
13
13
"os"
14
14
"path/filepath"
15
+ "time"
15
16
16
17
"github.com/fsnotify/fsnotify"
17
18
@@ -59,6 +60,12 @@ func File(ctx context.Context, path string, onChange func()) error {
59
60
fw .hash = hash
60
61
61
62
go func () {
63
+ const (
64
+ initialBackoff = 100 * time .Millisecond
65
+ maxBackoff = 15 * time .Second
66
+ )
67
+ var currentBackoff time.Duration
68
+
62
69
defer func () {
63
70
if err != nil {
64
71
log .WithError (err ).Error ("Stopping file watch" )
@@ -83,23 +90,40 @@ func File(ctx context.Context, path string, onChange func()) error {
83
90
continue
84
91
}
85
92
86
- currentHash , err := hashConfig (path )
87
- if err != nil {
88
- log .WithError (err ).WithField ("event" , event .Name ).Warn ("Cannot check if config has changed" )
89
- return
93
+ currentHash , hashErr := hashConfig (path )
94
+ if hashErr != nil {
95
+ log .WithError (hashErr ).WithField ("event" , event .Name ).Warn ("Cannot check if config has changed, backing off" )
96
+
97
+ if currentBackoff == 0 {
98
+ currentBackoff = initialBackoff
99
+ } else {
100
+ currentBackoff *= 2
101
+ if currentBackoff > maxBackoff {
102
+ currentBackoff = maxBackoff
103
+ }
104
+ }
105
+
106
+ select {
107
+ case <- time .After (currentBackoff ):
108
+ case <- ctx .Done ():
109
+ log .Info ("Context cancelled during backoff sleep, stopping file watcher" )
110
+ return
111
+ }
112
+ continue
90
113
}
91
114
92
- // no change
115
+ currentBackoff = 0
116
+
93
117
if currentHash == fw .hash {
118
+ log .WithField ("path" , path ).Debug ("Config file changed but content hash is the same" )
94
119
continue
95
120
}
96
121
97
122
log .WithField ("path" , path ).Info ("reloading file after change" )
98
-
99
123
fw .hash = currentHash
100
124
fw .onChange ()
101
- case err := <- watcher .Errors :
102
- log .WithError (err ).Error ("Unexpected error watching event" )
125
+ case watchErr := <- watcher .Errors :
126
+ log .WithError (watchErr ).Error ("Unexpected error watching event" )
103
127
case <- ctx .Done ():
104
128
return
105
129
}
0 commit comments