// watcher for data change in etcd directory func (p *service_pool) watcher() { client := p.client_pool.Get().(*etcd.Client) defer func() { p.client_pool.Put(client) }() for { ch := make(chan *etcd.Response, 10) go func() { for { if resp, ok := <-ch; ok { if resp.Node.Dir { continue } key, value := resp.Node.Key, resp.Node.Value if value == "" { log.Tracef("node delete: %v", key) p.remove_service(key) } else { log.Tracef("node add: %v %v", key, value) p.add_service(key, value) } } else { return } } }() _, err := client.Watch(DEFAULT_SERVICE_PATH, 0, true, ch, nil) if err != nil { log.Critical(err) } <-time.After(RETRY_DELAY) } }
// add a service func (p *service_pool) add_service(key, value string) { p.Lock() defer p.Unlock() service_name := filepath.Dir(key) if p.services[service_name] == nil { p.services[service_name] = &service{} log.Tracef("new service type: %v", service_name) } service := p.services[service_name] if conn, err := grpc.Dial(value, grpc.WithTimeout(DEFAULT_DIAL_TIMEOUT)); err == nil { service.clients = append(service.clients, client{key, conn}) log.Tracef("service added: %v -- %v", key, value) } else { log.Errorf("did not connect: %v -- %v err: %v", key, value, err) } }
// remove a service func (p *service_pool) remove_service(key string) { p.Lock() defer p.Unlock() service_name := filepath.Dir(key) service := p.services[service_name] if service == nil { log.Tracef("no such service %v", service_name) return } for k := range service.clients { if service.clients[k].key == key { // deletion service.clients[k].conn.Close() service.clients = append(service.clients[:k], service.clients[k+1:]...) log.Tracef("service removed %v", key) return } } }