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  }