func (r *registryRouter) watch() {
	var attempts int
	for {
		if r.isClosed() {
			return
		}
		w, err := r.opts.Registry.Watch()
		if err != nil {
			attempts++
			log.Println("Error watching endpoints", err)
			time.Sleep(time.Duration(attempts) * time.Second)
			continue
		}
		ch := make(chan bool)
		go func() {
			select {
			case <-ch:
				w.Stop()
			case <-r.exit:
				w.Stop()
			}
		}()
		attempts = 0
		for {
			res, err := w.Next()
			if err != nil {
				log.Println("Error getting next endpoint", err)
				close(ch)
				break
			}
			r.process(res)
		}
	}
}
watch for endpoint changes
package registry
import (
	"errors"
	"fmt"
	"log"
	"net/http"
	"regexp"
	"strings"
	"sync"
	"time"
	"github.com/micro/go-api"
	"github.com/micro/go-api/router"
	"github.com/micro/go-micro/registry"
	"github.com/micro/go-rcache"
)
type registryRouter struct {
	exit chan bool
	opts router.Options
	rc rcache.Cache
	sync.RWMutex
	eps map[string]*api.Service
}
func setNamespace(ns, name string) string {
	ns = strings.TrimSpace(ns)
	name = strings.TrimSpace(name)
	if len(ns) == 0 {
		return name
	}
	switch {
	case strings.HasSuffix(ns, "-"):
		return strings.Replace(ns+name, ".", "-", -1)
	case strings.HasSuffix(ns, "."):
		return ns + name
	}
	return strings.Join([]string{ns, name}, ".")
}
func (r *registryRouter) isClosed() bool {
	select {
	case <-r.exit:
		return true
	default:
		return false
	}
}
func (r *registryRouter) refresh() {
	var attempts int
	for {
		services, err := r.opts.Registry.ListServices()
		if err != nil {
			attempts++
			log.Println("Error listing endpoints", err)
			time.Sleep(time.Duration(attempts) * time.Second)
			continue
		}
		attempts = 0
		for _, s := range services {
			if !strings.HasPrefix(s.Name, r.opts.Namespace) {
				continue
			}
			service, err := r.rc.GetService(s.Name)
			if err != nil {
				continue
			}
			r.store(service)
		}
		select {
		case <-time.After(time.Minute * 10):
		case <-r.exit:
			return
		}
	}
}
func (r *registryRouter) process(res *registry.Result) {
	if res == nil || res.Service == nil || !strings.HasPrefix(res.Service.Name, r.opts.Namespace) {
		return
	}
	service, err := r.opts.Registry.GetService(res.Service.Name)
	if err != nil {
		return
	}
	r.store(service)
}
func (r *registryRouter) store(services []*registry.Service) {
	eps := map[string]*api.Service{}
	names := map[string]bool{}
	for _, service := range services {
		names[service.Name] = true
		for _, endpoint := range service.Endpoints {
			key := fmt.Sprintf("%s:%s", service.Name, endpoint.Name)
			end := api.Decode(endpoint.Metadata)
			if err := api.Validate(end); err != nil {
				continue
			}
			ep, ok := eps[key]
			if !ok {
				ep = &api.Service{Name: service.Name}
			}
			ep.Endpoint = end
			ep.Services = append(ep.Services, service)
			eps[key] = ep
		}
	}
	r.Lock()
	defer r.Unlock()
	for key, service := range r.eps {
		if !names[service.Name] {
			continue
		}
		delete(r.eps, key)
	}
	for name, endpoint := range eps {
		r.eps[name] = endpoint
	}
}