Functional loopback code

This commit is contained in:
Asim Aslam 2019-07-03 19:26:24 +01:00
parent 7008809eff
commit e54de56376
5 changed files with 313 additions and 137 deletions

View File

@ -45,7 +45,7 @@ type network struct {
// lease generates a new lease with a node id/address
// TODO: use a consensus mechanism, pool or some deterministic
// unique addressing method.
func (n *network) lease() *pb.Lease {
func (n *network) lease(muid string) *pb.Lease {
// create the id
id := uuid.New().String()
// create a timestamp
@ -62,6 +62,7 @@ func (n *network) lease() *pb.Lease {
Id: id,
Timestamp: now,
Node: &pb.Node{
Muid: muid,
Id: id,
Address: address,
Network: n.id,

View File

@ -5,24 +5,30 @@ import (
"io"
"sync"
"github.com/micro/go-micro/util/log"
gproto "github.com/golang/protobuf/proto"
"github.com/google/uuid"
"github.com/micro/go-micro/codec"
"github.com/micro/go-micro/codec/proto"
pb "github.com/micro/go-micro/network/proto"
"github.com/micro/go-micro/transport"
"github.com/micro/go-micro/util/log"
)
type link struct {
// the embedded node
*node
closed chan bool
sync.RWMutex
// the link id
id string
// the send queue to the socket
queue chan *Message
sendQueue chan *Message
// the recv queue to the socket
recvQueue chan *Message
// codec we use to marshal things
codec codec.Marshaler
@ -39,16 +45,53 @@ type link struct {
weight int
}
var (
ErrLinkClosed = errors.New("link closed")
)
func newLink(n *node, sock transport.Socket, lease *pb.Lease) *link {
return &link{
id: uuid.New().String(),
closed: make(chan bool),
codec: &proto.Marshaler{},
node: n,
lease: lease,
socket: sock,
sendQueue: make(chan *Message, 128),
recvQueue: make(chan *Message, 128),
}
}
// link methods
// process processe messages on the send queue
// process processes messages on the send queue.
// these are messages to be sent to the remote side.
func (l *link) process() {
for {
select {
case m := <-l.queue:
if err := l.send(m, nil); err != nil {
go func() {
for {
m := new(Message)
if err := l.recv(m, nil); err != nil {
l.Close()
return
}
select {
case l.recvQueue <- m:
log.Debugf("%s processing recv", l.id)
case <-l.closed:
return
}
}
}()
for {
select {
case m := <-l.sendQueue:
if err := l.send(m, nil); err != nil {
l.Close()
return
}
case <-l.closed:
return
}
}
}
@ -71,29 +114,49 @@ func (l *link) accept() error {
switch event {
// connect event
case "Connect":
case "connect":
// process connect events from network.Connect()
// these are new connections to join the network
// decode the connection event
conn := new(pb.Connect)
// expecting a connect message
if err := l.codec.Unmarshal(m.Body, conn); err != nil {
// skip error
continue
}
// no micro id close the link
if len(conn.Muid) == 0 {
l.Close()
return errors.New("invalid muid " + conn.Muid)
}
// get the existing lease if it exists
lease := conn.Lease
// if there's no lease create a new one
if lease == nil {
// create a new lease/node
lease = l.node.network.lease()
lease = l.node.network.lease(conn.Muid)
}
// check if we connected to ourself
if conn.Muid == l.node.muid {
// check our own leasae
l.node.Lock()
if l.node.lease == nil {
l.node.lease = lease
}
l.node.Unlock()
}
// set the author to our own muid
lease.Author = l.node.muid
// send back a lease offer for the node
if err := l.send(&Message{
Header: map[string]string{
"Micro-Method": "Lease",
"Micro-Method": "lease",
},
}, lease); err != nil {
return err
@ -107,11 +170,10 @@ func (l *link) accept() error {
// we've connected
// start processing the messages
go l.process()
return nil
case "Close":
case "close":
l.Close()
return errors.New("connection closed")
return io.EOF
default:
return errors.New("unknown method: " + event)
}
@ -132,9 +194,9 @@ func (l *link) connect() error {
// send a lease request
if err := l.send(&Message{
Header: map[string]string{
"Micro-Method": "Connect",
"Micro-Method": "connect",
},
}, &pb.Connect{Lease: lease}); err != nil {
}, &pb.Connect{Muid: l.node.muid, Lease: lease}); err != nil {
return err
}
@ -151,7 +213,7 @@ func (l *link) connect() error {
// check the method
switch event {
case "Lease":
case "lease":
// save the lease
l.Lock()
l.lease = newLease
@ -159,10 +221,11 @@ func (l *link) connect() error {
// start processing the messages
go l.process()
case "Close":
l.socket.Close()
return errors.New("connection closed")
case "close":
l.Close()
return io.EOF
default:
l.Close()
return errors.New("unable to attain lease")
}
@ -190,13 +253,8 @@ func (l *link) send(m *Message, v interface{}) error {
tm.Body = b
}
log.Debugf("link %s sending %+v %+v\n", l.id, m, v)
// send via the transport socket
return l.socket.Send(&transport.Message{
Header: m.Header,
Body: m.Body,
})
return l.socket.Send(tm)
}
// recv a message on the link
@ -207,12 +265,14 @@ func (l *link) recv(m *Message, v interface{}) error {
tm := new(transport.Message)
log.Debugf("link %s attempting receiving", l.id)
// receive the transport message
if err := l.socket.Recv(tm); err != nil {
return err
}
log.Debugf("link %s receiving %+v %+v\n", l.id, tm, v)
log.Debugf("link %s received %+v %+v\n", l.id, tm, v)
// set the message
m.Header = tm.Header
@ -235,12 +295,20 @@ func (l *link) recv(m *Message, v interface{}) error {
// Close the link
func (l *link) Close() error {
select {
case <-l.closed:
return nil
default:
close(l.closed)
}
// send a final close message
l.socket.Send(&transport.Message{
Header: map[string]string{
"Micro-Method": "Close",
"Micro-Method": "close",
},
})
// close the socket
return l.socket.Close()
}
@ -273,20 +341,27 @@ func (l *link) Length() int {
}
func (l *link) Weight() int {
l.RLock()
defer l.RUnlock()
return l.weight
return len(l.sendQueue) + len(l.recvQueue)
}
// Accept accepts a message on the socket
func (l *link) Accept() (*Message, error) {
m := new(Message)
err := l.recv(m, nil)
if err != nil {
return nil, err
select {
case <-l.closed:
return nil, ErrLinkClosed
case m := <-l.recvQueue:
return m, nil
}
return m, nil
// never reach
return nil, nil
}
// Send sends a message on the socket immediately
func (l *link) Send(m *Message) error {
return l.send(m, nil)
select {
case <-l.closed:
return ErrLinkClosed
case l.sendQueue <- m:
}
return nil
}

View File

@ -5,12 +5,12 @@ import (
"fmt"
"net"
"runtime/debug"
"sort"
"strconv"
"sync"
"time"
"github.com/google/uuid"
"github.com/micro/go-micro/codec/proto"
"github.com/micro/go-micro/registry"
"github.com/micro/go-micro/transport"
"github.com/micro/go-micro/util/addr"
@ -22,17 +22,23 @@ import (
type node struct {
*network
// closed channel
// closed channel to close our connection to the network
closed chan bool
sync.RWMutex
// the node id
// the nodes unique micro assigned mac address
muid string
// the node id registered in registry
id string
// address of this node
// address of this node registered in registry
address string
// our network lease with our network id/address
lease *pb.Lease
// the node registry
registry registry.Registry
@ -42,9 +48,13 @@ type node struct {
// the listener
listener transport.Listener
// connected records
// record.Address:true
connected map[string]bool
// leases for connections to us
// link id:link
links map[string]*link
// link remote node:link
links map[string][]*link
// messages received over links
recv chan *Message
@ -57,8 +67,12 @@ type node struct {
func newNode(n *network) (*node, error) {
// create a new node
node := &node{
// this nodes unique micro assigned mac address
muid: fmt.Sprintf("%s-%s", n.id, uuid.New().String()),
// map of connected records
connected: make(map[string]bool),
// the links
links: make(map[string]*link),
links: make(map[string][]*link),
// closed channel
closed: make(chan bool),
// set the nodes network
@ -113,17 +127,6 @@ func newNode(n *network) (*node, error) {
// forwards to every link we have
go node.process()
// lookup the network to see if there's any nodes
records := n.lookup(node.registry)
// assuming if there are no records, we are the first
// we set ourselves a lease. should we actually do this?
if len(records) == 0 {
// set your own node id
lease := n.lease()
node.id = lease.Node.Id
}
var port int
// TODO: this should be an overlay address
// ideally received via some dhcp style broadcast
@ -140,6 +143,9 @@ func newNode(n *network) (*node, error) {
// set the address
addr, _ := addr.Extract(host)
// used to register in registry for network resolution
// separate to our lease on the network itself
node.id = uuid.New().String()
node.address = fmt.Sprintf("%s:%d", addr, port)
// register self with the registry using network: prefix
@ -169,15 +175,19 @@ func newNode(n *network) (*node, error) {
link := <-linkChan
// process this link
log.Debugf("connect managing link %s", link.id)
go node.manage(link)
go func() {
// process any further new links
select {
case l := <-linkChan:
go node.manage(l)
case <-node.closed:
return
for {
// process any further new links
select {
case l := <-linkChan:
log.Debugf("Managing new link %s", l.id)
go node.manage(l)
case <-node.closed:
return
}
}
}()
@ -203,18 +213,7 @@ func (n *node) accept(l transport.Listener) error {
}()
// create a new link
link := &link{
// link has a unique id
id: uuid.New().String(),
// proto marshaler
codec: proto.Marshaler{},
// link has a socket
socket: sock,
// for generating leases,
node: n,
// the send queue,
queue: make(chan *Message, 128),
}
link := newLink(n, sock, nil)
log.Debugf("Accepting connection from %s", link.socket.Remote())
@ -222,24 +221,44 @@ func (n *node) accept(l transport.Listener) error {
// the remote end will send "Connect"
// and we will return a "Lease"
if err := link.accept(); err != nil {
log.Debugf("Error accepting connection %v", err)
return
}
log.Debugf("Accepted link from %s", link.socket.Remote())
// save with the remote address as the key
// save with the muid as the key
// where we attempt to connect to nodes
// we do not connect to the same thing
n.Lock()
n.links[link.socket.Remote()] = link
n.Unlock()
// TODO: figure out why this is an issue
// When we receive a connection from ourself
// we can't maintain the two links separately
// so we don't save it. It's basically some
// weird loopback issue because its our own socket.
if n.muid != link.lease.Node.Muid {
n.Lock()
// get the links
links := n.links[link.lease.Node.Muid]
// append to the current links
links = append(links, link)
// save the links with muid as the key
n.links[link.lease.Node.Muid] = links
n.Unlock()
}
// manage the link for its lifetime
log.Debugf("managing the link now %s", link.id)
n.manage(link)
})
}
// processes the send queue
// processes the sends the messages from n.Send into the queue of
// each link. If multiple links exist for a muid it should only
// send on link to figure it out.
// If we connected to a record and that link goes down we should
// also remove it from the n.connected map.
func (n *node) process() {
for {
select {
@ -251,29 +270,51 @@ func (n *node) process() {
// queue the message on each link
// TODO: more than likely use proxy
n.RLock()
for _, l := range n.links {
l.queue <- m
// range over all the links
for _, links := range n.links {
if len(links) == 0 {
continue
}
// sort the links by weight
sort.Slice(links, func(i, j int) bool {
return links[i].Weight() < links[j].Weight()
})
// queue the message
log.Debugf("sending on link %s", links[0].id)
links[0].Send(m)
}
n.RUnlock()
}
}
}
// Manage manages the link for its lifetime. It should ideally throw
// away the link in the n.links map if there's any issues or total disconnection
// it should look at link.Status.
// If we connected to a record and that link goes down we should
// also remove it from the n.connected map.
func (n *node) manage(l *link) {
// now process inbound messages on the link
// assumption is this handles everything else
for {
// get a message on the link
m := new(Message)
if err := l.recv(m, nil); err != nil {
// the send side uses a link queue but the receive side immediately sends it
// ideally we should probably have an internal queue on that side as well
// so we can judge link saturation both ways.
m, err := l.Accept()
if err != nil {
log.Debugf("Error accepting message on link %s: %v", l.id, err)
// ???
return
}
// if the node connection is closed bail out
select {
case <-n.closed:
return
// send to the recv channel e.g node.Accept()
// send to the network recv channel e.g node.Accept()
case n.recv <- m:
}
}
@ -301,18 +342,15 @@ func (n *node) connect(linkChan chan *link) {
n.RLock()
// only start processing if we have less than 3 links
if len(n.links) > 2 {
conns := len(n.links)
if conns > 2 {
n.RUnlock()
continue
}
// get a list of link addresses so we don't reconnect
// to the ones we're already connected to
nodes := map[string]bool{}
for addr, _ := range n.links {
// id is the lookup address used to connect
nodes[addr] = true
}
connected := n.connected
// unlock our read lock
n.RUnlock()
@ -329,11 +367,17 @@ func (n *node) connect(linkChan chan *link) {
// while still connecting to the global network
for _, record := range records {
// skip existing connections
if nodes[record.Address] {
log.Debugf("Skipping connection to %s", record.Address)
if connected[record.Address] {
log.Tracef("Skipping connection to %s", record.Address)
continue
}
// check how many connections we have
if conns > 2 {
log.Debugf("Made enough connections")
break
}
// attempt to connect and create a link
log.Debugf("Dialing connection to %s", record.Address)
@ -346,13 +390,7 @@ func (n *node) connect(linkChan chan *link) {
}
// create a new link with the lease and socket
link := &link{
codec: &proto.Marshaler{},
id: uuid.New().String(),
lease: lease,
socket: sock,
queue: make(chan *Message, 128),
}
link := newLink(n, sock, lease)
log.Debugf("Connecting link to %s", record.Address)
@ -363,7 +401,6 @@ func (n *node) connect(linkChan chan *link) {
// first connect will not have a lease so we get one with node id/address
if err := link.connect(); err != nil {
// shit
link.Close()
continue
}
@ -375,23 +412,39 @@ func (n *node) connect(linkChan chan *link) {
// we may have to expire the lease
lease = link.lease
// save the new link
n.links[link.socket.Remote()] = link
// get existing links using the lease author
links := n.links[lease.Author]
// append to the links
links = append(links, link)
// save the links using the author
n.links[lease.Author] = links
n.Unlock()
// update number of connections
conns++
// save the connection
n.Lock()
n.connected[record.Address] = true
n.Unlock()
// drop this down the link channel to the network
// so it can manage the links
select {
case linkChan <- link:
// we don't wait for anyone
default:
}
linkChan <- link
}
}
}
}
func (n *node) Address() string {
return n.address
n.RLock()
defer n.RUnlock()
// we have no address yet
if n.lease == nil {
return ""
}
// return node address in the lease
return n.lease.Node.Address
}
// Close shutdowns all the links and closes the listener
@ -400,15 +453,19 @@ func (n *node) Close() error {
case <-n.closed:
return nil
default:
// mark as closed
// mark as closed, we're now useless and there's no coming back
close(n.closed)
// shutdown all the links
n.Lock()
for id, link := range n.links {
link.Close()
delete(n.links, id)
for muid, links := range n.links {
for _, link := range links {
link.Close()
}
delete(n.links, muid)
}
// reset connected
n.connected = nil
n.Unlock()
// deregister self
@ -444,6 +501,15 @@ func (n *node) Accept() (*Message, error) {
return nil, nil
}
func (n *node) Id() string {
n.RLock()
defer n.RUnlock()
if n.lease == nil {
return ""
}
return n.lease.Node.Id
}
func (n *node) Network() string {
return n.network.id
}

View File

@ -22,10 +22,12 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
// A connect message is for connecting to the network
type Connect struct {
// the unique muid (mac) address of the node
Muid string `protobuf:"bytes,1,opt,name=muid,proto3" json:"muid,omitempty"`
// Lease specifies an existing lease to indicate
// we don't need a new address, we just want to
// establish a link.
Lease *Lease `protobuf:"bytes,1,opt,name=lease,proto3" json:"lease,omitempty"`
Lease *Lease `protobuf:"bytes,2,opt,name=lease,proto3" json:"lease,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -56,6 +58,13 @@ func (m *Connect) XXX_DiscardUnknown() {
var xxx_messageInfo_Connect proto.InternalMessageInfo
func (m *Connect) GetMuid() string {
if m != nil {
return m.Muid
}
return ""
}
func (m *Connect) GetLease() *Lease {
if m != nil {
return m.Lease
@ -63,14 +72,16 @@ func (m *Connect) GetLease() *Lease {
return nil
}
// A lease is returned to anyone attempting to connect.
// A lease is returned to anyone attempting to connect with a valid muid.
type Lease struct {
// unique lease id
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
// timestamp of lease
Timestamp int64 `protobuf:"varint,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
// author is the muid of the author
Author string `protobuf:"bytes,3,opt,name=author,proto3" json:"author,omitempty"`
// the node
Node *Node `protobuf:"bytes,3,opt,name=node,proto3" json:"node,omitempty"`
Node *Node `protobuf:"bytes,4,opt,name=node,proto3" json:"node,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -115,6 +126,13 @@ func (m *Lease) GetTimestamp() int64 {
return 0
}
func (m *Lease) GetAuthor() string {
if m != nil {
return m.Author
}
return ""
}
func (m *Lease) GetNode() *Node {
if m != nil {
return m.Node
@ -124,9 +142,10 @@ func (m *Lease) GetNode() *Node {
// A node is the network node
type Node struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"`
Network string `protobuf:"bytes,3,opt,name=network,proto3" json:"network,omitempty"`
Muid string `protobuf:"bytes,1,opt,name=muid,proto3" json:"muid,omitempty"`
Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`
Address string `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"`
Network string `protobuf:"bytes,4,opt,name=network,proto3" json:"network,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -157,6 +176,13 @@ func (m *Node) XXX_DiscardUnknown() {
var xxx_messageInfo_Node proto.InternalMessageInfo
func (m *Node) GetMuid() string {
if m != nil {
return m.Muid
}
return ""
}
func (m *Node) GetId() string {
if m != nil {
return m.Id
@ -189,18 +215,20 @@ func init() {
}
var fileDescriptor_4daa91d05ddc28b6 = []byte{
// 203 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x90, 0xc1, 0x4a, 0xc4, 0x30,
0x10, 0x86, 0x69, 0x77, 0xd7, 0x25, 0x23, 0x88, 0xe4, 0xa0, 0x39, 0x78, 0x58, 0x7a, 0x2a, 0x85,
0xa6, 0xa0, 0x17, 0xef, 0xde, 0x44, 0x3c, 0xe4, 0x0d, 0x62, 0x33, 0x94, 0xa0, 0xcd, 0x94, 0x24,
0xe0, 0xeb, 0x4b, 0xa7, 0xad, 0x82, 0xbd, 0xe5, 0x9b, 0xf9, 0xf3, 0x7f, 0x30, 0xd0, 0x8c, 0xbe,
0x8f, 0xd4, 0x0d, 0xd4, 0x2e, 0x8f, 0x80, 0xf9, 0x9b, 0xe2, 0x67, 0x37, 0x45, 0xca, 0xbf, 0xa4,
0x99, 0xe4, 0xed, 0x40, 0x9a, 0x53, 0x7a, 0x9d, 0x57, 0xcf, 0x70, 0x7e, 0xa1, 0x10, 0xb0, 0xcf,
0xb2, 0x85, 0xd3, 0x17, 0xda, 0x84, 0xaa, 0xb8, 0x14, 0xf5, 0xf5, 0xe3, 0xbd, 0xfe, 0x1f, 0xd6,
0x6f, 0xf3, 0xda, 0x2c, 0xa9, 0xca, 0xc2, 0x89, 0x59, 0xde, 0x40, 0xe9, 0x1d, 0x7f, 0x12, 0xa6,
0xf4, 0x4e, 0x3e, 0x80, 0xc8, 0x7e, 0xc4, 0x94, 0xed, 0x38, 0xa9, 0xf2, 0x52, 0xd4, 0x07, 0xf3,
0x37, 0x90, 0x0d, 0x1c, 0x03, 0x39, 0x54, 0x07, 0x96, 0xdc, 0xed, 0x25, 0xef, 0xe4, 0xd0, 0x70,
0xa6, 0x7a, 0x85, 0xe3, 0x4c, 0x3b, 0x83, 0x82, 0xb3, 0x75, 0x2e, 0x62, 0x4a, 0xdc, 0x2f, 0xcc,
0x86, 0xf3, 0x66, 0xed, 0x61, 0x81, 0x30, 0x1b, 0x7e, 0x5c, 0xf1, 0x05, 0x9e, 0x7e, 0x02, 0x00,
0x00, 0xff, 0xff, 0xf3, 0x2b, 0x3d, 0x08, 0x2f, 0x01, 0x00, 0x00,
// 229 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0xc1, 0x6a, 0xc3, 0x30,
0x0c, 0x86, 0x49, 0x9a, 0xb6, 0x44, 0x83, 0x31, 0x74, 0xe8, 0x7c, 0xd8, 0xa1, 0xe4, 0x54, 0x0a,
0x75, 0x61, 0x7b, 0x84, 0x5d, 0xcb, 0x0e, 0x7e, 0x80, 0x41, 0x56, 0x8b, 0x2e, 0x6c, 0xb6, 0x8a,
0xed, 0x32, 0xf6, 0xf6, 0x23, 0x8a, 0x93, 0xc1, 0xd6, 0x9b, 0x3e, 0xe9, 0xf7, 0xff, 0xcb, 0x82,
0xad, 0xeb, 0x8e, 0x81, 0xf7, 0x27, 0xde, 0x0d, 0x85, 0xa7, 0xf4, 0xc5, 0xe1, 0x63, 0x7f, 0x0e,
0x9c, 0x26, 0xd2, 0x42, 0x78, 0x77, 0x62, 0x2d, 0x2a, 0x9d, 0xfb, 0xcd, 0x01, 0x96, 0xcf, 0xec,
0x3d, 0x1d, 0x13, 0x22, 0x54, 0xee, 0xd2, 0x59, 0x55, 0xac, 0x8b, 0x4d, 0x6d, 0xa4, 0xc6, 0x1d,
0xcc, 0x3f, 0xa9, 0x8d, 0xa4, 0xca, 0x75, 0xb1, 0xb9, 0x79, 0xbc, 0xd7, 0x7f, 0x0d, 0xf4, 0xa1,
0x1f, 0x9b, 0x41, 0xd5, 0x7c, 0xc3, 0x5c, 0x18, 0x6f, 0xa1, 0x9c, 0x9c, 0xca, 0xce, 0xe2, 0x03,
0xd4, 0xa9, 0x73, 0x14, 0x53, 0xeb, 0xce, 0xe2, 0x35, 0x33, 0xbf, 0x0d, 0x5c, 0xc1, 0xa2, 0xbd,
0xa4, 0x77, 0x0e, 0x6a, 0x26, 0x2f, 0x32, 0xe1, 0x16, 0x2a, 0xcf, 0x96, 0x54, 0x25, 0xe1, 0xab,
0xff, 0xe1, 0x2f, 0x6c, 0xc9, 0x88, 0xa6, 0x79, 0x85, 0xaa, 0xa7, 0xab, 0xbf, 0x18, 0xb6, 0x29,
0xa7, 0x6d, 0x14, 0x2c, 0x5b, 0x6b, 0x03, 0xc5, 0x98, 0x03, 0x47, 0xec, 0x27, 0xd9, 0x5b, 0x42,
0x6b, 0x33, 0xe2, 0xdb, 0x42, 0x2e, 0xf8, 0xf4, 0x13, 0x00, 0x00, 0xff, 0xff, 0xba, 0xcc, 0x46,
0x1e, 0x6f, 0x01, 0x00, 0x00,
}

View File

@ -4,25 +4,31 @@ package go.micro.network;
// A connect message is for connecting to the network
message Connect {
// the unique muid (mac) address of the node
string muid = 1;
// Lease specifies an existing lease to indicate
// we don't need a new address, we just want to
// establish a link.
Lease lease = 1;
Lease lease = 2;
}
// A lease is returned to anyone attempting to connect.
// A lease is returned to anyone attempting to connect with a valid muid.
message Lease {
// unique lease id
string id = 1;
// timestamp of lease
int64 timestamp = 2;
// author is the muid of the author
string author = 3;
// the node
Node node = 3;
Node node = 4;
}
// A node is the network node
message Node {
string id = 1;
string address = 2;
string network = 3;
string muid = 1;
string id = 2;
string address = 3;
string network = 4;
}