github.com/aaabigfish/gopkg@v1.1.0/etcdv3/instancer.go (about) 1 package etcdv3 2 3 import ( 4 "github.com/aaabigfish/gopkg/log" 5 ) 6 7 // Instancer yields instances stored in a certain etcd keyspace. Any kind of 8 // change in that keyspace is watched and will update the Instancer's Instancers. 9 type Instancer struct { 10 cache *Cache 11 client Client 12 prefix string 13 quitc chan struct{} 14 callback func([]*WatchEvent) error 15 } 16 17 // NewInstancer returns an etcd instancer. It will start watching the given 18 // prefix for changes, and update the subscribers. 19 func NewInstancer(c Client, prefix string) (*Instancer, error) { 20 s := &Instancer{ 21 client: c, 22 prefix: prefix, 23 cache: &Cache{}, 24 quitc: make(chan struct{}), 25 } 26 27 instances, err := s.client.GetEntries(s.prefix) 28 if err == nil { 29 log.Info("NewInstancer prefix(%+v) instancesLen(%v)", s.prefix, len(instances)) 30 } else { 31 log.Errorf("NewInstancer prefix(%+v) err(%v)", s.prefix, err) 32 } 33 s.cache.UpdateByKvPair(instances) 34 35 // routine loop for watch 36 go s.loop() 37 return s, nil 38 } 39 40 func (s *Instancer) loop() { 41 ch := make(chan []*WatchEvent) 42 go s.client.WatchPrefix(s.prefix, ch) 43 44 for { 45 select { 46 case wev := <-ch: 47 s.cache.UpdateByWatchEvent(wev) 48 if s.callback != nil { 49 s.callback(wev) 50 } 51 case <-s.quitc: 52 return 53 } 54 } 55 } 56 57 // Subscribe if watch event will notice caller. 58 func (s *Instancer) Subscribe(callback func([]*WatchEvent) error) { 59 s.callback = callback 60 } 61 62 func (s *Instancer) Cached() *Cache { 63 return s.cache 64 } 65 66 // Stop terminates the Instancer. 67 func (s *Instancer) Stop() { 68 close(s.quitc) 69 }