further transport rework

This commit is contained in:
Asim
2015-05-21 19:24:57 +01:00
parent b555109fbb
commit 9d514f0e60
11 changed files with 209 additions and 137 deletions

View File

@@ -17,8 +17,8 @@ type HttpTransport struct {
}
type HttpTransportClient struct {
client *http.Client
target string
ht *HttpTransport
addr string
}
type HttpTransportSocket struct {
@@ -52,16 +52,16 @@ func (h *HttpTransportClient) Send(m *Message) (*Message, error) {
Method: "POST",
URL: &url.URL{
Scheme: "http",
Host: h.target,
Host: h.addr,
// Path: path,
},
Header: header,
Body: buf,
ContentLength: int64(reqB.Len()),
Host: h.target,
Host: h.addr,
}
rsp, err := h.client.Do(hreq)
rsp, err := h.ht.client.Do(hreq)
if err != nil {
return nil, err
}
@@ -144,14 +144,14 @@ func (h *HttpTransportServer) Serve(fn func(Socket)) error {
return srv.Serve(h.listener)
}
func (h *HttpTransport) NewClient(name, addr string) (Client, error) {
func (h *HttpTransport) NewClient(addr string) (Client, error) {
return &HttpTransportClient{
client: h.client,
target: addr,
ht: h,
addr: addr,
}, nil
}
func (h *HttpTransport) NewServer(name, addr string) (Server, error) {
func (h *HttpTransport) NewServer(addr string) (Server, error) {
l, err := net.Listen("tcp", addr)
if err != nil {
return nil, err

View File

@@ -9,11 +9,13 @@ import (
"github.com/apcera/nats"
)
type NatsTransport struct{}
type NatsTransport struct {
addrs []string
}
type NatsTransportClient struct {
conn *nats.Conn
target string
conn *nats.Conn
addr string
}
type NatsTransportSocket struct {
@@ -24,7 +26,7 @@ type NatsTransportSocket struct {
type NatsTransportServer struct {
conn *nats.Conn
name string
addr string
exit chan bool
}
@@ -34,7 +36,7 @@ func (n *NatsTransportClient) Send(m *Message) (*Message, error) {
return nil, err
}
rsp, err := n.conn.Request(n.target, b, time.Second*10)
rsp, err := n.conn.Request(n.addr, b, time.Second*10)
if err != nil {
return nil, err
}
@@ -72,7 +74,7 @@ func (n *NatsTransportSocket) Write(b []byte) error {
}
func (n *NatsTransportServer) Addr() string {
return "127.0.0.1:4222"
return n.addr
}
func (n *NatsTransportServer) Close() error {
@@ -82,7 +84,7 @@ func (n *NatsTransportServer) Close() error {
}
func (n *NatsTransportServer) Serve(fn func(Socket)) error {
s, err := n.conn.QueueSubscribe(n.name, "queue:"+n.name, func(m *nats.Msg) {
s, err := n.conn.Subscribe(n.addr, func(m *nats.Msg) {
buf := bytes.NewBuffer(nil)
hdr := make(map[string]string)
@@ -113,39 +115,45 @@ func (n *NatsTransportServer) Serve(fn func(Socket)) error {
return s.Unsubscribe()
}
func (n *NatsTransport) NewClient(name, addr string) (Client, error) {
if !strings.HasPrefix(addr, "nats://") {
addr = nats.DefaultURL
func (n *NatsTransport) NewClient(addr string) (Client, error) {
cAddr := nats.DefaultURL
if len(n.addrs) > 0 && strings.HasPrefix(n.addrs[0], "nats://") {
cAddr = n.addrs[0]
}
c, err := nats.Connect(addr)
c, err := nats.Connect(cAddr)
if err != nil {
return nil, err
}
return &NatsTransportClient{
conn: c,
target: name,
conn: c,
addr: addr,
}, nil
}
func (n *NatsTransport) NewServer(name, addr string) (Server, error) {
if !strings.HasPrefix(addr, "nats://") {
addr = nats.DefaultURL
func (n *NatsTransport) NewServer(addr string) (Server, error) {
cAddr := nats.DefaultURL
if len(n.addrs) > 0 && strings.HasPrefix(n.addrs[0], "nats://") {
cAddr = n.addrs[0]
}
c, err := nats.Connect(addr)
c, err := nats.Connect(cAddr)
if err != nil {
return nil, err
}
return &NatsTransportServer{
name: name,
addr: nats.NewInbox(),
conn: c,
exit: make(chan bool, 1),
}, nil
}
func NewNatsTransport(addrs []string) *NatsTransport {
return &NatsTransport{}
return &NatsTransport{
addrs: addrs,
}
}

View File

@@ -2,7 +2,6 @@ package transport
//
// All credit to Mondo
// https://github.com/mondough/typhon
//
import (
@@ -50,11 +49,11 @@ func (r *RabbitChannel) Close() error {
return r.channel.Close()
}
func (r *RabbitChannel) Publish(exchange, routingKey string, message amqp.Publishing) error {
func (r *RabbitChannel) Publish(exchange, key string, message amqp.Publishing) error {
if r.channel == nil {
return errors.New("Channel is nil")
}
return r.channel.Publish(exchange, routingKey, false, false, message)
return r.channel.Publish(exchange, key, false, false, message)
}
func (r *RabbitChannel) DeclareExchange(exchange string) error {

View File

@@ -2,10 +2,10 @@ package transport
//
// All credit to Mondo
// https://github.com/mondough/typhon
//
import (
"strings"
"sync"
"time"
@@ -27,9 +27,9 @@ type RabbitConnection struct {
connected bool
mtx sync.Mutex
closeChan chan struct{}
closed bool
mtx sync.Mutex
close chan bool
closed bool
}
func (r *RabbitConnection) Init() chan bool {
@@ -53,7 +53,7 @@ func (r *RabbitConnection) Connect(connected chan bool) {
case <-notifyClose:
// Spin around and reconnect
r.connected = false
case <-r.closeChan:
case <-r.close:
// Shut down connection
if err := r.Connection.Close(); err != nil {
}
@@ -75,7 +75,7 @@ func (r *RabbitConnection) Close() {
return
}
close(r.closeChan)
close(r.close)
r.closed = true
}
@@ -97,23 +97,23 @@ func (r *RabbitConnection) tryToConnect() error {
return nil
}
func (r *RabbitConnection) Consume(serverName string) (<-chan amqp.Delivery, error) {
func (r *RabbitConnection) Consume(queue string) (<-chan amqp.Delivery, error) {
consumerChannel, err := NewRabbitChannel(r.Connection)
if err != nil {
return nil, err
}
err = consumerChannel.DeclareQueue(serverName)
err = consumerChannel.DeclareQueue(queue)
if err != nil {
return nil, err
}
deliveries, err := consumerChannel.ConsumeQueue(serverName)
deliveries, err := consumerChannel.ConsumeQueue(queue)
if err != nil {
return nil, err
}
err = consumerChannel.BindQueue(serverName, r.exchange)
err = consumerChannel.BindQueue(queue, r.exchange)
if err != nil {
return nil, err
}
@@ -121,12 +121,16 @@ func (r *RabbitConnection) Consume(serverName string) (<-chan amqp.Delivery, err
return deliveries, nil
}
func (r *RabbitConnection) Publish(exchange, routingKey string, msg amqp.Publishing) error {
return r.ExchangeChannel.Publish(exchange, routingKey, msg)
func (r *RabbitConnection) Publish(exchange, key string, msg amqp.Publishing) error {
return r.ExchangeChannel.Publish(exchange, key, msg)
}
func NewRabbitConnection(exchange, url string) *RabbitConnection {
if len(url) == 0 {
func NewRabbitConnection(exchange string, urls []string) *RabbitConnection {
var url string
if len(urls) > 0 && strings.HasPrefix(urls[0], "amqp://") {
url = urls[0]
} else {
url = DefaultRabbitURL
}
@@ -135,9 +139,9 @@ func NewRabbitConnection(exchange, url string) *RabbitConnection {
}
return &RabbitConnection{
exchange: DefaultExchange,
url: DefaultRabbitURL,
notify: make(chan bool, 1),
closeChan: make(chan struct{}),
exchange: exchange,
url: url,
notify: make(chan bool, 1),
close: make(chan bool),
}
}

View File

@@ -12,13 +12,14 @@ import (
)
type RabbitMQTransport struct {
conn *RabbitConnection
conn *RabbitConnection
addrs []string
}
type RabbitMQTransportClient struct {
once sync.Once
conn *RabbitConnection
target string
rt *RabbitMQTransport
addr string
replyTo string
sync.Mutex
@@ -33,27 +34,27 @@ type RabbitMQTransportSocket struct {
type RabbitMQTransportServer struct {
conn *RabbitConnection
name string
addr string
}
func (h *RabbitMQTransportClient) init() {
<-h.conn.Init()
if err := h.conn.Channel.DeclareReplyQueue(h.replyTo); err != nil {
func (r *RabbitMQTransportClient) init() {
<-r.rt.conn.Init()
if err := r.rt.conn.Channel.DeclareReplyQueue(r.replyTo); err != nil {
return
}
deliveries, err := h.conn.Channel.ConsumeQueue(h.replyTo)
deliveries, err := r.rt.conn.Channel.ConsumeQueue(r.replyTo)
if err != nil {
return
}
go func() {
for delivery := range deliveries {
go h.handle(delivery)
go r.handle(delivery)
}
}()
}
func (h *RabbitMQTransportClient) handle(delivery amqp.Delivery) {
ch := h.getReq(delivery.CorrelationId)
func (r *RabbitMQTransportClient) handle(delivery amqp.Delivery) {
ch := r.getReq(delivery.CorrelationId)
if ch == nil {
return
}
@@ -63,28 +64,28 @@ func (h *RabbitMQTransportClient) handle(delivery amqp.Delivery) {
}
}
func (h *RabbitMQTransportClient) putReq(id string) chan amqp.Delivery {
h.Lock()
func (r *RabbitMQTransportClient) putReq(id string) chan amqp.Delivery {
r.Lock()
ch := make(chan amqp.Delivery, 1)
h.inflight[id] = ch
h.Unlock()
r.inflight[id] = ch
r.Unlock()
return ch
}
func (h *RabbitMQTransportClient) getReq(id string) chan amqp.Delivery {
h.Lock()
defer h.Unlock()
if ch, ok := h.inflight[id]; ok {
delete(h.inflight, id)
func (r *RabbitMQTransportClient) getReq(id string) chan amqp.Delivery {
r.Lock()
defer r.Unlock()
if ch, ok := r.inflight[id]; ok {
delete(r.inflight, id)
return ch
}
return nil
}
func (h *RabbitMQTransportClient) Send(m *Message) (*Message, error) {
h.once.Do(h.init)
func (r *RabbitMQTransportClient) Send(m *Message) (*Message, error) {
r.once.Do(r.init)
if !h.conn.IsConnected() {
if !r.rt.conn.IsConnected() {
return nil, errors.New("Not connected to AMQP")
}
@@ -93,7 +94,7 @@ func (h *RabbitMQTransportClient) Send(m *Message) (*Message, error) {
return nil, err
}
replyChan := h.putReq(id.String())
replyChan := r.putReq(id.String())
headers := amqp.Table{}
@@ -105,12 +106,12 @@ func (h *RabbitMQTransportClient) Send(m *Message) (*Message, error) {
CorrelationId: id.String(),
Timestamp: time.Now().UTC(),
Body: m.Body,
ReplyTo: h.replyTo,
ReplyTo: r.replyTo,
Headers: headers,
}
if err := h.conn.Publish("micro", h.target, message); err != nil {
h.getReq(id.String())
if err := r.rt.conn.Publish("micro", r.addr, message); err != nil {
r.getReq(id.String())
return nil, err
}
@@ -131,44 +132,43 @@ func (h *RabbitMQTransportClient) Send(m *Message) (*Message, error) {
}
}
func (h *RabbitMQTransportClient) Close() error {
h.conn.Close()
func (r *RabbitMQTransportClient) Close() error {
return nil
}
func (h *RabbitMQTransportSocket) Recv() (*Message, error) {
func (r *RabbitMQTransportSocket) Recv() (*Message, error) {
m := &Message{
Header: make(map[string]string),
Body: h.d.Body,
Body: r.d.Body,
}
for k, v := range h.d.Headers {
for k, v := range r.d.Headers {
m.Header[k] = fmt.Sprintf("%v", v)
}
return m, nil
}
func (h *RabbitMQTransportSocket) WriteHeader(k string, v string) {
h.hdr[k] = v
func (r *RabbitMQTransportSocket) WriteHeader(k string, v string) {
r.hdr[k] = v
}
func (h *RabbitMQTransportSocket) Write(b []byte) error {
_, err := h.buf.Write(b)
func (r *RabbitMQTransportSocket) Write(b []byte) error {
_, err := r.buf.Write(b)
return err
}
func (h *RabbitMQTransportServer) Addr() string {
return h.conn.Connection.LocalAddr().String()
func (r *RabbitMQTransportServer) Addr() string {
return r.addr
}
func (h *RabbitMQTransportServer) Close() error {
h.conn.Close()
func (r *RabbitMQTransportServer) Close() error {
r.conn.Close()
return nil
}
func (h *RabbitMQTransportServer) Serve(fn func(Socket)) error {
deliveries, err := h.conn.Consume(h.name)
func (r *RabbitMQTransportServer) Serve(fn func(Socket)) error {
deliveries, err := r.conn.Consume(r.addr)
if err != nil {
return err
}
@@ -190,7 +190,7 @@ func (h *RabbitMQTransportServer) Serve(fn func(Socket)) error {
Headers: headers,
}
h.conn.Publish("", d.ReplyTo, msg)
r.conn.Publish("", d.ReplyTo, msg)
buf.Reset()
}
@@ -201,32 +201,38 @@ func (h *RabbitMQTransportServer) Serve(fn func(Socket)) error {
return nil
}
func (h *RabbitMQTransport) NewClient(name, addr string) (Client, error) {
func (r *RabbitMQTransport) NewClient(addr string) (Client, error) {
id, err := uuid.NewV4()
if err != nil {
return nil, err
}
return &RabbitMQTransportClient{
conn: h.conn,
target: name,
rt: r,
addr: addr,
inflight: make(map[string]chan amqp.Delivery),
replyTo: fmt.Sprintf("replyTo-%s", id.String()),
}, nil
}
func (h *RabbitMQTransport) NewServer(name, addr string) (Server, error) {
conn := NewRabbitConnection("", "")
func (r *RabbitMQTransport) NewServer(addr string) (Server, error) {
id, err := uuid.NewV4()
if err != nil {
return nil, err
}
conn := NewRabbitConnection("", r.addrs)
<-conn.Init()
return &RabbitMQTransportServer{
name: name,
addr: id.String(),
conn: conn,
}, nil
}
func NewRabbitMQTransport(addrs []string) *RabbitMQTransport {
return &RabbitMQTransport{
conn: NewRabbitConnection("", ""),
conn: NewRabbitConnection("", addrs),
addrs: addrs,
}
}

View File

@@ -23,18 +23,18 @@ type Server interface {
}
type Transport interface {
NewClient(name, addr string) (Client, error)
NewServer(name, addr string) (Server, error)
NewClient(addr string) (Client, error)
NewServer(addr string) (Server, error)
}
var (
DefaultTransport Transport = NewHttpTransport([]string{})
)
func NewClient(name, addr string) (Client, error) {
return DefaultTransport.NewClient(name, addr)
func NewClient(addr string) (Client, error) {
return DefaultTransport.NewClient(addr)
}
func NewServer(name, addr string) (Server, error) {
return DefaultTransport.NewServer(name, addr)
func NewServer(addr string) (Server, error) {
return DefaultTransport.NewServer(addr)
}