package env import ( "reflect" "go.unistack.org/micro/v3/config" "go.unistack.org/micro/v3/util/jitter" rutil "go.unistack.org/micro/v3/util/reflect" ) type envWatcher struct { opts config.Options wopts config.WatchOptions done chan struct{} vchan chan map[string]interface{} echan chan error } func (w *envWatcher) run() { ticker := jitter.NewTicker(w.wopts.MinInterval, w.wopts.MaxInterval) defer ticker.Stop() src := w.opts.Struct if w.wopts.Struct != nil { src = w.wopts.Struct } for { select { case <-w.done: return case <-ticker.C: dst, err := rutil.Zero(src) if err == nil { err = fillValues(w.opts.Context, reflect.ValueOf(dst), w.opts.StructTag) } if err != nil { w.echan <- err return } srcmp, err := rutil.StructFieldsMap(src) if err != nil { w.echan <- err return } dstmp, err := rutil.StructFieldsMap(dst) if err != nil { w.echan <- err return } for sk, sv := range srcmp { if reflect.DeepEqual(dstmp[sk], sv) { delete(dstmp, sk) } } if len(dstmp) > 0 { w.vchan <- dstmp src = dst } } } } func (w *envWatcher) Next() (map[string]interface{}, error) { select { case <-w.done: break case err := <-w.echan: return nil, err case v, ok := <-w.vchan: if !ok { break } return v, nil } return nil, config.ErrWatcherStopped } func (w *envWatcher) Stop() error { close(w.done) return nil }