github.com/Cloud-Foundations/Dominator@v0.3.4/lib/configwatch/impl.go (about) 1 package configwatch 2 3 import ( 4 "bytes" 5 "io" 6 "time" 7 8 "github.com/Cloud-Foundations/Dominator/lib/fsutil" 9 "github.com/Cloud-Foundations/Dominator/lib/log" 10 "github.com/Cloud-Foundations/Dominator/lib/url/urlutil" 11 ) 12 13 func watch(url string, checkInterval time.Duration, 14 decoder Decoder, logger log.DebugLogger) (<-chan interface{}, error) { 15 rawChannel, err := urlutil.WatchUrl(url, checkInterval, logger) 16 if err != nil { 17 return nil, err 18 } 19 configChannel := make(chan interface{}, 1) 20 go watchLoop(rawChannel, configChannel, decoder, logger) 21 return configChannel, nil 22 } 23 24 func watchLoop(rawChannel <-chan io.ReadCloser, 25 configChannel chan<- interface{}, decoder Decoder, logger log.DebugLogger) { 26 var previousChecksum []byte 27 for reader := range rawChannel { 28 checksumReader := fsutil.NewChecksumReader(reader) 29 if config, err := decoder(checksumReader); err != nil { 30 logger.Println(err) 31 } else { 32 newChecksum := checksumReader.GetChecksum() 33 if bytes.Equal(newChecksum, previousChecksum) { 34 logger.Debugln(1, "ignoring unchanged configuration") 35 } else { 36 configChannel <- config 37 previousChecksum = newChecksum 38 } 39 } 40 reader.Close() 41 } 42 close(configChannel) 43 } 44 45 func watchWithCache(url string, checkInterval time.Duration, 46 decoder Decoder, cacheFilename string, initialTimeout time.Duration, 47 logger log.DebugLogger) (<-chan interface{}, error) { 48 rawChannel, err := urlutil.WatchUrlWithCache(url, checkInterval, 49 cacheFilename, initialTimeout, logger) 50 if err != nil { 51 return nil, err 52 } 53 configChannel := make(chan interface{}, 1) 54 go watchLoopWithCache(rawChannel, configChannel, decoder, logger) 55 return configChannel, nil 56 } 57 58 func watchLoopWithCache(rawChannel <-chan *urlutil.CachedReadCloser, 59 configChannel chan<- interface{}, decoder Decoder, logger log.DebugLogger) { 60 var previousChecksum []byte 61 for reader := range rawChannel { 62 checksumReader := fsutil.NewChecksumReader(reader) 63 if config, err := decoder(checksumReader); err != nil { 64 logger.Println(err) 65 } else { 66 newChecksum := checksumReader.GetChecksum() 67 if bytes.Equal(newChecksum, previousChecksum) { 68 logger.Debugln(1, "ignoring unchanged configuration") 69 } else { 70 if err := reader.SaveCache(); err != nil { 71 logger.Println(err) 72 } 73 configChannel <- config 74 previousChecksum = newChecksum 75 } 76 } 77 reader.Close() 78 } 79 close(configChannel) 80 }