@@ -37,9 +37,9 @@ type shardLoader interface {
3737}
3838
3939type DirectoryWatcher struct {
40- dir string
41- timestamps map [string ]time. Time
42- loader shardLoader
40+ dir string
41+ files map [string ]watchedFile
42+ loader shardLoader
4343
4444 // closed once ready
4545 ready chan struct {}
@@ -52,6 +52,22 @@ type DirectoryWatcher struct {
5252 stopped chan struct {}
5353}
5454
55+ type watchedFile struct {
56+ shard os.FileInfo
57+ meta os.FileInfo
58+ modTime time.Time
59+ }
60+
61+ func (f watchedFile ) equal (other watchedFile ) bool {
62+ if ! f .modTime .Equal (other .modTime ) || ! os .SameFile (f .shard , other .shard ) {
63+ return false
64+ }
65+ if (f .meta == nil ) != (other .meta == nil ) {
66+ return false
67+ }
68+ return f .meta == nil || os .SameFile (f .meta , other .meta )
69+ }
70+
5571func (sw * DirectoryWatcher ) Stop () {
5672 sw .closeOnce .Do (func () {
5773 close (sw .quit )
@@ -61,12 +77,12 @@ func (sw *DirectoryWatcher) Stop() {
6177
6278func newDirectoryWatcher (dir string , loader shardLoader ) (* DirectoryWatcher , error ) {
6379 sw := & DirectoryWatcher {
64- dir : dir ,
65- timestamps : map [string ]time. Time {},
66- loader : loader ,
67- ready : make (chan struct {}),
68- quit : make (chan struct {}),
69- stopped : make (chan struct {}),
80+ dir : dir ,
81+ files : map [string ]watchedFile {},
82+ loader : loader ,
83+ ready : make (chan struct {}),
84+ quit : make (chan struct {}),
85+ stopped : make (chan struct {}),
7086 }
7187
7288 go func () {
@@ -140,7 +156,7 @@ func (s *DirectoryWatcher) scan() error {
140156 }
141157 }
142158
143- ts := map [string ]time. Time {}
159+ files := map [string ]watchedFile {}
144160 for _ , fn := range fs {
145161 if name , version := versionFromPath (fn ); latest [name ] != version {
146162 continue
@@ -151,31 +167,35 @@ func (s *DirectoryWatcher) scan() error {
151167 continue
152168 }
153169
154- ts [fn ] = fi .ModTime ()
170+ current := watchedFile {
171+ shard : fi ,
172+ modTime : fi .ModTime (),
173+ }
155174
156175 fiMeta , err := os .Lstat (fn + ".meta" )
157- if err ! = nil {
158- continue
159- }
160- if fiMeta .ModTime (). After ( fi . ModTime ()) {
161- ts [ fn ] = fiMeta . ModTime ()
176+ if err = = nil {
177+ current . meta = fiMeta
178+ if fiMeta . ModTime (). After ( current . modTime ) {
179+ current . modTime = fiMeta .ModTime ()
180+ }
162181 }
182+ files [fn ] = current
163183 }
164184
165185 var toLoad []string
166- for k , mtime := range ts {
167- if t , ok := s .timestamps [k ]; ! ok || t != mtime {
186+ for k , current := range files {
187+ if previous , ok := s .files [k ]; ! ok || ! previous . equal ( current ) {
168188 toLoad = append (toLoad , k )
169- s .timestamps [k ] = mtime
189+ s .files [k ] = current
170190 }
171191 }
172192
173193 var toDrop []string
174194 // Unload deleted shards.
175- for k := range s .timestamps {
176- if _ , ok := ts [k ]; ! ok {
195+ for k := range s .files {
196+ if _ , ok := files [k ]; ! ok {
177197 toDrop = append (toDrop , k )
178- delete (s .timestamps , k )
198+ delete (s .files , k )
179199 }
180200 }
181201
0 commit comments