1
0
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:
Asim
2015-06-01 18:55:27 +01:00
parent fa2c27b64f
commit 09c784d294
25 changed files with 729 additions and 384 deletions

View File

@@ -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)
}

View File

@@ -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{}) {

View File

@@ -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
}

View File

@@ -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() {

View File

@@ -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
}

View File

@@ -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 := &registry.Service{
Name: name,
Nodes: []*registry.Node{
&registry.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] = &registry.Service{
Name: name,
Nodes: []*registry.Node{
&registry.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
}

View File

@@ -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 {