Restructure go-micro layout and plugins
This commit is contained in:
parent
018183fa49
commit
74fd1fc989
@ -27,7 +27,7 @@ type Subscriber interface {
|
|||||||
|
|
||||||
type options struct{}
|
type options struct{}
|
||||||
|
|
||||||
type Options func(*options)
|
type Option func(*options)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Address string
|
Address string
|
||||||
@ -35,13 +35,17 @@ var (
|
|||||||
DefaultBroker Broker
|
DefaultBroker Broker
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func NewBroker(addrs []string, opt ...Option) Broker {
|
||||||
|
return newHttpBroker([]string{Address}, opt...)
|
||||||
|
}
|
||||||
|
|
||||||
func Init() error {
|
func Init() error {
|
||||||
if len(Id) == 0 {
|
if len(Id) == 0 {
|
||||||
Id = "broker-" + uuid.NewUUID().String()
|
Id = "broker-" + uuid.NewUUID().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
if DefaultBroker == nil {
|
if DefaultBroker == nil {
|
||||||
DefaultBroker = NewHttpBroker([]string{Address})
|
DefaultBroker = newHttpBroker([]string{Address})
|
||||||
}
|
}
|
||||||
|
|
||||||
return DefaultBroker.Init()
|
return DefaultBroker.Init()
|
||||||
|
11
broker/http/http.go
Normal file
11
broker/http/http.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package http
|
||||||
|
|
||||||
|
// This is a hack
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/myodc/go-micro/broker"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewBroker(addrs []string, opt ...broker.Option) broker.Broker {
|
||||||
|
return broker.NewBroker(addrs, opt...)
|
||||||
|
}
|
@ -21,39 +21,54 @@ import (
|
|||||||
"github.com/myodc/go-micro/registry"
|
"github.com/myodc/go-micro/registry"
|
||||||
)
|
)
|
||||||
|
|
||||||
type HttpBroker struct {
|
type httpBroker struct {
|
||||||
id string
|
id string
|
||||||
address string
|
address string
|
||||||
unsubscribe chan *HttpSubscriber
|
unsubscribe chan *httpSubscriber
|
||||||
|
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
subscribers map[string][]*HttpSubscriber
|
subscribers map[string][]*httpSubscriber
|
||||||
running bool
|
running bool
|
||||||
exit chan chan error
|
exit chan chan error
|
||||||
}
|
}
|
||||||
|
|
||||||
type HttpSubscriber struct {
|
type httpSubscriber struct {
|
||||||
id string
|
id string
|
||||||
topic string
|
topic string
|
||||||
ch chan *HttpSubscriber
|
ch chan *httpSubscriber
|
||||||
fn func(*Message)
|
fn func(*Message)
|
||||||
svc registry.Service
|
svc registry.Service
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
SubPath = "/_sub"
|
DefaultSubPath = "/_sub"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *HttpSubscriber) Topic() string {
|
func newHttpBroker(addrs []string, opt ...Option) Broker {
|
||||||
|
addr := ":0"
|
||||||
|
if len(addrs) > 0 {
|
||||||
|
addr = addrs[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
return &httpBroker{
|
||||||
|
id: Id,
|
||||||
|
address: addr,
|
||||||
|
subscribers: make(map[string][]*httpSubscriber),
|
||||||
|
unsubscribe: make(chan *httpSubscriber),
|
||||||
|
exit: make(chan chan error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *httpSubscriber) Topic() string {
|
||||||
return h.topic
|
return h.topic
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HttpSubscriber) Unsubscribe() error {
|
func (h *httpSubscriber) Unsubscribe() error {
|
||||||
h.ch <- h
|
h.ch <- h
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HttpBroker) start() error {
|
func (h *httpBroker) start() error {
|
||||||
h.Lock()
|
h.Lock()
|
||||||
defer h.Unlock()
|
defer h.Unlock()
|
||||||
|
|
||||||
@ -87,7 +102,7 @@ func (h *HttpBroker) start() error {
|
|||||||
h.stop()
|
h.stop()
|
||||||
case subscriber := <-h.unsubscribe:
|
case subscriber := <-h.unsubscribe:
|
||||||
h.Lock()
|
h.Lock()
|
||||||
var subscribers []*HttpSubscriber
|
var subscribers []*httpSubscriber
|
||||||
for _, sub := range h.subscribers[subscriber.topic] {
|
for _, sub := range h.subscribers[subscriber.topic] {
|
||||||
if sub.id == subscriber.id {
|
if sub.id == subscriber.id {
|
||||||
registry.Deregister(sub.svc)
|
registry.Deregister(sub.svc)
|
||||||
@ -104,13 +119,13 @@ func (h *HttpBroker) start() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HttpBroker) stop() error {
|
func (h *httpBroker) stop() error {
|
||||||
ch := make(chan error)
|
ch := make(chan error)
|
||||||
h.exit <- ch
|
h.exit <- ch
|
||||||
return <-ch
|
return <-ch
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HttpBroker) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
func (h *httpBroker) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
if req.Method != "POST" {
|
if req.Method != "POST" {
|
||||||
err := errors.BadRequest("go.micro.broker", "Method not allowed")
|
err := errors.BadRequest("go.micro.broker", "Method not allowed")
|
||||||
http.Error(w, err.Error(), http.StatusMethodNotAllowed)
|
http.Error(w, err.Error(), http.StatusMethodNotAllowed)
|
||||||
@ -148,28 +163,28 @@ func (h *HttpBroker) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
h.RUnlock()
|
h.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HttpBroker) Address() string {
|
func (h *httpBroker) Address() string {
|
||||||
return h.address
|
return h.address
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HttpBroker) Connect() error {
|
func (h *httpBroker) Connect() error {
|
||||||
return h.start()
|
return h.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HttpBroker) Disconnect() error {
|
func (h *httpBroker) Disconnect() error {
|
||||||
return h.stop()
|
return h.stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HttpBroker) Init() error {
|
func (h *httpBroker) Init() error {
|
||||||
if len(h.id) == 0 {
|
if len(h.id) == 0 {
|
||||||
h.id = "broker-" + uuid.NewUUID().String()
|
h.id = "broker-" + uuid.NewUUID().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
http.Handle(SubPath, h)
|
http.Handle(DefaultSubPath, h)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HttpBroker) Publish(topic string, data []byte) error {
|
func (h *httpBroker) Publish(topic string, data []byte) error {
|
||||||
s, err := registry.GetService("topic:" + topic)
|
s, err := registry.GetService("topic:" + topic)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -186,7 +201,7 @@ func (h *HttpBroker) Publish(topic string, data []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, node := range s.Nodes() {
|
for _, node := range s.Nodes() {
|
||||||
r, err := http.Post(fmt.Sprintf("http://%s:%d%s", node.Address(), node.Port(), SubPath), "application/json", bytes.NewBuffer(b))
|
r, err := http.Post(fmt.Sprintf("http://%s:%d%s", node.Address(), node.Port(), DefaultSubPath), "application/json", bytes.NewBuffer(b))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
r.Body.Close()
|
r.Body.Close()
|
||||||
}
|
}
|
||||||
@ -195,7 +210,7 @@ func (h *HttpBroker) Publish(topic string, data []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HttpBroker) Subscribe(topic string, function func(*Message)) (Subscriber, error) {
|
func (h *httpBroker) Subscribe(topic string, function func(*Message)) (Subscriber, error) {
|
||||||
// parse address for host, port
|
// parse address for host, port
|
||||||
parts := strings.Split(h.Address(), ":")
|
parts := strings.Split(h.Address(), ":")
|
||||||
host := strings.Join(parts[:len(parts)-1], ":")
|
host := strings.Join(parts[:len(parts)-1], ":")
|
||||||
@ -205,7 +220,7 @@ func (h *HttpBroker) Subscribe(topic string, function func(*Message)) (Subscribe
|
|||||||
node := registry.NewNode(h.id, host, port)
|
node := registry.NewNode(h.id, host, port)
|
||||||
service := registry.NewService("topic:"+topic, node)
|
service := registry.NewService("topic:"+topic, node)
|
||||||
|
|
||||||
subscriber := &HttpSubscriber{
|
subscriber := &httpSubscriber{
|
||||||
id: uuid.NewUUID().String(),
|
id: uuid.NewUUID().String(),
|
||||||
topic: topic,
|
topic: topic,
|
||||||
ch: h.unsubscribe,
|
ch: h.unsubscribe,
|
||||||
@ -224,18 +239,3 @@ func (h *HttpBroker) Subscribe(topic string, function func(*Message)) (Subscribe
|
|||||||
|
|
||||||
return subscriber, nil
|
return subscriber, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHttpBroker(addrs []string, opts ...Options) Broker {
|
|
||||||
addr := ":0"
|
|
||||||
if len(addrs) > 0 {
|
|
||||||
addr = addrs[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
return &HttpBroker{
|
|
||||||
id: Id,
|
|
||||||
address: addr,
|
|
||||||
subscribers: make(map[string][]*HttpSubscriber),
|
|
||||||
unsubscribe: make(chan *HttpSubscriber),
|
|
||||||
exit: make(chan chan error),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package broker
|
package nats
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@ -7,33 +7,34 @@ import (
|
|||||||
|
|
||||||
"code.google.com/p/go-uuid/uuid"
|
"code.google.com/p/go-uuid/uuid"
|
||||||
"github.com/apcera/nats"
|
"github.com/apcera/nats"
|
||||||
|
"github.com/myodc/go-micro/broker"
|
||||||
)
|
)
|
||||||
|
|
||||||
type NatsBroker struct {
|
type nbroker struct {
|
||||||
addrs []string
|
addrs []string
|
||||||
conn *nats.Conn
|
conn *nats.Conn
|
||||||
}
|
}
|
||||||
|
|
||||||
type NatsSubscriber struct {
|
type subscriber struct {
|
||||||
s *nats.Subscription
|
s *nats.Subscription
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NatsSubscriber) Topic() string {
|
func (n *subscriber) Topic() string {
|
||||||
return n.s.Subject
|
return n.s.Subject
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NatsSubscriber) Unsubscribe() error {
|
func (n *subscriber) Unsubscribe() error {
|
||||||
return n.s.Unsubscribe()
|
return n.s.Unsubscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NatsBroker) Address() string {
|
func (n *nbroker) Address() string {
|
||||||
if len(n.addrs) > 0 {
|
if len(n.addrs) > 0 {
|
||||||
return n.addrs[0]
|
return n.addrs[0]
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NatsBroker) Connect() error {
|
func (n *nbroker) Connect() error {
|
||||||
if n.conn != nil {
|
if n.conn != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -48,17 +49,17 @@ func (n *NatsBroker) Connect() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NatsBroker) Disconnect() error {
|
func (n *nbroker) Disconnect() error {
|
||||||
n.conn.Close()
|
n.conn.Close()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NatsBroker) Init() error {
|
func (n *nbroker) Init() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NatsBroker) Publish(topic string, data []byte) error {
|
func (n *nbroker) Publish(topic string, data []byte) error {
|
||||||
b, err := json.Marshal(&Message{
|
b, err := json.Marshal(&broker.Message{
|
||||||
Id: uuid.NewUUID().String(),
|
Id: uuid.NewUUID().String(),
|
||||||
Timestamp: time.Now().Unix(),
|
Timestamp: time.Now().Unix(),
|
||||||
Topic: topic,
|
Topic: topic,
|
||||||
@ -70,9 +71,9 @@ func (n *NatsBroker) Publish(topic string, data []byte) error {
|
|||||||
return n.conn.Publish(topic, b)
|
return n.conn.Publish(topic, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NatsBroker) Subscribe(topic string, function func(*Message)) (Subscriber, error) {
|
func (n *nbroker) Subscribe(topic string, function func(*broker.Message)) (broker.Subscriber, error) {
|
||||||
subscriber, err := n.conn.Subscribe(topic, func(msg *nats.Msg) {
|
sub, err := n.conn.Subscribe(topic, func(msg *nats.Msg) {
|
||||||
var data *Message
|
var data *broker.Message
|
||||||
if err := json.Unmarshal(msg.Data, &data); err != nil {
|
if err := json.Unmarshal(msg.Data, &data); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -81,10 +82,10 @@ func (n *NatsBroker) Subscribe(topic string, function func(*Message)) (Subscribe
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &NatsSubscriber{s: subscriber}, nil
|
return &subscriber{s: sub}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNatsBroker(addrs []string, opts ...Options) Broker {
|
func NewBroker(addrs []string, opt ...broker.Option) broker.Broker {
|
||||||
var cAddrs []string
|
var cAddrs []string
|
||||||
for _, addr := range addrs {
|
for _, addr := range addrs {
|
||||||
if len(addr) == 0 {
|
if len(addr) == 0 {
|
||||||
@ -98,7 +99,7 @@ func NewNatsBroker(addrs []string, opts ...Options) Broker {
|
|||||||
if len(cAddrs) == 0 {
|
if len(cAddrs) == 0 {
|
||||||
cAddrs = []string{nats.DefaultURL}
|
cAddrs = []string{nats.DefaultURL}
|
||||||
}
|
}
|
||||||
return &NatsBroker{
|
return &nbroker{
|
||||||
addrs: cAddrs,
|
addrs: cAddrs,
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -37,7 +37,7 @@ func CallRemote(ctx context.Context, address string, request Request, response i
|
|||||||
return DefaultClient.CallRemote(ctx, address, request, response)
|
return DefaultClient.CallRemote(ctx, address, request, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(opt ...Option) Client {
|
func NewClient(opt ...Option) Client {
|
||||||
return newRpcClient(opt...)
|
return newRpcClient(opt...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
43
cmd/cmd.go
43
cmd/cmd.go
@ -14,6 +14,25 @@ import (
|
|||||||
"github.com/myodc/go-micro/server"
|
"github.com/myodc/go-micro/server"
|
||||||
"github.com/myodc/go-micro/store"
|
"github.com/myodc/go-micro/store"
|
||||||
"github.com/myodc/go-micro/transport"
|
"github.com/myodc/go-micro/transport"
|
||||||
|
|
||||||
|
// brokers
|
||||||
|
"github.com/myodc/go-micro/broker/http"
|
||||||
|
"github.com/myodc/go-micro/broker/nats"
|
||||||
|
|
||||||
|
// registries
|
||||||
|
"github.com/myodc/go-micro/registry/consul"
|
||||||
|
"github.com/myodc/go-micro/registry/kubernetes"
|
||||||
|
|
||||||
|
// stores
|
||||||
|
sconsul "github.com/myodc/go-micro/store/consul"
|
||||||
|
"github.com/myodc/go-micro/store/etcd"
|
||||||
|
"github.com/myodc/go-micro/store/memcached"
|
||||||
|
"github.com/myodc/go-micro/store/memory"
|
||||||
|
|
||||||
|
// transport
|
||||||
|
thttp "github.com/myodc/go-micro/transport/http"
|
||||||
|
tnats "github.com/myodc/go-micro/transport/nats"
|
||||||
|
"github.com/myodc/go-micro/transport/rabbitmq"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -78,43 +97,45 @@ func Setup(c *cli.Context) error {
|
|||||||
|
|
||||||
switch c.String("broker") {
|
switch c.String("broker") {
|
||||||
case "http":
|
case "http":
|
||||||
broker.DefaultBroker = broker.NewHttpBroker(bAddrs)
|
broker.DefaultBroker = http.NewBroker(bAddrs)
|
||||||
case "nats":
|
case "nats":
|
||||||
broker.DefaultBroker = broker.NewNatsBroker(bAddrs)
|
broker.DefaultBroker = nats.NewBroker(bAddrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
rAddrs := strings.Split(c.String("registry_address"), ",")
|
rAddrs := strings.Split(c.String("registry_address"), ",")
|
||||||
|
|
||||||
switch c.String("registry") {
|
switch c.String("registry") {
|
||||||
case "kubernetes":
|
case "kubernetes":
|
||||||
registry.DefaultRegistry = registry.NewKubernetesRegistry(rAddrs)
|
registry.DefaultRegistry = kubernetes.NewRegistry(rAddrs)
|
||||||
case "consul":
|
case "consul":
|
||||||
registry.DefaultRegistry = registry.NewConsulRegistry(rAddrs)
|
registry.DefaultRegistry = consul.NewRegistry(rAddrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
sAddrs := strings.Split(c.String("store_address"), ",")
|
sAddrs := strings.Split(c.String("store_address"), ",")
|
||||||
|
|
||||||
switch c.String("store") {
|
switch c.String("store") {
|
||||||
|
case "consul":
|
||||||
|
store.DefaultStore = sconsul.NewStore(sAddrs)
|
||||||
case "memcached":
|
case "memcached":
|
||||||
store.DefaultStore = store.NewMemcacheStore(sAddrs)
|
store.DefaultStore = memcached.NewStore(sAddrs)
|
||||||
case "memory":
|
case "memory":
|
||||||
store.DefaultStore = store.NewMemoryStore(sAddrs)
|
store.DefaultStore = memory.NewStore(sAddrs)
|
||||||
case "etcd":
|
case "etcd":
|
||||||
store.DefaultStore = store.NewEtcdStore(sAddrs)
|
store.DefaultStore = etcd.NewStore(sAddrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
tAddrs := strings.Split(c.String("transport_address"), ",")
|
tAddrs := strings.Split(c.String("transport_address"), ",")
|
||||||
|
|
||||||
switch c.String("transport") {
|
switch c.String("transport") {
|
||||||
case "http":
|
case "http":
|
||||||
transport.DefaultTransport = transport.NewHttpTransport(tAddrs)
|
transport.DefaultTransport = thttp.NewTransport(tAddrs)
|
||||||
case "rabbitmq":
|
case "rabbitmq":
|
||||||
transport.DefaultTransport = transport.NewRabbitMQTransport(tAddrs)
|
transport.DefaultTransport = rabbitmq.NewTransport(tAddrs)
|
||||||
case "nats":
|
case "nats":
|
||||||
transport.DefaultTransport = transport.NewNatsTransport(tAddrs)
|
transport.DefaultTransport = tnats.NewTransport(tAddrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
client.DefaultClient = client.New()
|
client.DefaultClient = client.NewClient()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
11
registry/consul/consul.go
Normal file
11
registry/consul/consul.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package consul
|
||||||
|
|
||||||
|
// This is a hack
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/myodc/go-micro/registry"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewRegistry(addrs []string, opt ...registry.Option) registry.Registry {
|
||||||
|
return registry.NewRegistry(addrs, opt...)
|
||||||
|
}
|
@ -1,20 +1,20 @@
|
|||||||
package registry
|
package registry
|
||||||
|
|
||||||
type ConsulNode struct {
|
type consulNode struct {
|
||||||
Node string
|
Node string
|
||||||
NodeId string
|
NodeId string
|
||||||
NodeAddress string
|
NodeAddress string
|
||||||
NodePort int
|
NodePort int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConsulNode) Id() string {
|
func (c *consulNode) Id() string {
|
||||||
return c.NodeId
|
return c.NodeId
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConsulNode) Address() string {
|
func (c *consulNode) Address() string {
|
||||||
return c.NodeAddress
|
return c.NodeAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConsulNode) Port() int {
|
func (c *consulNode) Port() int {
|
||||||
return c.NodePort
|
return c.NodePort
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
consul "github.com/hashicorp/consul/api"
|
consul "github.com/hashicorp/consul/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ConsulRegistry struct {
|
type consulRegistry struct {
|
||||||
Address string
|
Address string
|
||||||
Client *consul.Client
|
Client *consul.Client
|
||||||
|
|
||||||
@ -15,7 +15,24 @@ type ConsulRegistry struct {
|
|||||||
services map[string]Service
|
services map[string]Service
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConsulRegistry) Deregister(s Service) error {
|
func newConsulRegistry(addrs []string, opts ...Option) Registry {
|
||||||
|
config := consul.DefaultConfig()
|
||||||
|
client, _ := consul.NewClient(config)
|
||||||
|
if len(addrs) > 0 {
|
||||||
|
config.Address = addrs[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
cr := &consulRegistry{
|
||||||
|
Address: config.Address,
|
||||||
|
Client: client,
|
||||||
|
services: make(map[string]Service),
|
||||||
|
}
|
||||||
|
|
||||||
|
cr.Watch()
|
||||||
|
return cr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *consulRegistry) Deregister(s Service) error {
|
||||||
if len(s.Nodes()) == 0 {
|
if len(s.Nodes()) == 0 {
|
||||||
return errors.New("Require at least one node")
|
return errors.New("Require at least one node")
|
||||||
}
|
}
|
||||||
@ -31,7 +48,7 @@ func (c *ConsulRegistry) Deregister(s Service) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConsulRegistry) Register(s Service) error {
|
func (c *consulRegistry) Register(s Service) error {
|
||||||
if len(s.Nodes()) == 0 {
|
if len(s.Nodes()) == 0 {
|
||||||
return errors.New("Require at least one node")
|
return errors.New("Require at least one node")
|
||||||
}
|
}
|
||||||
@ -51,7 +68,7 @@ func (c *ConsulRegistry) Register(s Service) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConsulRegistry) GetService(name string) (Service, error) {
|
func (c *consulRegistry) GetService(name string) (Service, error) {
|
||||||
c.mtx.RLock()
|
c.mtx.RLock()
|
||||||
service, ok := c.services[name]
|
service, ok := c.services[name]
|
||||||
c.mtx.RUnlock()
|
c.mtx.RUnlock()
|
||||||
@ -65,7 +82,7 @@ func (c *ConsulRegistry) GetService(name string) (Service, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cs := &ConsulService{}
|
cs := &consulService{}
|
||||||
|
|
||||||
for _, s := range rsp {
|
for _, s := range rsp {
|
||||||
if s.ServiceName != name {
|
if s.ServiceName != name {
|
||||||
@ -73,7 +90,7 @@ func (c *ConsulRegistry) GetService(name string) (Service, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cs.ServiceName = s.ServiceName
|
cs.ServiceName = s.ServiceName
|
||||||
cs.ServiceNodes = append(cs.ServiceNodes, &ConsulNode{
|
cs.ServiceNodes = append(cs.ServiceNodes, &consulNode{
|
||||||
Node: s.Node,
|
Node: s.Node,
|
||||||
NodeId: s.ServiceID,
|
NodeId: s.ServiceID,
|
||||||
NodeAddress: s.Address,
|
NodeAddress: s.Address,
|
||||||
@ -84,7 +101,7 @@ func (c *ConsulRegistry) GetService(name string) (Service, error) {
|
|||||||
return cs, nil
|
return cs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConsulRegistry) ListServices() ([]Service, error) {
|
func (c *consulRegistry) ListServices() ([]Service, error) {
|
||||||
c.mtx.RLock()
|
c.mtx.RLock()
|
||||||
serviceMap := c.services
|
serviceMap := c.services
|
||||||
c.mtx.RUnlock()
|
c.mtx.RUnlock()
|
||||||
@ -104,29 +121,29 @@ func (c *ConsulRegistry) ListServices() ([]Service, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for service, _ := range rsp {
|
for service, _ := range rsp {
|
||||||
services = append(services, &ConsulService{ServiceName: service})
|
services = append(services, &consulService{ServiceName: service})
|
||||||
}
|
}
|
||||||
|
|
||||||
return services, nil
|
return services, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConsulRegistry) NewService(name string, nodes ...Node) Service {
|
func (c *consulRegistry) NewService(name string, nodes ...Node) Service {
|
||||||
var snodes []*ConsulNode
|
var snodes []*consulNode
|
||||||
|
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
if n, ok := node.(*ConsulNode); ok {
|
if n, ok := node.(*consulNode); ok {
|
||||||
snodes = append(snodes, n)
|
snodes = append(snodes, n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ConsulService{
|
return &consulService{
|
||||||
ServiceName: name,
|
ServiceName: name,
|
||||||
ServiceNodes: snodes,
|
ServiceNodes: snodes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConsulRegistry) NewNode(id, address string, port int) Node {
|
func (c *consulRegistry) NewNode(id, address string, port int) Node {
|
||||||
return &ConsulNode{
|
return &consulNode{
|
||||||
Node: id,
|
Node: id,
|
||||||
NodeId: id,
|
NodeId: id,
|
||||||
NodeAddress: address,
|
NodeAddress: address,
|
||||||
@ -134,23 +151,6 @@ func (c *ConsulRegistry) NewNode(id, address string, port int) Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConsulRegistry) Watch() {
|
func (c *consulRegistry) Watch() {
|
||||||
NewConsulWatcher(c)
|
newConsulWatcher(c)
|
||||||
}
|
|
||||||
|
|
||||||
func NewConsulRegistry(addrs []string, opts ...Options) Registry {
|
|
||||||
config := consul.DefaultConfig()
|
|
||||||
client, _ := consul.NewClient(config)
|
|
||||||
if len(addrs) > 0 {
|
|
||||||
config.Address = addrs[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
cr := &ConsulRegistry{
|
|
||||||
Address: config.Address,
|
|
||||||
Client: client,
|
|
||||||
services: make(map[string]Service),
|
|
||||||
}
|
|
||||||
|
|
||||||
cr.Watch()
|
|
||||||
return cr
|
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
package registry
|
package registry
|
||||||
|
|
||||||
type ConsulService struct {
|
type consulService struct {
|
||||||
ServiceName string
|
ServiceName string
|
||||||
ServiceNodes []*ConsulNode
|
ServiceNodes []*consulNode
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConsulService) Name() string {
|
func (c *consulService) Name() string {
|
||||||
return c.ServiceName
|
return c.ServiceName
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConsulService) Nodes() []Node {
|
func (c *consulService) Nodes() []Node {
|
||||||
var nodes []Node
|
var nodes []Node
|
||||||
|
|
||||||
for _, node := range c.ServiceNodes {
|
for _, node := range c.ServiceNodes {
|
||||||
|
@ -5,8 +5,8 @@ import (
|
|||||||
"github.com/hashicorp/consul/watch"
|
"github.com/hashicorp/consul/watch"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ConsulWatcher struct {
|
type consulWatcher struct {
|
||||||
Registry *ConsulRegistry
|
Registry *consulRegistry
|
||||||
wp *watch.WatchPlan
|
wp *watch.WatchPlan
|
||||||
watchers map[string]*watch.WatchPlan
|
watchers map[string]*watch.WatchPlan
|
||||||
}
|
}
|
||||||
@ -15,17 +15,33 @@ type serviceWatcher struct {
|
|||||||
name string
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cw *ConsulWatcher) serviceHandler(idx uint64, data interface{}) {
|
func newConsulWatcher(cr *consulRegistry) *consulWatcher {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
return cw
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cw *consulWatcher) serviceHandler(idx uint64, data interface{}) {
|
||||||
entries, ok := data.([]*api.ServiceEntry)
|
entries, ok := data.([]*api.ServiceEntry)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cs := &ConsulService{}
|
cs := &consulService{}
|
||||||
|
|
||||||
for _, e := range entries {
|
for _, e := range entries {
|
||||||
cs.ServiceName = e.Service.Service
|
cs.ServiceName = e.Service.Service
|
||||||
cs.ServiceNodes = append(cs.ServiceNodes, &ConsulNode{
|
cs.ServiceNodes = append(cs.ServiceNodes, &consulNode{
|
||||||
Node: e.Node.Node,
|
Node: e.Node.Node,
|
||||||
NodeId: e.Service.ID,
|
NodeId: e.Service.ID,
|
||||||
NodeAddress: e.Node.Address,
|
NodeAddress: e.Node.Address,
|
||||||
@ -38,7 +54,7 @@ func (cw *ConsulWatcher) serviceHandler(idx uint64, data interface{}) {
|
|||||||
cw.Registry.mtx.Unlock()
|
cw.Registry.mtx.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cw *ConsulWatcher) Handle(idx uint64, data interface{}) {
|
func (cw *consulWatcher) Handle(idx uint64, data interface{}) {
|
||||||
services, ok := data.(map[string][]string)
|
services, ok := data.(map[string][]string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
@ -82,25 +98,9 @@ func (cw *ConsulWatcher) Handle(idx uint64, data interface{}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cw *ConsulWatcher) Stop() {
|
func (cw *consulWatcher) Stop() {
|
||||||
if cw.wp == nil {
|
if cw.wp == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cw.wp.Stop()
|
cw.wp.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConsulWatcher(cr *ConsulRegistry) *ConsulWatcher {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
return cw
|
|
||||||
}
|
|
||||||
|
139
registry/kubernetes/kubernetes.go
Normal file
139
registry/kubernetes/kubernetes.go
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
package kubernetes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/myodc/go-micro/registry"
|
||||||
|
|
||||||
|
k8s "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
||||||
|
)
|
||||||
|
|
||||||
|
type kregistry struct {
|
||||||
|
client *k8s.Client
|
||||||
|
namespace string
|
||||||
|
|
||||||
|
mtx sync.RWMutex
|
||||||
|
services map[string]registry.Service
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *kregistry) Watch() {
|
||||||
|
newWatcher(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *kregistry) Deregister(s registry.Service) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *kregistry) Register(s registry.Service) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *kregistry) GetService(name string) (registry.Service, error) {
|
||||||
|
c.mtx.RLock()
|
||||||
|
svc, ok := c.services[name]
|
||||||
|
c.mtx.RUnlock()
|
||||||
|
|
||||||
|
if ok {
|
||||||
|
return svc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
selector := labels.SelectorFromSet(labels.Set{"name": name})
|
||||||
|
|
||||||
|
services, err := c.client.Services(c.namespace).List(selector)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(services.Items) == 0 {
|
||||||
|
return nil, fmt.Errorf("Service not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
ks := &service{name: name}
|
||||||
|
for _, item := range services.Items {
|
||||||
|
ks.nodes = append(ks.nodes, &node{
|
||||||
|
address: item.Spec.PortalIP,
|
||||||
|
port: item.Spec.Ports[0].Port,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return ks, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *kregistry) ListServices() ([]registry.Service, error) {
|
||||||
|
c.mtx.RLock()
|
||||||
|
serviceMap := c.services
|
||||||
|
c.mtx.RUnlock()
|
||||||
|
|
||||||
|
var services []registry.Service
|
||||||
|
|
||||||
|
if len(serviceMap) > 0 {
|
||||||
|
for _, service := range serviceMap {
|
||||||
|
services = append(services, service)
|
||||||
|
}
|
||||||
|
return services, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
rsp, err := c.client.Services(c.namespace).List(labels.Everything())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, svc := range rsp.Items {
|
||||||
|
if len(svc.ObjectMeta.Labels["name"]) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
services = append(services, &service{
|
||||||
|
name: svc.ObjectMeta.Labels["name"],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return services, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *kregistry) NewService(name string, nodes ...registry.Node) registry.Service {
|
||||||
|
var snodes []*node
|
||||||
|
|
||||||
|
for _, nod := range nodes {
|
||||||
|
if n, ok := nod.(*node); ok {
|
||||||
|
snodes = append(snodes, n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &service{
|
||||||
|
name: name,
|
||||||
|
nodes: snodes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *kregistry) NewNode(id, address string, port int) registry.Node {
|
||||||
|
return &node{
|
||||||
|
id: id,
|
||||||
|
address: address,
|
||||||
|
port: port,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
host = addrs[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
client, _ := k8s.New(&k8s.Config{
|
||||||
|
Host: host,
|
||||||
|
})
|
||||||
|
|
||||||
|
kr := &kregistry{
|
||||||
|
client: client,
|
||||||
|
namespace: "default",
|
||||||
|
services: make(map[string]registry.Service),
|
||||||
|
}
|
||||||
|
|
||||||
|
kr.Watch()
|
||||||
|
|
||||||
|
return kr
|
||||||
|
}
|
19
registry/kubernetes/node.go
Normal file
19
registry/kubernetes/node.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package kubernetes
|
||||||
|
|
||||||
|
type node struct {
|
||||||
|
id string
|
||||||
|
address string
|
||||||
|
port int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *node) Id() string {
|
||||||
|
return n.id
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *node) Address() string {
|
||||||
|
return n.address
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *node) Port() int {
|
||||||
|
return n.port
|
||||||
|
}
|
24
registry/kubernetes/service.go
Normal file
24
registry/kubernetes/service.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package kubernetes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/myodc/go-micro/registry"
|
||||||
|
)
|
||||||
|
|
||||||
|
type service struct {
|
||||||
|
name string
|
||||||
|
nodes []*node
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Name() string {
|
||||||
|
return s.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) Nodes() []registry.Node {
|
||||||
|
var nodes []registry.Node
|
||||||
|
|
||||||
|
for _, node := range s.nodes {
|
||||||
|
nodes = append(nodes, node)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodes
|
||||||
|
}
|
72
registry/kubernetes/watcher.go
Normal file
72
registry/kubernetes/watcher.go
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
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"
|
||||||
|
)
|
||||||
|
|
||||||
|
type watcher struct {
|
||||||
|
registry *kregistry
|
||||||
|
}
|
||||||
|
|
||||||
|
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.PortalIP)
|
||||||
|
|
||||||
|
ks := &service{
|
||||||
|
name: name,
|
||||||
|
nodes: []*node{
|
||||||
|
&node{
|
||||||
|
address: serviceIP.String(),
|
||||||
|
port: svc.Spec.Ports[0].Port,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
k.registry.mtx.Lock()
|
||||||
|
k.registry.services[name] = ks
|
||||||
|
k.registry.mtx.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
k.registry.mtx.Lock()
|
||||||
|
defer k.registry.mtx.Unlock()
|
||||||
|
for name, _ := range k.registry.services {
|
||||||
|
if !activeServices.Has(name) {
|
||||||
|
delete(k.registry.services, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newWatcher(kr *kregistry) *watcher {
|
||||||
|
serviceConfig := config.NewServiceConfig()
|
||||||
|
endpointsConfig := config.NewEndpointsConfig()
|
||||||
|
|
||||||
|
config.NewSourceAPI(
|
||||||
|
kr.client.Services(api.NamespaceAll),
|
||||||
|
kr.client.Endpoints(api.NamespaceAll),
|
||||||
|
time.Second*10,
|
||||||
|
serviceConfig.Channel("api"),
|
||||||
|
endpointsConfig.Channel("api"),
|
||||||
|
)
|
||||||
|
|
||||||
|
ks := &watcher{
|
||||||
|
registry: kr,
|
||||||
|
}
|
||||||
|
|
||||||
|
serviceConfig.RegisterHandler(ks)
|
||||||
|
return ks
|
||||||
|
}
|
@ -1,19 +0,0 @@
|
|||||||
package registry
|
|
||||||
|
|
||||||
type KubernetesNode struct {
|
|
||||||
NodeId string
|
|
||||||
NodeAddress string
|
|
||||||
NodePort int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *KubernetesNode) Id() string {
|
|
||||||
return c.NodeId
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *KubernetesNode) Address() string {
|
|
||||||
return c.NodeAddress
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *KubernetesNode) Port() int {
|
|
||||||
return c.NodePort
|
|
||||||
}
|
|
@ -1,137 +0,0 @@
|
|||||||
package registry
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
k8s "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
|
|
||||||
)
|
|
||||||
|
|
||||||
type KubernetesRegistry struct {
|
|
||||||
Client *k8s.Client
|
|
||||||
Namespace string
|
|
||||||
|
|
||||||
mtx sync.RWMutex
|
|
||||||
services map[string]Service
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *KubernetesRegistry) Watch() {
|
|
||||||
NewKubernetesWatcher(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *KubernetesRegistry) Deregister(s Service) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *KubernetesRegistry) Register(s Service) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *KubernetesRegistry) GetService(name string) (Service, error) {
|
|
||||||
c.mtx.RLock()
|
|
||||||
service, ok := c.services[name]
|
|
||||||
c.mtx.RUnlock()
|
|
||||||
|
|
||||||
if ok {
|
|
||||||
return service, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
selector := labels.SelectorFromSet(labels.Set{"name": name})
|
|
||||||
|
|
||||||
services, err := c.Client.Services(c.Namespace).List(selector)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(services.Items) == 0 {
|
|
||||||
return nil, fmt.Errorf("Service not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
ks := &KubernetesService{ServiceName: name}
|
|
||||||
for _, item := range services.Items {
|
|
||||||
ks.ServiceNodes = append(ks.ServiceNodes, &KubernetesNode{
|
|
||||||
NodeAddress: item.Spec.PortalIP,
|
|
||||||
NodePort: item.Spec.Ports[0].Port,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return ks, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *KubernetesRegistry) ListServices() ([]Service, error) {
|
|
||||||
c.mtx.RLock()
|
|
||||||
serviceMap := c.services
|
|
||||||
c.mtx.RUnlock()
|
|
||||||
|
|
||||||
var services []Service
|
|
||||||
|
|
||||||
if len(serviceMap) > 0 {
|
|
||||||
for _, service := range serviceMap {
|
|
||||||
services = append(services, service)
|
|
||||||
}
|
|
||||||
return services, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
rsp, err := c.Client.Services(c.Namespace).List(labels.Everything())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, service := range rsp.Items {
|
|
||||||
if len(service.ObjectMeta.Labels["name"]) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
services = append(services, &KubernetesService{
|
|
||||||
ServiceName: service.ObjectMeta.Labels["name"],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return services, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *KubernetesRegistry) NewService(name string, nodes ...Node) Service {
|
|
||||||
var snodes []*KubernetesNode
|
|
||||||
|
|
||||||
for _, node := range nodes {
|
|
||||||
if n, ok := node.(*KubernetesNode); ok {
|
|
||||||
snodes = append(snodes, n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &KubernetesService{
|
|
||||||
ServiceName: name,
|
|
||||||
ServiceNodes: snodes,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *KubernetesRegistry) NewNode(id, address string, port int) Node {
|
|
||||||
return &KubernetesNode{
|
|
||||||
NodeId: id,
|
|
||||||
NodeAddress: address,
|
|
||||||
NodePort: port,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewKubernetesRegistry(addrs []string, opts ...Options) Registry {
|
|
||||||
host := "http://" + os.Getenv("KUBERNETES_RO_SERVICE_HOST") + ":" + os.Getenv("KUBERNETES_RO_SERVICE_PORT")
|
|
||||||
if len(addrs) > 0 {
|
|
||||||
host = addrs[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
client, _ := k8s.New(&k8s.Config{
|
|
||||||
Host: host,
|
|
||||||
})
|
|
||||||
|
|
||||||
kr := &KubernetesRegistry{
|
|
||||||
Client: client,
|
|
||||||
Namespace: "default",
|
|
||||||
services: make(map[string]Service),
|
|
||||||
}
|
|
||||||
|
|
||||||
kr.Watch()
|
|
||||||
|
|
||||||
return kr
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
package registry
|
|
||||||
|
|
||||||
type KubernetesService struct {
|
|
||||||
ServiceName string
|
|
||||||
ServiceNodes []*KubernetesNode
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *KubernetesService) Name() string {
|
|
||||||
return c.ServiceName
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *KubernetesService) Nodes() []Node {
|
|
||||||
var nodes []Node
|
|
||||||
|
|
||||||
for _, node := range c.ServiceNodes {
|
|
||||||
nodes = append(nodes, node)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nodes
|
|
||||||
}
|
|
@ -1,72 +0,0 @@
|
|||||||
package registry
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/proxy/config"
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
|
||||||
)
|
|
||||||
|
|
||||||
type KubernetesWatcher struct {
|
|
||||||
Registry *KubernetesRegistry
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *KubernetesWatcher) OnUpdate(services []api.Service) {
|
|
||||||
fmt.Println("got update")
|
|
||||||
activeServices := util.StringSet{}
|
|
||||||
for _, service := range services {
|
|
||||||
fmt.Printf("%#v\n", service.ObjectMeta)
|
|
||||||
name, exists := service.ObjectMeta.Labels["name"]
|
|
||||||
if !exists {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
activeServices.Insert(name)
|
|
||||||
serviceIP := net.ParseIP(service.Spec.PortalIP)
|
|
||||||
|
|
||||||
ks := &KubernetesService{
|
|
||||||
ServiceName: name,
|
|
||||||
ServiceNodes: []*KubernetesNode{
|
|
||||||
&KubernetesNode{
|
|
||||||
NodeAddress: serviceIP.String(),
|
|
||||||
NodePort: service.Spec.Ports[0].Port,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
k.Registry.mtx.Lock()
|
|
||||||
k.Registry.services[name] = ks
|
|
||||||
k.Registry.mtx.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
k.Registry.mtx.Lock()
|
|
||||||
defer k.Registry.mtx.Unlock()
|
|
||||||
for name, _ := range k.Registry.services {
|
|
||||||
if !activeServices.Has(name) {
|
|
||||||
delete(k.Registry.services, name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewKubernetesWatcher(kr *KubernetesRegistry) *KubernetesWatcher {
|
|
||||||
serviceConfig := config.NewServiceConfig()
|
|
||||||
endpointsConfig := config.NewEndpointsConfig()
|
|
||||||
|
|
||||||
config.NewSourceAPI(
|
|
||||||
kr.Client.Services(api.NamespaceAll),
|
|
||||||
kr.Client.Endpoints(api.NamespaceAll),
|
|
||||||
time.Second*10,
|
|
||||||
serviceConfig.Channel("api"),
|
|
||||||
endpointsConfig.Channel("api"),
|
|
||||||
)
|
|
||||||
|
|
||||||
ks := &KubernetesWatcher{
|
|
||||||
Registry: kr,
|
|
||||||
}
|
|
||||||
|
|
||||||
serviceConfig.RegisterHandler(ks)
|
|
||||||
return ks
|
|
||||||
}
|
|
@ -11,12 +11,16 @@ type Registry interface {
|
|||||||
|
|
||||||
type options struct{}
|
type options struct{}
|
||||||
|
|
||||||
type Options func(*options)
|
type Option func(*options)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
DefaultRegistry = NewConsulRegistry([]string{})
|
DefaultRegistry = newConsulRegistry([]string{})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func NewRegistry(addrs []string, opt ...Option) Registry {
|
||||||
|
return newConsulRegistry(addrs, opt...)
|
||||||
|
}
|
||||||
|
|
||||||
func Register(s Service) error {
|
func Register(s Service) error {
|
||||||
return DefaultRegistry.Register(s)
|
return DefaultRegistry.Register(s)
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ func Init() error {
|
|||||||
return DefaultServer.Init()
|
return DefaultServer.Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(address string, opt ...Option) Server {
|
func NewServer(address string, opt ...Option) Server {
|
||||||
return newRpcServer(address, opt...)
|
return newRpcServer(address, opt...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
store/consul/consul.go
Normal file
11
store/consul/consul.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package consul
|
||||||
|
|
||||||
|
// This is a hack
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/myodc/go-micro/store"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewStore(addrs []string, opt ...store.Option) store.Store {
|
||||||
|
return store.NewStore(addrs, opt...)
|
||||||
|
}
|
@ -1,14 +1,14 @@
|
|||||||
package store
|
package store
|
||||||
|
|
||||||
type ConsulItem struct {
|
type consulItem struct {
|
||||||
key string
|
key string
|
||||||
value []byte
|
value []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConsulItem) Key() string {
|
func (c *consulItem) Key() string {
|
||||||
return c.key
|
return c.key
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConsulItem) Value() []byte {
|
func (c *consulItem) Value() []byte {
|
||||||
return c.value
|
return c.value
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,11 @@ import (
|
|||||||
consul "github.com/hashicorp/consul/api"
|
consul "github.com/hashicorp/consul/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ConsulStore struct {
|
type consulStore struct {
|
||||||
Client *consul.Client
|
Client *consul.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConsulStore) Get(key string) (Item, error) {
|
func (c *consulStore) Get(key string) (Item, error) {
|
||||||
kv, _, err := c.Client.KV().Get(key, nil)
|
kv, _, err := c.Client.KV().Get(key, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -19,18 +19,18 @@ func (c *ConsulStore) Get(key string) (Item, error) {
|
|||||||
return nil, errors.New("key not found")
|
return nil, errors.New("key not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ConsulItem{
|
return &consulItem{
|
||||||
key: kv.Key,
|
key: kv.Key,
|
||||||
value: kv.Value,
|
value: kv.Value,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConsulStore) Del(key string) error {
|
func (c *consulStore) Del(key string) error {
|
||||||
_, err := c.Client.KV().Delete(key, nil)
|
_, err := c.Client.KV().Delete(key, nil)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConsulStore) Put(item Item) error {
|
func (c *consulStore) Put(item Item) error {
|
||||||
_, err := c.Client.KV().Put(&consul.KVPair{
|
_, err := c.Client.KV().Put(&consul.KVPair{
|
||||||
Key: item.Key(),
|
Key: item.Key(),
|
||||||
Value: item.Value(),
|
Value: item.Value(),
|
||||||
@ -39,14 +39,14 @@ func (c *ConsulStore) Put(item Item) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ConsulStore) NewItem(key string, value []byte) Item {
|
func (c *consulStore) NewItem(key string, value []byte) Item {
|
||||||
return &ConsulItem{
|
return &consulItem{
|
||||||
key: key,
|
key: key,
|
||||||
value: value,
|
value: value,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConsulStore(addrs []string, opts ...Options) Store {
|
func newConsulStore(addrs []string, opt ...Option) Store {
|
||||||
config := consul.DefaultConfig()
|
config := consul.DefaultConfig()
|
||||||
if len(addrs) > 0 {
|
if len(addrs) > 0 {
|
||||||
config.Address = addrs[0]
|
config.Address = addrs[0]
|
||||||
@ -54,7 +54,7 @@ func NewConsulStore(addrs []string, opts ...Options) Store {
|
|||||||
|
|
||||||
client, _ := consul.NewClient(config)
|
client, _ := consul.NewClient(config)
|
||||||
|
|
||||||
return &ConsulStore{
|
return &consulStore{
|
||||||
Client: client,
|
Client: client,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,30 @@
|
|||||||
package store
|
package etcd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/coreos/go-etcd/etcd"
|
"github.com/coreos/go-etcd/etcd"
|
||||||
|
"github.com/myodc/go-micro/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type EtcdStore struct {
|
type estore struct {
|
||||||
Client *etcd.Client
|
Client *etcd.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *EtcdStore) Get(key string) (Item, error) {
|
type item struct {
|
||||||
|
key string
|
||||||
|
value []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *item) Key() string {
|
||||||
|
return i.key
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *item) Value() []byte {
|
||||||
|
return i.value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *estore) Get(key string) (store.Item, error) {
|
||||||
kv, err := e.Client.Get(key, false, false)
|
kv, err := e.Client.Get(key, false, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -19,38 +33,38 @@ func (e *EtcdStore) Get(key string) (Item, error) {
|
|||||||
return nil, errors.New("key not found")
|
return nil, errors.New("key not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &EtcdItem{
|
return &item{
|
||||||
key: kv.Node.Key,
|
key: kv.Node.Key,
|
||||||
value: []byte(kv.Node.Value),
|
value: []byte(kv.Node.Value),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *EtcdStore) Del(key string) error {
|
func (e *estore) Del(key string) error {
|
||||||
_, err := e.Client.Delete(key, false)
|
_, err := e.Client.Delete(key, false)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *EtcdStore) Put(item Item) error {
|
func (e *estore) Put(item store.Item) error {
|
||||||
_, err := e.Client.Set(item.Key(), string(item.Value()), 0)
|
_, err := e.Client.Set(item.Key(), string(item.Value()), 0)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *EtcdStore) NewItem(key string, value []byte) Item {
|
func (e *estore) NewItem(key string, value []byte) store.Item {
|
||||||
return &EtcdItem{
|
return &item{
|
||||||
key: key,
|
key: key,
|
||||||
value: value,
|
value: value,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEtcdStore(addrs []string, opts ...Options) Store {
|
func NewStore(addrs []string, opts ...store.Option) store.Store {
|
||||||
if len(addrs) == 0 {
|
if len(addrs) == 0 {
|
||||||
addrs = []string{"127.0.0.1:2379"}
|
addrs = []string{"127.0.0.1:2379"}
|
||||||
}
|
}
|
||||||
|
|
||||||
client := etcd.NewClient(addrs)
|
client := etcd.NewClient(addrs)
|
||||||
|
|
||||||
return &EtcdStore{
|
return &estore{
|
||||||
Client: client,
|
Client: client,
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,14 +0,0 @@
|
|||||||
package store
|
|
||||||
|
|
||||||
type EtcdItem struct {
|
|
||||||
key string
|
|
||||||
value []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *EtcdItem) Key() string {
|
|
||||||
return c.key
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *EtcdItem) Value() []byte {
|
|
||||||
return c.value
|
|
||||||
}
|
|
@ -1,16 +1,30 @@
|
|||||||
package store
|
package memcached
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
mc "github.com/bradfitz/gomemcache/memcache"
|
mc "github.com/bradfitz/gomemcache/memcache"
|
||||||
|
"github.com/myodc/go-micro/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MemcacheStore struct {
|
type mstore struct {
|
||||||
Client *mc.Client
|
Client *mc.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MemcacheStore) Get(key string) (Item, error) {
|
type item struct {
|
||||||
|
key string
|
||||||
|
value []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *item) Key() string {
|
||||||
|
return i.key
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *item) Value() []byte {
|
||||||
|
return i.value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mstore) Get(key string) (store.Item, error) {
|
||||||
kv, err := m.Client.Get(key)
|
kv, err := m.Client.Get(key)
|
||||||
if err != nil && err == mc.ErrCacheMiss {
|
if err != nil && err == mc.ErrCacheMiss {
|
||||||
return nil, errors.New("key not found")
|
return nil, errors.New("key not found")
|
||||||
@ -22,35 +36,35 @@ func (m *MemcacheStore) Get(key string) (Item, error) {
|
|||||||
return nil, errors.New("key not found")
|
return nil, errors.New("key not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &MemcacheItem{
|
return &item{
|
||||||
key: kv.Key,
|
key: kv.Key,
|
||||||
value: kv.Value,
|
value: kv.Value,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MemcacheStore) Del(key string) error {
|
func (m *mstore) Del(key string) error {
|
||||||
return m.Client.Delete(key)
|
return m.Client.Delete(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MemcacheStore) Put(item Item) error {
|
func (m *mstore) Put(item store.Item) error {
|
||||||
return m.Client.Set(&mc.Item{
|
return m.Client.Set(&mc.Item{
|
||||||
Key: item.Key(),
|
Key: item.Key(),
|
||||||
Value: item.Value(),
|
Value: item.Value(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MemcacheStore) NewItem(key string, value []byte) Item {
|
func (m *mstore) NewItem(key string, value []byte) store.Item {
|
||||||
return &MemcacheItem{
|
return &item{
|
||||||
key: key,
|
key: key,
|
||||||
value: value,
|
value: value,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMemcacheStore(addrs []string, opts ...Options) Store {
|
func NewStore(addrs []string, opts ...store.Option) store.Store {
|
||||||
if len(addrs) == 0 {
|
if len(addrs) == 0 {
|
||||||
addrs = []string{"127.0.0.1:11211"}
|
addrs = []string{"127.0.0.1:11211"}
|
||||||
}
|
}
|
||||||
return &MemcacheStore{
|
return &mstore{
|
||||||
Client: mc.New(addrs...),
|
Client: mc.New(addrs...),
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,14 +0,0 @@
|
|||||||
package store
|
|
||||||
|
|
||||||
type MemcacheItem struct {
|
|
||||||
key string
|
|
||||||
value []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MemcacheItem) Key() string {
|
|
||||||
return m.key
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MemcacheItem) Value() []byte {
|
|
||||||
return m.value
|
|
||||||
}
|
|
63
store/memory/memory.go
Normal file
63
store/memory/memory.go
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package memory
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/myodc/go-micro/store"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mstore struct {
|
||||||
|
sync.RWMutex
|
||||||
|
store map[string]store.Item
|
||||||
|
}
|
||||||
|
|
||||||
|
type item struct {
|
||||||
|
key string
|
||||||
|
value []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *item) Key() string {
|
||||||
|
return i.key
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *item) Value() []byte {
|
||||||
|
return i.value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mstore) Get(key string) (store.Item, error) {
|
||||||
|
m.RLock()
|
||||||
|
v, ok := m.store[key]
|
||||||
|
m.RUnlock()
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("key not found")
|
||||||
|
}
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mstore) Del(key string) error {
|
||||||
|
m.Lock()
|
||||||
|
delete(m.store, key)
|
||||||
|
m.Unlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mstore) Put(item store.Item) error {
|
||||||
|
m.Lock()
|
||||||
|
m.store[item.Key()] = item
|
||||||
|
m.Unlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mstore) NewItem(key string, value []byte) store.Item {
|
||||||
|
return &item{
|
||||||
|
key: key,
|
||||||
|
value: value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStore(addrs []string, opt ...store.Option) store.Store {
|
||||||
|
return &mstore{
|
||||||
|
store: make(map[string]store.Item),
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +0,0 @@
|
|||||||
package store
|
|
||||||
|
|
||||||
type MemoryItem struct {
|
|
||||||
key string
|
|
||||||
value []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MemoryItem) Key() string {
|
|
||||||
return m.key
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MemoryItem) Value() []byte {
|
|
||||||
return m.value
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
package store
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MemoryStore struct {
|
|
||||||
sync.RWMutex
|
|
||||||
store map[string]Item
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MemoryStore) Get(key string) (Item, error) {
|
|
||||||
m.RLock()
|
|
||||||
v, ok := m.store[key]
|
|
||||||
m.RUnlock()
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("key not found")
|
|
||||||
}
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MemoryStore) Del(key string) error {
|
|
||||||
m.Lock()
|
|
||||||
delete(m.store, key)
|
|
||||||
m.Unlock()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MemoryStore) Put(item Item) error {
|
|
||||||
m.Lock()
|
|
||||||
m.store[item.Key()] = item
|
|
||||||
m.Unlock()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *MemoryStore) NewItem(key string, value []byte) Item {
|
|
||||||
return &MemoryItem{
|
|
||||||
key: key,
|
|
||||||
value: value,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewMemoryStore(addrs []string, opts ...Options) Store {
|
|
||||||
return &MemoryStore{
|
|
||||||
store: make(map[string]Item),
|
|
||||||
}
|
|
||||||
}
|
|
@ -9,12 +9,16 @@ type Store interface {
|
|||||||
|
|
||||||
type options struct{}
|
type options struct{}
|
||||||
|
|
||||||
type Options func(*options)
|
type Option func(*options)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
DefaultStore = NewConsulStore([]string{})
|
DefaultStore = newConsulStore([]string{})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func NewStore(addrs []string, opt ...Option) Store {
|
||||||
|
return newConsulStore(addrs, opt...)
|
||||||
|
}
|
||||||
|
|
||||||
func Get(key string) (Item, error) {
|
func Get(key string) (Item, error) {
|
||||||
return DefaultStore.Get(key)
|
return DefaultStore.Get(key)
|
||||||
}
|
}
|
||||||
|
11
transport/http/http.go
Normal file
11
transport/http/http.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package http
|
||||||
|
|
||||||
|
// This is a hack
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/myodc/go-micro/transport"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewTransport(addrs []string, opt ...transport.Option) transport.Transport {
|
||||||
|
return transport.NewTransport(addrs, opt...)
|
||||||
|
}
|
@ -13,21 +13,21 @@ type headerRoundTripper struct {
|
|||||||
r http.RoundTripper
|
r http.RoundTripper
|
||||||
}
|
}
|
||||||
|
|
||||||
type HttpTransport struct {
|
type httpTransport struct {
|
||||||
client *http.Client
|
client *http.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
type HttpTransportClient struct {
|
type httpTransportClient struct {
|
||||||
ht *HttpTransport
|
ht *httpTransport
|
||||||
addr string
|
addr string
|
||||||
}
|
}
|
||||||
|
|
||||||
type HttpTransportSocket struct {
|
type httpTransportSocket struct {
|
||||||
r *http.Request
|
r *http.Request
|
||||||
w http.ResponseWriter
|
w http.ResponseWriter
|
||||||
}
|
}
|
||||||
|
|
||||||
type HttpTransportListener struct {
|
type httpTransportListener struct {
|
||||||
listener net.Listener
|
listener net.Listener
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ func (t *headerRoundTripper) RoundTrip(r *http.Request) (*http.Response, error)
|
|||||||
return t.r.RoundTrip(r)
|
return t.r.RoundTrip(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HttpTransportClient) Send(m *Message) (*Message, error) {
|
func (h *httpTransportClient) Send(m *Message) (*Message, error) {
|
||||||
header := make(http.Header)
|
header := make(http.Header)
|
||||||
|
|
||||||
for k, v := range m.Header {
|
for k, v := range m.Header {
|
||||||
@ -88,11 +88,11 @@ func (h *HttpTransportClient) Send(m *Message) (*Message, error) {
|
|||||||
return mr, nil
|
return mr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HttpTransportClient) Close() error {
|
func (h *httpTransportClient) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HttpTransportSocket) Recv(m *Message) error {
|
func (h *httpTransportSocket) Recv(m *Message) error {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return errors.New("message passed in is nil")
|
return errors.New("message passed in is nil")
|
||||||
}
|
}
|
||||||
@ -119,7 +119,7 @@ func (h *HttpTransportSocket) Recv(m *Message) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HttpTransportSocket) Send(m *Message) error {
|
func (h *httpTransportSocket) Send(m *Message) error {
|
||||||
for k, v := range m.Header {
|
for k, v := range m.Header {
|
||||||
h.w.Header().Set(k, v)
|
h.w.Header().Set(k, v)
|
||||||
}
|
}
|
||||||
@ -128,22 +128,22 @@ func (h *HttpTransportSocket) Send(m *Message) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HttpTransportSocket) Close() error {
|
func (h *httpTransportSocket) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HttpTransportListener) Addr() string {
|
func (h *httpTransportListener) Addr() string {
|
||||||
return h.listener.Addr().String()
|
return h.listener.Addr().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HttpTransportListener) Close() error {
|
func (h *httpTransportListener) Close() error {
|
||||||
return h.listener.Close()
|
return h.listener.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HttpTransportListener) Accept(fn func(Socket)) error {
|
func (h *httpTransportListener) Accept(fn func(Socket)) error {
|
||||||
srv := &http.Server{
|
srv := &http.Server{
|
||||||
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
fn(&HttpTransportSocket{
|
fn(&httpTransportSocket{
|
||||||
r: r,
|
r: r,
|
||||||
w: w,
|
w: w,
|
||||||
})
|
})
|
||||||
@ -153,27 +153,27 @@ func (h *HttpTransportListener) Accept(fn func(Socket)) error {
|
|||||||
return srv.Serve(h.listener)
|
return srv.Serve(h.listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HttpTransport) Dial(addr string) (Client, error) {
|
func (h *httpTransport) Dial(addr string) (Client, error) {
|
||||||
return &HttpTransportClient{
|
return &httpTransportClient{
|
||||||
ht: h,
|
ht: h,
|
||||||
addr: addr,
|
addr: addr,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HttpTransport) Listen(addr string) (Listener, error) {
|
func (h *httpTransport) Listen(addr string) (Listener, error) {
|
||||||
l, err := net.Listen("tcp", addr)
|
l, err := net.Listen("tcp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &HttpTransportListener{
|
return &httpTransportListener{
|
||||||
listener: l,
|
listener: l,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHttpTransport(addrs []string) *HttpTransport {
|
func newHttpTransport(addrs []string, opt ...Option) *httpTransport {
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
client.Transport = &headerRoundTripper{http.DefaultTransport}
|
client.Transport = &headerRoundTripper{http.DefaultTransport}
|
||||||
|
|
||||||
return &HttpTransport{client: client}
|
return &httpTransport{client: client}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package transport
|
package nats
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@ -7,29 +7,30 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/apcera/nats"
|
"github.com/apcera/nats"
|
||||||
|
"github.com/myodc/go-micro/transport"
|
||||||
)
|
)
|
||||||
|
|
||||||
type NatsTransport struct {
|
type ntport struct {
|
||||||
addrs []string
|
addrs []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type NatsTransportClient struct {
|
type ntportClient struct {
|
||||||
conn *nats.Conn
|
conn *nats.Conn
|
||||||
addr string
|
addr string
|
||||||
}
|
}
|
||||||
|
|
||||||
type NatsTransportSocket struct {
|
type ntportSocket struct {
|
||||||
conn *nats.Conn
|
conn *nats.Conn
|
||||||
m *nats.Msg
|
m *nats.Msg
|
||||||
}
|
}
|
||||||
|
|
||||||
type NatsTransportListener struct {
|
type ntportListener struct {
|
||||||
conn *nats.Conn
|
conn *nats.Conn
|
||||||
addr string
|
addr string
|
||||||
exit chan bool
|
exit chan bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NatsTransportClient) Send(m *Message) (*Message, error) {
|
func (n *ntportClient) Send(m *transport.Message) (*transport.Message, error) {
|
||||||
b, err := json.Marshal(m)
|
b, err := json.Marshal(m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -40,7 +41,7 @@ func (n *NatsTransportClient) Send(m *Message) (*Message, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var mr *Message
|
var mr *transport.Message
|
||||||
if err := json.Unmarshal(rsp.Data, &mr); err != nil {
|
if err := json.Unmarshal(rsp.Data, &mr); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -48,12 +49,12 @@ func (n *NatsTransportClient) Send(m *Message) (*Message, error) {
|
|||||||
return mr, nil
|
return mr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NatsTransportClient) Close() error {
|
func (n *ntportClient) Close() error {
|
||||||
n.conn.Close()
|
n.conn.Close()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NatsTransportSocket) Recv(m *Message) error {
|
func (n *ntportSocket) Recv(m *transport.Message) error {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return errors.New("message passed in is nil")
|
return errors.New("message passed in is nil")
|
||||||
}
|
}
|
||||||
@ -64,7 +65,7 @@ func (n *NatsTransportSocket) Recv(m *Message) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NatsTransportSocket) Send(m *Message) error {
|
func (n *ntportSocket) Send(m *transport.Message) error {
|
||||||
b, err := json.Marshal(m)
|
b, err := json.Marshal(m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -72,23 +73,23 @@ func (n *NatsTransportSocket) Send(m *Message) error {
|
|||||||
return n.conn.Publish(n.m.Reply, b)
|
return n.conn.Publish(n.m.Reply, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NatsTransportSocket) Close() error {
|
func (n *ntportSocket) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NatsTransportListener) Addr() string {
|
func (n *ntportListener) Addr() string {
|
||||||
return n.addr
|
return n.addr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NatsTransportListener) Close() error {
|
func (n *ntportListener) Close() error {
|
||||||
n.exit <- true
|
n.exit <- true
|
||||||
n.conn.Close()
|
n.conn.Close()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NatsTransportListener) Accept(fn func(Socket)) error {
|
func (n *ntportListener) Accept(fn func(transport.Socket)) error {
|
||||||
s, err := n.conn.Subscribe(n.addr, func(m *nats.Msg) {
|
s, err := n.conn.Subscribe(n.addr, func(m *nats.Msg) {
|
||||||
fn(&NatsTransportSocket{
|
fn(&ntportSocket{
|
||||||
conn: n.conn,
|
conn: n.conn,
|
||||||
m: m,
|
m: m,
|
||||||
})
|
})
|
||||||
@ -101,7 +102,7 @@ func (n *NatsTransportListener) Accept(fn func(Socket)) error {
|
|||||||
return s.Unsubscribe()
|
return s.Unsubscribe()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NatsTransport) Dial(addr string) (Client, error) {
|
func (n *ntport) Dial(addr string) (transport.Client, error) {
|
||||||
cAddr := nats.DefaultURL
|
cAddr := nats.DefaultURL
|
||||||
|
|
||||||
if len(n.addrs) > 0 && strings.HasPrefix(n.addrs[0], "nats://") {
|
if len(n.addrs) > 0 && strings.HasPrefix(n.addrs[0], "nats://") {
|
||||||
@ -113,13 +114,13 @@ func (n *NatsTransport) Dial(addr string) (Client, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &NatsTransportClient{
|
return &ntportClient{
|
||||||
conn: c,
|
conn: c,
|
||||||
addr: addr,
|
addr: addr,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *NatsTransport) Listen(addr string) (Listener, error) {
|
func (n *ntport) Listen(addr string) (transport.Listener, error) {
|
||||||
cAddr := nats.DefaultURL
|
cAddr := nats.DefaultURL
|
||||||
|
|
||||||
if len(n.addrs) > 0 && strings.HasPrefix(n.addrs[0], "nats://") {
|
if len(n.addrs) > 0 && strings.HasPrefix(n.addrs[0], "nats://") {
|
||||||
@ -131,15 +132,15 @@ func (n *NatsTransport) Listen(addr string) (Listener, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &NatsTransportListener{
|
return &ntportListener{
|
||||||
addr: nats.NewInbox(),
|
addr: nats.NewInbox(),
|
||||||
conn: c,
|
conn: c,
|
||||||
exit: make(chan bool, 1),
|
exit: make(chan bool, 1),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNatsTransport(addrs []string) *NatsTransport {
|
func NewTransport(addrs []string, opt ...transport.Option) transport.Transport {
|
||||||
return &NatsTransport{
|
return &ntport{
|
||||||
addrs: addrs,
|
addrs: addrs,
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package transport
|
package rabbitmq
|
||||||
|
|
||||||
//
|
//
|
||||||
// All credit to Mondo
|
// All credit to Mondo
|
@ -1,4 +1,4 @@
|
|||||||
package transport
|
package rabbitmq
|
||||||
|
|
||||||
//
|
//
|
||||||
// All credit to Mondo
|
// All credit to Mondo
|
@ -1,4 +1,4 @@
|
|||||||
package transport
|
package rabbitmq
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -8,16 +8,18 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
uuid "github.com/nu7hatch/gouuid"
|
uuid "github.com/nu7hatch/gouuid"
|
||||||
"github.com/streadway/amqp"
|
"github.com/streadway/amqp"
|
||||||
|
|
||||||
|
"github.com/myodc/go-micro/transport"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RabbitMQTransport struct {
|
type rmqtport struct {
|
||||||
conn *rabbitMQConn
|
conn *rabbitMQConn
|
||||||
addrs []string
|
addrs []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type RabbitMQTransportClient struct {
|
type rmqtportClient struct {
|
||||||
once sync.Once
|
once sync.Once
|
||||||
rt *RabbitMQTransport
|
rt *rmqtport
|
||||||
addr string
|
addr string
|
||||||
replyTo string
|
replyTo string
|
||||||
|
|
||||||
@ -25,17 +27,17 @@ type RabbitMQTransportClient struct {
|
|||||||
inflight map[string]chan amqp.Delivery
|
inflight map[string]chan amqp.Delivery
|
||||||
}
|
}
|
||||||
|
|
||||||
type RabbitMQTransportSocket struct {
|
type rmqtportSocket struct {
|
||||||
conn *rabbitMQConn
|
conn *rabbitMQConn
|
||||||
d *amqp.Delivery
|
d *amqp.Delivery
|
||||||
}
|
}
|
||||||
|
|
||||||
type RabbitMQTransportListener struct {
|
type rmqtportListener struct {
|
||||||
conn *rabbitMQConn
|
conn *rabbitMQConn
|
||||||
addr string
|
addr string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RabbitMQTransportClient) init() {
|
func (r *rmqtportClient) init() {
|
||||||
<-r.rt.conn.Init()
|
<-r.rt.conn.Init()
|
||||||
if err := r.rt.conn.Channel.DeclareReplyQueue(r.replyTo); err != nil {
|
if err := r.rt.conn.Channel.DeclareReplyQueue(r.replyTo); err != nil {
|
||||||
return
|
return
|
||||||
@ -51,7 +53,7 @@ func (r *RabbitMQTransportClient) init() {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RabbitMQTransportClient) handle(delivery amqp.Delivery) {
|
func (r *rmqtportClient) handle(delivery amqp.Delivery) {
|
||||||
ch := r.getReq(delivery.CorrelationId)
|
ch := r.getReq(delivery.CorrelationId)
|
||||||
if ch == nil {
|
if ch == nil {
|
||||||
return
|
return
|
||||||
@ -62,7 +64,7 @@ func (r *RabbitMQTransportClient) handle(delivery amqp.Delivery) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RabbitMQTransportClient) putReq(id string) chan amqp.Delivery {
|
func (r *rmqtportClient) putReq(id string) chan amqp.Delivery {
|
||||||
r.Lock()
|
r.Lock()
|
||||||
ch := make(chan amqp.Delivery, 1)
|
ch := make(chan amqp.Delivery, 1)
|
||||||
r.inflight[id] = ch
|
r.inflight[id] = ch
|
||||||
@ -70,7 +72,7 @@ func (r *RabbitMQTransportClient) putReq(id string) chan amqp.Delivery {
|
|||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RabbitMQTransportClient) getReq(id string) chan amqp.Delivery {
|
func (r *rmqtportClient) getReq(id string) chan amqp.Delivery {
|
||||||
r.Lock()
|
r.Lock()
|
||||||
defer r.Unlock()
|
defer r.Unlock()
|
||||||
if ch, ok := r.inflight[id]; ok {
|
if ch, ok := r.inflight[id]; ok {
|
||||||
@ -80,7 +82,7 @@ func (r *RabbitMQTransportClient) getReq(id string) chan amqp.Delivery {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RabbitMQTransportClient) Send(m *Message) (*Message, error) {
|
func (r *rmqtportClient) Send(m *transport.Message) (*transport.Message, error) {
|
||||||
r.once.Do(r.init)
|
r.once.Do(r.init)
|
||||||
|
|
||||||
if !r.rt.conn.IsConnected() {
|
if !r.rt.conn.IsConnected() {
|
||||||
@ -115,7 +117,7 @@ func (r *RabbitMQTransportClient) Send(m *Message) (*Message, error) {
|
|||||||
|
|
||||||
select {
|
select {
|
||||||
case d := <-replyChan:
|
case d := <-replyChan:
|
||||||
mr := &Message{
|
mr := &transport.Message{
|
||||||
Header: make(map[string]string),
|
Header: make(map[string]string),
|
||||||
Body: d.Body,
|
Body: d.Body,
|
||||||
}
|
}
|
||||||
@ -130,16 +132,16 @@ func (r *RabbitMQTransportClient) Send(m *Message) (*Message, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RabbitMQTransportClient) Close() error {
|
func (r *rmqtportClient) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RabbitMQTransportSocket) Recv(m *Message) error {
|
func (r *rmqtportSocket) Recv(m *transport.Message) error {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return errors.New("message passed in is nil")
|
return errors.New("message passed in is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
mr := &Message{
|
mr := &transport.Message{
|
||||||
Header: make(map[string]string),
|
Header: make(map[string]string),
|
||||||
Body: r.d.Body,
|
Body: r.d.Body,
|
||||||
}
|
}
|
||||||
@ -152,7 +154,7 @@ func (r *RabbitMQTransportSocket) Recv(m *Message) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RabbitMQTransportSocket) Send(m *Message) error {
|
func (r *rmqtportSocket) Send(m *transport.Message) error {
|
||||||
msg := amqp.Publishing{
|
msg := amqp.Publishing{
|
||||||
CorrelationId: r.d.CorrelationId,
|
CorrelationId: r.d.CorrelationId,
|
||||||
Timestamp: time.Now().UTC(),
|
Timestamp: time.Now().UTC(),
|
||||||
@ -167,27 +169,27 @@ func (r *RabbitMQTransportSocket) Send(m *Message) error {
|
|||||||
return r.conn.Publish("", r.d.ReplyTo, msg)
|
return r.conn.Publish("", r.d.ReplyTo, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RabbitMQTransportSocket) Close() error {
|
func (r *rmqtportSocket) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RabbitMQTransportListener) Addr() string {
|
func (r *rmqtportListener) Addr() string {
|
||||||
return r.addr
|
return r.addr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RabbitMQTransportListener) Close() error {
|
func (r *rmqtportListener) Close() error {
|
||||||
r.conn.Close()
|
r.conn.Close()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RabbitMQTransportListener) Accept(fn func(Socket)) error {
|
func (r *rmqtportListener) Accept(fn func(transport.Socket)) error {
|
||||||
deliveries, err := r.conn.Consume(r.addr)
|
deliveries, err := r.conn.Consume(r.addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
handler := func(d amqp.Delivery) {
|
handler := func(d amqp.Delivery) {
|
||||||
fn(&RabbitMQTransportSocket{
|
fn(&rmqtportSocket{
|
||||||
d: &d,
|
d: &d,
|
||||||
conn: r.conn,
|
conn: r.conn,
|
||||||
})
|
})
|
||||||
@ -200,13 +202,13 @@ func (r *RabbitMQTransportListener) Accept(fn func(Socket)) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RabbitMQTransport) Dial(addr string) (Client, error) {
|
func (r *rmqtport) Dial(addr string) (transport.Client, error) {
|
||||||
id, err := uuid.NewV4()
|
id, err := uuid.NewV4()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &RabbitMQTransportClient{
|
return &rmqtportClient{
|
||||||
rt: r,
|
rt: r,
|
||||||
addr: addr,
|
addr: addr,
|
||||||
inflight: make(map[string]chan amqp.Delivery),
|
inflight: make(map[string]chan amqp.Delivery),
|
||||||
@ -214,7 +216,7 @@ func (r *RabbitMQTransport) Dial(addr string) (Client, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RabbitMQTransport) Listen(addr string) (Listener, error) {
|
func (r *rmqtport) Listen(addr string) (transport.Listener, error) {
|
||||||
id, err := uuid.NewV4()
|
id, err := uuid.NewV4()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -223,14 +225,14 @@ func (r *RabbitMQTransport) Listen(addr string) (Listener, error) {
|
|||||||
conn := newRabbitMQConn("", r.addrs)
|
conn := newRabbitMQConn("", r.addrs)
|
||||||
<-conn.Init()
|
<-conn.Init()
|
||||||
|
|
||||||
return &RabbitMQTransportListener{
|
return &rmqtportListener{
|
||||||
addr: id.String(),
|
addr: id.String(),
|
||||||
conn: conn,
|
conn: conn,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRabbitMQTransport(addrs []string) *RabbitMQTransport {
|
func NewTransport(addrs []string, opt ...transport.Option) transport.Transport {
|
||||||
return &RabbitMQTransport{
|
return &rmqtport{
|
||||||
conn: newRabbitMQConn("", addrs),
|
conn: newRabbitMQConn("", addrs),
|
||||||
addrs: addrs,
|
addrs: addrs,
|
||||||
}
|
}
|
@ -27,10 +27,18 @@ type Transport interface {
|
|||||||
Listen(addr string) (Listener, error)
|
Listen(addr string) (Listener, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type options struct{}
|
||||||
|
|
||||||
|
type Option func(*options)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
DefaultTransport Transport = NewHttpTransport([]string{})
|
DefaultTransport Transport = newHttpTransport([]string{})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func NewTransport(addrs []string, opt ...Option) Transport {
|
||||||
|
return newHttpTransport(addrs, opt...)
|
||||||
|
}
|
||||||
|
|
||||||
func Dial(addr string) (Client, error) {
|
func Dial(addr string) (Client, error) {
|
||||||
return DefaultTransport.Dial(addr)
|
return DefaultTransport.Dial(addr)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user