mirror of
https://github.com/go-micro/go-micro.git
synced 2025-08-10 21:52:01 +02:00
add support for streaming requests. cleanup watcher initilisation
This commit is contained in:
@@ -54,7 +54,6 @@ func newConsulRegistry(addrs []string, opts ...Option) Registry {
|
||||
services: make(map[string]*Service),
|
||||
}
|
||||
|
||||
cr.Watch()
|
||||
return cr
|
||||
}
|
||||
|
||||
@@ -156,6 +155,6 @@ func (c *consulRegistry) ListServices() ([]*Service, error) {
|
||||
return services, nil
|
||||
}
|
||||
|
||||
func (c *consulRegistry) Watch() {
|
||||
newConsulWatcher(c)
|
||||
func (c *consulRegistry) Watch() (Watcher, error) {
|
||||
return newConsulWatcher(c)
|
||||
}
|
||||
|
@@ -15,20 +15,22 @@ type serviceWatcher struct {
|
||||
name string
|
||||
}
|
||||
|
||||
func newConsulWatcher(cr *consulRegistry) *consulWatcher {
|
||||
func newConsulWatcher(cr *consulRegistry) (Watcher, error) {
|
||||
cw := &consulWatcher{
|
||||
Registry: cr,
|
||||
watchers: make(map[string]*watch.WatchPlan),
|
||||
}
|
||||
|
||||
wp, err := watch.Parse(map[string]interface{}{"type": "services"})
|
||||
if err == nil {
|
||||
wp.Handler = cw.Handle
|
||||
go wp.Run(cr.Address)
|
||||
cw.wp = wp
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cw
|
||||
wp.Handler = cw.Handle
|
||||
go wp.Run(cr.Address)
|
||||
cw.wp = wp
|
||||
|
||||
return cw, nil
|
||||
}
|
||||
|
||||
func (cw *consulWatcher) serviceHandler(idx uint64, data interface{}) {
|
||||
|
@@ -147,8 +147,9 @@ func (e *etcdRegistry) ListServices() ([]*registry.Service, error) {
|
||||
return services, nil
|
||||
}
|
||||
|
||||
func (e *etcdRegistry) Watch() {
|
||||
newEtcdWatcher(e)
|
||||
func (e *etcdRegistry) Watch() (registry.Watcher, error) {
|
||||
// todo: fix watcher
|
||||
return newEtcdWatcher(e)
|
||||
}
|
||||
|
||||
func NewRegistry(addrs []string, opt ...registry.Option) registry.Registry {
|
||||
@@ -170,8 +171,5 @@ func NewRegistry(addrs []string, opt ...registry.Option) registry.Registry {
|
||||
services: make(map[string]*registry.Service),
|
||||
}
|
||||
|
||||
// Need to fix watcher
|
||||
// e.Watch()
|
||||
|
||||
return e
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@ type etcdWatcher struct {
|
||||
stop chan bool
|
||||
}
|
||||
|
||||
func newEtcdWatcher(r *etcdRegistry) *etcdWatcher {
|
||||
func newEtcdWatcher(r *etcdRegistry) (registry.Watcher, error) {
|
||||
ew := &etcdWatcher{
|
||||
registry: r,
|
||||
stop: make(chan bool),
|
||||
@@ -19,53 +19,55 @@ func newEtcdWatcher(r *etcdRegistry) *etcdWatcher {
|
||||
ch := make(chan *etcd.Response)
|
||||
|
||||
go r.client.Watch(prefix, 0, true, ch, ew.stop)
|
||||
go ew.watch(ch)
|
||||
|
||||
go func() {
|
||||
for rsp := range ch {
|
||||
if rsp.Node.Dir {
|
||||
continue
|
||||
}
|
||||
return ew, nil
|
||||
}
|
||||
|
||||
s := decode(rsp.Node.Value)
|
||||
if s == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
r.Lock()
|
||||
|
||||
service, ok := r.services[s.Name]
|
||||
if !ok {
|
||||
if rsp.Action == "create" {
|
||||
r.services[s.Name] = s
|
||||
}
|
||||
r.Unlock()
|
||||
continue
|
||||
}
|
||||
|
||||
switch rsp.Action {
|
||||
case "delete":
|
||||
var nodes []*registry.Node
|
||||
for _, node := range service.Nodes {
|
||||
var seen bool
|
||||
for _, n := range s.Nodes {
|
||||
if node.Id == n.Id {
|
||||
seen = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !seen {
|
||||
nodes = append(nodes, node)
|
||||
}
|
||||
}
|
||||
service.Nodes = nodes
|
||||
case "create":
|
||||
service.Nodes = append(service.Nodes, s.Nodes...)
|
||||
}
|
||||
r.Unlock()
|
||||
func (e *etcdWatcher) watch(ch chan *etcd.Response) {
|
||||
for rsp := range ch {
|
||||
if rsp.Node.Dir {
|
||||
continue
|
||||
}
|
||||
}()
|
||||
|
||||
return ew
|
||||
s := decode(rsp.Node.Value)
|
||||
if s == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
e.registry.Lock()
|
||||
|
||||
service, ok := e.registry.services[s.Name]
|
||||
if !ok {
|
||||
if rsp.Action == "create" {
|
||||
e.registry.services[s.Name] = s
|
||||
}
|
||||
e.registry.Unlock()
|
||||
continue
|
||||
}
|
||||
|
||||
switch rsp.Action {
|
||||
case "delete":
|
||||
var nodes []*registry.Node
|
||||
for _, node := range service.Nodes {
|
||||
var seen bool
|
||||
for _, n := range s.Nodes {
|
||||
if node.Id == n.Id {
|
||||
seen = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !seen {
|
||||
nodes = append(nodes, node)
|
||||
}
|
||||
}
|
||||
service.Nodes = nodes
|
||||
case "create":
|
||||
service.Nodes = append(service.Nodes, s.Nodes...)
|
||||
}
|
||||
|
||||
e.registry.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (ew *etcdWatcher) Stop() {
|
||||
|
@@ -19,10 +19,6 @@ type kregistry struct {
|
||||
services map[string]*registry.Service
|
||||
}
|
||||
|
||||
func (c *kregistry) Watch() {
|
||||
newWatcher(c)
|
||||
}
|
||||
|
||||
func (c *kregistry) Deregister(s *registry.Service) error {
|
||||
return nil
|
||||
}
|
||||
@@ -97,6 +93,10 @@ func (c *kregistry) ListServices() ([]*registry.Service, error) {
|
||||
return services, nil
|
||||
}
|
||||
|
||||
func (c *kregistry) Watch() (registry.Watcher, error) {
|
||||
return newWatcher(c)
|
||||
}
|
||||
|
||||
func NewRegistry(addrs []string, opts ...registry.Option) registry.Registry {
|
||||
host := "http://" + os.Getenv("KUBERNETES_RO_SERVICE_HOST") + ":" + os.Getenv("KUBERNETES_RO_SERVICE_PORT")
|
||||
if len(addrs) > 0 {
|
||||
@@ -113,7 +113,5 @@ func NewRegistry(addrs []string, opts ...registry.Option) registry.Registry {
|
||||
services: make(map[string]*registry.Service),
|
||||
}
|
||||
|
||||
kr.Watch()
|
||||
|
||||
return kr
|
||||
}
|
||||
|
@@ -1,73 +1,91 @@
|
||||
package kubernetes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/proxy/config"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||
"github.com/myodc/go-micro/registry"
|
||||
)
|
||||
|
||||
type watcher struct {
|
||||
registry *kregistry
|
||||
watcher watch.Interface
|
||||
}
|
||||
|
||||
func (k *watcher) OnUpdate(services []api.Service) {
|
||||
fmt.Println("got update")
|
||||
activeServices := util.StringSet{}
|
||||
for _, svc := range services {
|
||||
fmt.Printf("%#v\n", svc.ObjectMeta)
|
||||
name, exists := svc.ObjectMeta.Labels["name"]
|
||||
if !exists {
|
||||
continue
|
||||
}
|
||||
|
||||
activeServices.Insert(name)
|
||||
serviceIP := net.ParseIP(svc.Spec.ClusterIP)
|
||||
|
||||
ks := ®istry.Service{
|
||||
Name: name,
|
||||
Nodes: []*registry.Node{
|
||||
®istry.Node{
|
||||
Address: serviceIP.String(),
|
||||
Port: svc.Spec.Ports[0].Port,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
k.registry.mtx.Lock()
|
||||
k.registry.services[name] = ks
|
||||
k.registry.mtx.Unlock()
|
||||
func (k *watcher) update(event watch.Event) {
|
||||
if event.Object == nil {
|
||||
return
|
||||
}
|
||||
|
||||
var service *api.Service
|
||||
switch obj := event.Object.(type) {
|
||||
case *api.Service:
|
||||
service = obj
|
||||
default:
|
||||
return
|
||||
}
|
||||
|
||||
name, exists := service.ObjectMeta.Labels["name"]
|
||||
if !exists {
|
||||
return
|
||||
}
|
||||
|
||||
switch event.Type {
|
||||
case watch.Added, watch.Modified:
|
||||
case watch.Deleted:
|
||||
k.registry.mtx.Lock()
|
||||
delete(k.registry.services, name)
|
||||
k.registry.mtx.Unlock()
|
||||
return
|
||||
default:
|
||||
return
|
||||
}
|
||||
|
||||
serviceIP := net.ParseIP(service.Spec.ClusterIP)
|
||||
|
||||
k.registry.mtx.Lock()
|
||||
defer k.registry.mtx.Unlock()
|
||||
for name, _ := range k.registry.services {
|
||||
if !activeServices.Has(name) {
|
||||
delete(k.registry.services, name)
|
||||
}
|
||||
k.registry.services[name] = ®istry.Service{
|
||||
Name: name,
|
||||
Nodes: []*registry.Node{
|
||||
®istry.Node{
|
||||
Address: serviceIP.String(),
|
||||
Port: service.Spec.Ports[0].Port,
|
||||
},
|
||||
},
|
||||
}
|
||||
k.registry.mtx.Unlock()
|
||||
}
|
||||
|
||||
func newWatcher(kr *kregistry) *watcher {
|
||||
serviceConfig := config.NewServiceConfig()
|
||||
endpointsConfig := config.NewEndpointsConfig()
|
||||
func (k *watcher) Stop() {
|
||||
k.watcher.Stop()
|
||||
}
|
||||
|
||||
config.NewSourceAPI(
|
||||
kr.client.Services(api.NamespaceAll),
|
||||
kr.client.Endpoints(api.NamespaceAll),
|
||||
time.Second*10,
|
||||
serviceConfig.Channel("api"),
|
||||
endpointsConfig.Channel("api"),
|
||||
)
|
||||
func newWatcher(kr *kregistry) (registry.Watcher, error) {
|
||||
svi := kr.client.Services(api.NamespaceAll)
|
||||
|
||||
ks := &watcher{
|
||||
services, err := svi.List(labels.Everything())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
watch, err := svi.Watch(labels.Everything(), fields.Everything(), services.ResourceVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
w := &watcher{
|
||||
registry: kr,
|
||||
watcher: watch,
|
||||
}
|
||||
|
||||
serviceConfig.RegisterHandler(ks)
|
||||
return ks
|
||||
go func() {
|
||||
for event := range watch.ResultChan() {
|
||||
w.update(event)
|
||||
}
|
||||
}()
|
||||
|
||||
return w, nil
|
||||
}
|
||||
|
@@ -5,6 +5,11 @@ type Registry interface {
|
||||
Deregister(*Service) error
|
||||
GetService(string) (*Service, error)
|
||||
ListServices() ([]*Service, error)
|
||||
Watch() (Watcher, error)
|
||||
}
|
||||
|
||||
type Watcher interface {
|
||||
Stop()
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
|
Reference in New Issue
Block a user