Added sync message. Refactored connect flow. Adverts are gossipped.

This commit adds a Sync message which is sent as a reply to Connect
message. This should in theory speed up convergence of a (re)connecting
node.

We respond to Sync message by sending a peer message back to the peer
origin of the Sync message. We consequently update our routing table and
peer graph with the data sent in via Sync message.

We now gossip advertse to up to 3 randomly selected peers instead of
sending a multicast message to the network.

Equally, Solicitation i.e. full table adverts are gossipped to a
randomly selected peer. If that fails we send a multicast message to the
network.
This commit is contained in:
Milos Gajdos 2020-01-10 11:57:34 +00:00
parent 0a4bd02503
commit bf42c028fb
No known key found for this signature in database
GPG Key ID: 8B31058CC55DFD4F
4 changed files with 222 additions and 84 deletions

View File

@ -6,6 +6,7 @@ import (
"hash/fnv"
"io"
"math"
"math/rand"
"sort"
"sync"
"time"
@ -25,6 +26,7 @@ import (
tun "github.com/micro/go-micro/tunnel/transport"
"github.com/micro/go-micro/util/backoff"
"github.com/micro/go-micro/util/log"
pbUtil "github.com/micro/go-micro/util/proto"
)
var (
@ -270,9 +272,9 @@ func (n *network) acceptCtrlConn(l tunnel.Listener, recv chan *message) {
}
}
// handleCtrlConn handles ControlChannel connections
// advertise advertises routes to the network
func (n *network) advertise(advertChan <-chan *router.Advert) {
rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
hasher := fnv.New64()
for {
select {
@ -322,11 +324,22 @@ func (n *network) advertise(advertChan <-chan *router.Advert) {
Events: events,
}
// send the advert to all on the control channel
// since its not a solicitation
// send the advert to a select number of random peers
if advert.Type != router.Solicitation {
if err := n.sendMsg("advert", ControlChannel, msg); err != nil {
log.Debugf("Network failed to advertise routes: %v", err)
// get a list of node peers
peers := n.Peers()
// advertise to max 3 peers
max := len(peers)
if max > 3 {
max = 3
}
for i := 0; i < max; i++ {
if peer := n.node.GetPeerNode(peers[rnd.Intn(len(peers))].Id()); peer != nil {
if err := n.sendTo("advert", ControlChannel, peer, msg); err != nil {
log.Debugf("Network failed to advertise routes: %v", err)
}
}
}
continue
}
@ -338,8 +351,16 @@ func (n *network) advertise(advertChan <-chan *router.Advert) {
// someone requested the route
n.sendTo("advert", ControlChannel, peer, msg)
default:
if err := n.sendMsg("advert", ControlChannel, msg); err != nil {
log.Debugf("Network failed to advertise routes: %v", err)
// get a list of node peers
peers := n.Peers()
// pick a random peer from the list of peers
peer := n.node.GetPeerNode(peers[rnd.Intn(len(peers))].Id())
if err := n.sendTo("advert", ControlChannel, peer, msg); err != nil {
log.Debugf("Network failed to advertise routes to %s: %v, sending multicast", err, peer.Id())
// send a multicast message if we fail to send Unicast message
if err := n.sendMsg("advert", ControlChannel, msg); err != nil {
log.Debugf("Network failed to advertise routes: %v", err)
}
}
}
case <-n.closed:
@ -460,6 +481,7 @@ func (n *network) handleNetConn(s tunnel.Session, msg chan *message) {
}
}
// handleCtrlConn handles ControlChannel connections
func (n *network) handleCtrlConn(s tunnel.Session, msg chan *message) {
for {
m := new(transport.Message)
@ -733,8 +755,8 @@ func (n *network) processNetChan(listener tunnel.Listener) {
case "connect":
// mark the time the message has been received
now := time.Now()
pbNetConnect := &pbNet.Connect{}
pbNetConnect := &pbNet.Connect{}
if err := proto.Unmarshal(m.msg.Body, pbNetConnect); err != nil {
log.Debugf("Network tunnel [%s] connect unmarshal error: %v", NetworkChannel, err)
continue
@ -757,35 +779,61 @@ func (n *network) processNetChan(listener tunnel.Listener) {
// update peer links
// TODO: should we do this only if we manage to add a peer
// What should we do if the peer links failed to be updated?
if err := n.updatePeerLinks(peer); err != nil {
log.Debugf("Network failed updating peer links: %s", err)
}
// add peer to the list of node peers
if err := n.node.AddPeer(peer); err == ErrPeerExists {
if err := n.AddPeer(peer); err == ErrPeerExists {
log.Tracef("Network peer exists, refreshing: %s", peer.id)
// update lastSeen time for the existing node
// update lastSeen time for the peer
if err := n.RefreshPeer(peer.id, peer.link, now); err != nil {
log.Debugf("Network failed refreshing peer %s: %v", peer.id, err)
}
}
// we send the peer message because someone has sent connect
// and wants to know what's on the network. The faster we
// respond the faster we start to converge
// we send the sync message because someone has sent connect
// and wants to either connect or reconnect to the network
// The faster it gets the network config (routes and peer graph)
// the faster the network converges to a stable state
go func() {
// get node peers down to MaxDepth encoded in protobuf
msg := PeersToProto(n.node, MaxDepth)
// get node peer graph to send back to the connecting node
node := PeersToProto(n.node, MaxDepth)
// advertise yourself to the new node
if err := n.sendTo("peer", NetworkChannel, peer, msg); err != nil {
log.Debugf("Network failed to advertise peers: %v", err)
msg := &pbNet.Sync{
Peer: node,
}
// get a list of all of our routes
routes, err := n.options.Router.Table().List()
switch err {
case nil:
// encode the routes to protobuf
pbRoutes := make([]*pbRtr.Route, 0, len(routes))
for _, route := range routes {
pbRoute := pbUtil.RouteToProto(route)
pbRoutes = append(pbRoutes, pbRoute)
}
// pack the routes into the sync message
msg.Routes = pbRoutes
default:
// we can't list the routes
log.Debugf("Network node %s failed listing routes: %v", n.id, err)
}
// send sync message to the newly connected peer
if err := n.sendTo("sync", NetworkChannel, peer, msg); err != nil {
log.Debugf("Network failed to send sync message: %v", err)
}
// wait for a short period of time before sending a solicit message
<-time.After(time.Millisecond * 100)
// send a solicit message when discovering new peer
// this triggers the node to flush its routing table to the network
// and leads to faster convergence of the network
solicit := &pbRtr.Solicit{
Id: n.options.Id,
}
@ -801,13 +849,6 @@ func (n *network) processNetChan(listener tunnel.Listener) {
default:
// don't block
}
// advertise all the routes when a new node has connected
// NOTE: this might unnecessarily flood network with advertisements
// every time a node's connection is flakey and it keeps reconnecting
if err := n.router.Solicit(); err != nil {
log.Debugf("Network failed to solicit routes: %s", err)
}
}()
case "peer":
// mark the time the message has been received
@ -836,10 +877,13 @@ func (n *network) processNetChan(listener tunnel.Listener) {
// update peer links
// TODO: should we do this only if we manage to add a peer
// What should we do if the peer links failed to be updated?
if err := n.updatePeerLinks(peer); err != nil {
log.Debugf("Network failed updating peer links: %s", err)
}
// if it's a new peer i.e. we do not have it in our graph, we solicit its routes
if err := n.node.AddPeer(peer); err == nil {
go func() {
msg := PeersToProto(n.node, MaxDepth)
@ -875,7 +919,7 @@ func (n *network) processNetChan(listener tunnel.Listener) {
}()
continue
// we're expecting any error to be ErrPeerExists
// if we already have the peer in our graph, skip further steps
} else if err != ErrPeerExists {
log.Debugf("Network got error adding peer %v", err)
continue
@ -905,6 +949,75 @@ func (n *network) processNetChan(listener tunnel.Listener) {
default:
// don't block here
}
case "sync":
// record the timestamp of the message receipt
now := time.Now()
pbNetSync := &pbNet.Sync{}
if err := proto.Unmarshal(m.msg.Body, pbNetSync); err != nil {
log.Debugf("Network tunnel [%s] sync unmarshal error: %v", NetworkChannel, err)
continue
}
// don't process your own messages
if pbNetSync.Peer.Node.Id == n.options.Id {
continue
}
log.Debugf("Network received sync message from: %s", pbNetSync.Peer.Node.Id)
peer := &node{
id: pbNetSync.Peer.Node.Id,
address: pbNetSync.Peer.Node.Address,
link: m.msg.Header["Micro-Link"],
peers: make(map[string]*node),
lastSeen: now,
}
// update peer links
// TODO: should we do this only if we manage to add a peer
// What should we do if the peer links failed to be updated?
if err := n.updatePeerLinks(peer); err != nil {
log.Debugf("Network failed updating peer links: %s", err)
}
// add peer to the list of node peers
if err := n.node.AddPeer(peer); err == ErrPeerExists {
log.Tracef("Network peer exists, refreshing: %s", peer.id)
// update lastSeen time for the existing node
if err := n.RefreshPeer(peer.id, peer.link, now); err != nil {
log.Debugf("Network failed refreshing peer %s: %v", peer.id, err)
}
}
// when we receive a sync message we update our routing table
// and send a peer message back to the network to announce our presence
// we consequently flush our table to the network too to make the convergence faster
go func() {
// add all the routes we have received in the sync message
for _, pbRoute := range pbNetSync.Routes {
route := pbUtil.ProtoToRoute(pbRoute)
if err := n.router.Table().Create(route); err != nil && err != router.ErrDuplicateRoute {
log.Debugf("Network node %s failed to add route: %v", n.id, err)
}
}
// update your sync timestamp
// NOTE: this might go away as we will be doing full table advert to random peer
if err := n.RefreshSync(now); err != nil {
log.Debugf("Network failed refreshing sync time: %v", err)
}
// get node peer graph to send back to the syncing node
msg := PeersToProto(n.node, MaxDepth)
// advertise yourself to the new node
if err := n.sendTo("peer", NetworkChannel, peer, msg); err != nil {
log.Debugf("Network failed to advertise peers: %v", err)
}
}()
case "close":
pbNetClose := &pbNet.Close{}
if err := proto.Unmarshal(m.msg.Body, pbNetClose); err != nil {
@ -932,6 +1045,9 @@ func (n *network) processNetChan(listener tunnel.Listener) {
log.Debugf("Network failed pruning peer %s routes: %v", peer.id, err)
}
// NOTE: we should maybe advertise this to the network so we converge faster on closed nodes
// as opposed to our waiting until the node eventually gets pruned; something to think about
// delete peer from the peerLinks
n.Lock()
delete(n.peerLinks, pbNetClose.Node.Address)

View File

@ -675,12 +675,10 @@ func (m *Peer) GetPeers() []*Peer {
// Sync is network sync message
type Sync struct {
// node address
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
// node peers
Peers []*Peer `protobuf:"bytes,2,rep,name=peers,proto3" json:"peers,omitempty"`
// peer origin
Peer *Peer `protobuf:"bytes,1,opt,name=peer,proto3" json:"peer,omitempty"`
// node routes
Routes []*proto1.Route `protobuf:"bytes,3,rep,name=routes,proto3" json:"routes,omitempty"`
Routes []*proto1.Route `protobuf:"bytes,2,rep,name=routes,proto3" json:"routes,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -711,16 +709,9 @@ func (m *Sync) XXX_DiscardUnknown() {
var xxx_messageInfo_Sync proto.InternalMessageInfo
func (m *Sync) GetAddress() string {
func (m *Sync) GetPeer() *Peer {
if m != nil {
return m.Address
}
return ""
}
func (m *Sync) GetPeers() []*Peer {
if m != nil {
return m.Peers
return m.Peer
}
return nil
}
@ -755,43 +746,43 @@ func init() {
func init() { proto.RegisterFile("network.proto", fileDescriptor_8571034d60397816) }
var fileDescriptor_8571034d60397816 = []byte{
// 594 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0xc1, 0x6a, 0xdb, 0x40,
0x10, 0x8d, 0x2c, 0x29, 0x76, 0xa6, 0x91, 0xeb, 0x2e, 0x25, 0x15, 0x3a, 0xb4, 0xee, 0xe2, 0x43,
0x28, 0x8d, 0x0c, 0x09, 0x85, 0x52, 0xd3, 0x10, 0x08, 0xa5, 0x50, 0x48, 0x48, 0xe5, 0x1f, 0xa8,
0x62, 0x2d, 0xb6, 0x49, 0xac, 0x75, 0x56, 0xeb, 0x04, 0x5f, 0x7a, 0xed, 0x27, 0xf4, 0x9b, 0xfa,
0x57, 0x65, 0x77, 0x47, 0x8e, 0x14, 0xcb, 0x22, 0xbe, 0x79, 0x34, 0x6f, 0xde, 0xec, 0xce, 0x7b,
0xb3, 0x06, 0x2f, 0x65, 0xf2, 0x81, 0x8b, 0x9b, 0x70, 0x2e, 0xb8, 0xe4, 0xa4, 0x33, 0xe6, 0xe1,
0x6c, 0x3a, 0x12, 0x3c, 0xc4, 0xef, 0xc1, 0x60, 0x3c, 0x95, 0x93, 0xc5, 0x75, 0x38, 0xe2, 0xb3,
0xbe, 0xce, 0xf4, 0xc7, 0xfc, 0xc8, 0xfc, 0x10, 0x7c, 0x21, 0x99, 0xe8, 0x67, 0x4c, 0xdc, 0x4f,
0x47, 0xac, 0xaf, 0x19, 0xf0, 0xa3, 0xa1, 0xa3, 0x7f, 0x2c, 0x70, 0x7f, 0x2e, 0x98, 0x58, 0x12,
0x1f, 0x9a, 0x88, 0xf3, 0xad, 0xae, 0x75, 0xb8, 0x17, 0xe5, 0xa1, 0xca, 0xc4, 0x49, 0x22, 0x58,
0x96, 0xf9, 0x0d, 0x93, 0xc1, 0x50, 0x65, 0xc6, 0xb1, 0x64, 0x0f, 0xf1, 0xd2, 0xb7, 0x4d, 0x06,
0x43, 0x72, 0x00, 0xbb, 0xa6, 0x8f, 0xef, 0xe8, 0x04, 0x46, 0xaa, 0x02, 0xcf, 0xed, 0xbb, 0xa6,
0x02, 0x43, 0x7a, 0x0a, 0xed, 0x73, 0x9e, 0xa6, 0x6c, 0x24, 0x23, 0x76, 0xb7, 0x60, 0x99, 0x24,
0x1f, 0xc1, 0x4d, 0x79, 0xc2, 0x32, 0xdf, 0xea, 0xda, 0x87, 0x2f, 0x8e, 0x0f, 0xc2, 0xa7, 0x57,
0x0f, 0x2f, 0x79, 0xc2, 0x22, 0x03, 0xa2, 0xaf, 0xe0, 0xe5, 0xaa, 0x3e, 0x9b, 0xf3, 0x34, 0x63,
0xb4, 0x07, 0xfb, 0x0a, 0x91, 0xe5, 0x84, 0xaf, 0xc1, 0x4d, 0xd8, 0x5c, 0x4e, 0xf4, 0x05, 0xbd,
0xc8, 0x04, 0xf4, 0x2b, 0x78, 0x88, 0x32, 0x65, 0x5b, 0xf6, 0xed, 0xc1, 0xfe, 0x77, 0x11, 0xcf,
0x27, 0xf5, 0x4d, 0x06, 0xe0, 0x21, 0x0a, 0x9b, 0x7c, 0x00, 0x47, 0x70, 0x2e, 0x35, 0xaa, 0xb2,
0xc7, 0x15, 0x63, 0x22, 0xd2, 0x18, 0x7a, 0x0a, 0x5e, 0xa4, 0xc6, 0xb7, 0xba, 0xc8, 0x11, 0xb8,
0x77, 0x4a, 0x34, 0xac, 0x7e, 0xb3, 0x5e, 0xad, 0x35, 0x8d, 0x0c, 0x8a, 0x9e, 0x41, 0x3b, 0xaf,
0xc7, 0xee, 0x21, 0xca, 0x53, 0x71, 0x47, 0xb4, 0x87, 0x2e, 0x40, 0xd9, 0xf4, 0x70, 0x87, 0xc6,
0x0d, 0xf9, 0x19, 0x68, 0x08, 0x9d, 0xc7, 0x4f, 0x48, 0x1b, 0x40, 0x0b, 0x4d, 0x63, 0x88, 0xf7,
0xa2, 0x55, 0x4c, 0xff, 0x59, 0xe0, 0xa8, 0xb9, 0x91, 0x36, 0x34, 0xa6, 0x09, 0x7a, 0xac, 0x31,
0x4d, 0xea, 0xed, 0x95, 0x9b, 0xc5, 0x2e, 0x99, 0x85, 0x9c, 0x41, 0x6b, 0xc6, 0x64, 0x9c, 0xc4,
0x32, 0xf6, 0x1d, 0x7d, 0x83, 0x5e, 0xb5, 0x4a, 0xe1, 0x05, 0xc2, 0xbe, 0xa5, 0x52, 0x2c, 0xa3,
0x55, 0x55, 0x30, 0x00, 0xaf, 0x94, 0x22, 0x1d, 0xb0, 0x6f, 0xd8, 0x12, 0xcf, 0xa5, 0x7e, 0x2a,
0x25, 0xef, 0xe3, 0xdb, 0x05, 0xc3, 0x63, 0x99, 0xe0, 0x4b, 0xe3, 0xb3, 0x45, 0x3f, 0x41, 0x13,
0xbd, 0xa6, 0x74, 0x54, 0x3e, 0xd8, 0xac, 0xa3, 0xf6, 0x8a, 0xc6, 0xd0, 0x13, 0x70, 0xcf, 0x6f,
0xb9, 0x11, 0xff, 0xd9, 0x45, 0xbf, 0xc0, 0x51, 0x56, 0xd8, 0xa6, 0x46, 0x39, 0x78, 0xce, 0x98,
0x50, 0x03, 0xb5, 0x6b, 0xdc, 0x65, 0x40, 0xf4, 0x37, 0x38, 0xc3, 0x65, 0x3a, 0x2a, 0x0a, 0x61,
0x95, 0x85, 0xd8, 0x8a, 0xaf, 0x60, 0x2e, 0xfb, 0x39, 0xe6, 0x3a, 0xfe, 0x6b, 0x43, 0xf3, 0x12,
0x85, 0xbd, 0x7a, 0x9c, 0x6c, 0x77, 0xbd, 0x4b, 0xf9, 0x81, 0x08, 0xde, 0xd7, 0x20, 0xf0, 0x09,
0xd8, 0x21, 0x3f, 0xc0, 0xd5, 0x9b, 0x47, 0xde, 0xae, 0xa3, 0x8b, 0x8b, 0x1b, 0xbc, 0xdb, 0x98,
0x2f, 0x72, 0xe9, 0xa7, 0xa2, 0x8a, 0xab, 0xf8, 0xd2, 0x54, 0x71, 0x95, 0xde, 0x18, 0xba, 0x43,
0x2e, 0x60, 0xd7, 0x2c, 0x25, 0xa9, 0x00, 0x97, 0xd6, 0x3d, 0xe8, 0x6e, 0x06, 0xac, 0xe8, 0x86,
0xd0, 0xca, 0xd7, 0x91, 0x54, 0xcc, 0xe5, 0xc9, 0xf6, 0x06, 0xb4, 0x0e, 0x92, 0x93, 0x5e, 0xef,
0xea, 0x3f, 0x89, 0x93, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x78, 0x0e, 0x14, 0x60, 0x84, 0x06,
0x00, 0x00,
// 593 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0x5d, 0x6a, 0xdb, 0x40,
0x10, 0x8e, 0x2c, 0x29, 0x3f, 0xd3, 0xc8, 0x75, 0x97, 0x92, 0x0a, 0x3d, 0xb4, 0xee, 0xe2, 0x87,
0x50, 0x1a, 0x19, 0x12, 0x0a, 0xa5, 0xa6, 0x21, 0x10, 0x4a, 0xa1, 0x90, 0x90, 0xca, 0x17, 0xa8,
0x6c, 0x0d, 0xb6, 0x49, 0xac, 0x75, 0x56, 0xeb, 0x04, 0x9f, 0xa0, 0x47, 0xe8, 0x99, 0x7a, 0xab,
0xb2, 0xbb, 0x23, 0xc7, 0x8e, 0x65, 0x37, 0x79, 0xd3, 0xec, 0x7c, 0xdf, 0xcc, 0xce, 0xcc, 0x37,
0x2b, 0x08, 0x72, 0x54, 0xf7, 0x42, 0x5e, 0xc7, 0x13, 0x29, 0x94, 0x60, 0x8d, 0x81, 0x88, 0xc7,
0xa3, 0xbe, 0x14, 0x31, 0x9d, 0x47, 0x9d, 0xc1, 0x48, 0x0d, 0xa7, 0xbd, 0xb8, 0x2f, 0xc6, 0x6d,
0xe3, 0x69, 0x0f, 0xc4, 0x91, 0xfd, 0x90, 0x62, 0xaa, 0x50, 0xb6, 0x0b, 0x94, 0x77, 0xa3, 0x3e,
0xb6, 0x4d, 0x04, 0x3a, 0xb4, 0xe1, 0xf8, 0x6f, 0x07, 0xfc, 0x9f, 0x53, 0x94, 0x33, 0x16, 0xc2,
0x0e, 0xe1, 0x42, 0xa7, 0xe9, 0x1c, 0xee, 0x25, 0xa5, 0xa9, 0x3d, 0x69, 0x96, 0x49, 0x2c, 0x8a,
0xb0, 0x66, 0x3d, 0x64, 0x6a, 0xcf, 0x20, 0x55, 0x78, 0x9f, 0xce, 0x42, 0xd7, 0x7a, 0xc8, 0x64,
0x07, 0xb0, 0x6d, 0xf3, 0x84, 0x9e, 0x71, 0x90, 0xa5, 0x19, 0x74, 0xef, 0xd0, 0xb7, 0x0c, 0x32,
0xf9, 0x29, 0xd4, 0xcf, 0x45, 0x9e, 0x63, 0x5f, 0x25, 0x78, 0x3b, 0xc5, 0x42, 0xb1, 0x8f, 0xe0,
0xe7, 0x22, 0xc3, 0x22, 0x74, 0x9a, 0xee, 0xe1, 0x8b, 0xe3, 0x83, 0xf8, 0x71, 0xe9, 0xf1, 0xa5,
0xc8, 0x30, 0xb1, 0x20, 0xfe, 0x0a, 0x5e, 0xce, 0xf9, 0xc5, 0x44, 0xe4, 0x05, 0xf2, 0x16, 0xec,
0x6b, 0x44, 0x51, 0x06, 0x7c, 0x0d, 0x7e, 0x86, 0x13, 0x35, 0x34, 0x05, 0x06, 0x89, 0x35, 0xf8,
0x57, 0x08, 0x08, 0x65, 0x69, 0xcf, 0xcc, 0xdb, 0x82, 0xfd, 0xef, 0x32, 0x9d, 0x0c, 0x37, 0x27,
0xe9, 0x40, 0x40, 0x28, 0x4a, 0xf2, 0x01, 0x3c, 0x29, 0x84, 0x32, 0xa8, 0xca, 0x1c, 0x57, 0x88,
0x32, 0x31, 0x18, 0x7e, 0x0a, 0x41, 0xa2, 0xdb, 0x37, 0x2f, 0xe4, 0x08, 0xfc, 0x5b, 0x3d, 0x34,
0x62, 0xbf, 0x59, 0x65, 0x9b, 0x99, 0x26, 0x16, 0xc5, 0xcf, 0xa0, 0x5e, 0xf2, 0x29, 0x7b, 0x4c,
0xe3, 0xa9, 0xa8, 0x91, 0xe4, 0x61, 0x08, 0x34, 0x36, 0xd3, 0xdc, 0xae, 0x55, 0x43, 0x79, 0x07,
0x1e, 0x43, 0xe3, 0xe1, 0x88, 0xc2, 0x46, 0xb0, 0x4b, 0xa2, 0xb1, 0x81, 0xf7, 0x92, 0xb9, 0xcd,
0xff, 0x3a, 0xe0, 0xe9, 0xbe, 0xb1, 0x3a, 0xd4, 0x46, 0x19, 0x69, 0xac, 0x36, 0xca, 0x36, 0xcb,
0xab, 0x14, 0x8b, 0xbb, 0x24, 0x16, 0x76, 0x06, 0xbb, 0x63, 0x54, 0x69, 0x96, 0xaa, 0x34, 0xf4,
0x4c, 0x05, 0xad, 0xea, 0x29, 0xc5, 0x17, 0x04, 0xfb, 0x96, 0x2b, 0x39, 0x4b, 0xe6, 0xac, 0xa8,
0x03, 0xc1, 0x92, 0x8b, 0x35, 0xc0, 0xbd, 0xc6, 0x19, 0xdd, 0x4b, 0x7f, 0xea, 0x49, 0xde, 0xa5,
0x37, 0x53, 0xa4, 0x6b, 0x59, 0xe3, 0x4b, 0xed, 0xb3, 0xc3, 0x3f, 0xc1, 0x0e, 0x69, 0x4d, 0xcf,
0x51, 0xeb, 0x60, 0xfd, 0x1c, 0x8d, 0x56, 0x0c, 0x86, 0x9f, 0x80, 0x7f, 0x7e, 0x23, 0xec, 0xf0,
0x9f, 0x4c, 0xfa, 0x05, 0x9e, 0x96, 0xc2, 0x73, 0x38, 0x5a, 0xc1, 0x13, 0x44, 0xa9, 0x1b, 0xea,
0x6e, 0x50, 0x97, 0x05, 0xf1, 0x1e, 0x78, 0xdd, 0x59, 0xde, 0xd7, 0x19, 0xf4, 0xc1, 0xff, 0x24,
0xa9, 0x31, 0x0b, 0x02, 0xaa, 0x3d, 0x45, 0x40, 0xc7, 0x7f, 0x5c, 0xd8, 0xb9, 0xa4, 0xe1, 0x5d,
0x3d, 0x74, 0xaf, 0xb9, 0x9a, 0x64, 0xf9, 0x11, 0x88, 0xde, 0x6f, 0x40, 0xd0, 0x9a, 0x6f, 0xb1,
0x1f, 0xe0, 0x9b, 0xed, 0x62, 0x6f, 0x57, 0xd1, 0x8b, 0xcb, 0x19, 0xbd, 0x5b, 0xeb, 0x5f, 0x8c,
0x65, 0x9e, 0x83, 0xaa, 0x58, 0x8b, 0xaf, 0x49, 0x55, 0xac, 0xa5, 0x77, 0x84, 0x6f, 0xb1, 0x0b,
0xd8, 0xb6, 0x8b, 0xc7, 0x2a, 0xc0, 0x4b, 0x2b, 0x1d, 0x35, 0xd7, 0x03, 0xe6, 0xe1, 0xba, 0xb0,
0x5b, 0xae, 0x1c, 0xab, 0xe8, 0xcb, 0xa3, 0x0d, 0x8d, 0xf8, 0x26, 0x48, 0x19, 0xb4, 0xb7, 0x6d,
0x7e, 0x04, 0x27, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x66, 0x66, 0x42, 0x5f, 0x68, 0x06, 0x00,
0x00,
}

View File

@ -103,10 +103,8 @@ message Peer {
// Sync is network sync message
message Sync {
// node address
string address = 1;
// node peers
repeated Peer peers = 2;
// peer origin
Peer peer = 1;
// node routes
repeated go.micro.router.Route routes = 3;
repeated go.micro.router.Route routes = 2;
}

33
util/proto/proto.go Normal file
View File

@ -0,0 +1,33 @@
// Package proto contains utility functions for working with protobufs
package proto
import (
"github.com/micro/go-micro/router"
pbRtr "github.com/micro/go-micro/router/service/proto"
)
// RouteToProto encodes route into protobuf and returns it
func RouteToProto(route router.Route) *pbRtr.Route {
return &pbRtr.Route{
Service: route.Service,
Address: route.Address,
Gateway: route.Gateway,
Network: route.Network,
Router: route.Router,
Link: route.Link,
Metric: int64(route.Metric),
}
}
// ProtoToRoute decodes protobuf route into router route and returns it
func ProtoToRoute(route *pbRtr.Route) router.Route {
return router.Route{
Service: route.Service,
Address: route.Address,
Gateway: route.Gateway,
Network: route.Network,
Router: route.Router,
Link: route.Link,
Metric: route.Metric,
}
}