Merge pull request #1104 from milosgajdos83/network-hackery
[WIP] Network hackery
This commit is contained in:
commit
7c7b0ced5f
@ -6,6 +6,7 @@ import (
|
|||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
|
"math/rand"
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -25,6 +26,7 @@ import (
|
|||||||
tun "github.com/micro/go-micro/tunnel/transport"
|
tun "github.com/micro/go-micro/tunnel/transport"
|
||||||
"github.com/micro/go-micro/util/backoff"
|
"github.com/micro/go-micro/util/backoff"
|
||||||
"github.com/micro/go-micro/util/log"
|
"github.com/micro/go-micro/util/log"
|
||||||
|
pbUtil "github.com/micro/go-micro/util/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -36,6 +38,8 @@ var (
|
|||||||
DefaultLink = "network"
|
DefaultLink = "network"
|
||||||
// MaxConnections is the max number of network client connections
|
// MaxConnections is the max number of network client connections
|
||||||
MaxConnections = 3
|
MaxConnections = 3
|
||||||
|
// MaxPeerErrors is the max number of peer errors before we remove it from network graph
|
||||||
|
MaxPeerErrors = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -43,6 +47,8 @@ var (
|
|||||||
ErrClientNotFound = errors.New("client not found")
|
ErrClientNotFound = errors.New("client not found")
|
||||||
// ErrPeerLinkNotFound is returned when peer link could not be found in tunnel Links
|
// ErrPeerLinkNotFound is returned when peer link could not be found in tunnel Links
|
||||||
ErrPeerLinkNotFound = errors.New("peer link not found")
|
ErrPeerLinkNotFound = errors.New("peer link not found")
|
||||||
|
// ErrPeerMaxExceeded is returned when peer has reached its max error count limit
|
||||||
|
ErrPeerMaxExceeded = errors.New("peer max errors exceeded")
|
||||||
)
|
)
|
||||||
|
|
||||||
// network implements Network interface
|
// network implements Network interface
|
||||||
@ -159,6 +165,7 @@ func newNetwork(opts ...Option) Network {
|
|||||||
id: options.Id,
|
id: options.Id,
|
||||||
address: peerAddress,
|
address: peerAddress,
|
||||||
peers: make(map[string]*node),
|
peers: make(map[string]*node),
|
||||||
|
status: newStatus(),
|
||||||
},
|
},
|
||||||
options: options,
|
options: options,
|
||||||
router: options.Router,
|
router: options.Router,
|
||||||
@ -270,9 +277,9 @@ func (n *network) acceptCtrlConn(l tunnel.Listener, recv chan *message) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleCtrlConn handles ControlChannel connections
|
|
||||||
// advertise advertises routes to the network
|
// advertise advertises routes to the network
|
||||||
func (n *network) advertise(advertChan <-chan *router.Advert) {
|
func (n *network) advertise(advertChan <-chan *router.Advert) {
|
||||||
|
rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
hasher := fnv.New64()
|
hasher := fnv.New64()
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
@ -322,11 +329,22 @@ func (n *network) advertise(advertChan <-chan *router.Advert) {
|
|||||||
Events: events,
|
Events: events,
|
||||||
}
|
}
|
||||||
|
|
||||||
// send the advert to all on the control channel
|
// send the advert to a select number of random peers
|
||||||
// since its not a solicitation
|
|
||||||
if advert.Type != router.Solicitation {
|
if advert.Type != router.Solicitation {
|
||||||
if err := n.sendMsg("advert", ControlChannel, msg); err != nil {
|
// get a list of node peers
|
||||||
log.Debugf("Network failed to advertise routes: %v", err)
|
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 to %s: %v", peer.Id(), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -338,8 +356,17 @@ func (n *network) advertise(advertChan <-chan *router.Advert) {
|
|||||||
// someone requested the route
|
// someone requested the route
|
||||||
n.sendTo("advert", ControlChannel, peer, msg)
|
n.sendTo("advert", ControlChannel, peer, msg)
|
||||||
default:
|
default:
|
||||||
if err := n.sendMsg("advert", ControlChannel, msg); err != nil {
|
// get a list of node peers
|
||||||
log.Debugf("Network failed to advertise routes: %v", err)
|
peers := n.Peers()
|
||||||
|
// pick a random peer from the list of peers
|
||||||
|
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 to %s: %v, sending multicast", peer.Id(), err)
|
||||||
|
// 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 to %s: %v", peer.Id(), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case <-n.closed:
|
case <-n.closed:
|
||||||
@ -354,7 +381,7 @@ func (n *network) initNodes(startup bool) {
|
|||||||
// NOTE: this condition never fires
|
// NOTE: this condition never fires
|
||||||
// as resolveNodes() never returns error
|
// as resolveNodes() never returns error
|
||||||
if err != nil && !startup {
|
if err != nil && !startup {
|
||||||
log.Debugf("Network failed to resolve nodes: %v", err)
|
log.Debugf("Network failed to init nodes: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,6 +487,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) {
|
func (n *network) handleCtrlConn(s tunnel.Session, msg chan *message) {
|
||||||
for {
|
for {
|
||||||
m := new(transport.Message)
|
m := new(transport.Message)
|
||||||
@ -493,10 +521,11 @@ func (n *network) handleCtrlConn(s tunnel.Session, msg chan *message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getHopCount queries network graph and returns hop count for given router
|
// getHopCount queries network graph and returns hop count for given router
|
||||||
|
// NOTE: this should be called getHopeMetric
|
||||||
// - Routes for local services have hop count 1
|
// - Routes for local services have hop count 1
|
||||||
// - Routes with ID of adjacent nodes have hop count 2
|
// - Routes with ID of adjacent nodes have hop count 10
|
||||||
// - Routes by peers of the advertiser have hop count 3
|
// - Routes by peers of the advertiser have hop count 100
|
||||||
// - Routes beyond node neighbourhood have hop count 4
|
// - Routes beyond node neighbourhood have hop count 1000
|
||||||
func (n *network) getHopCount(rtr string) int {
|
func (n *network) getHopCount(rtr string) int {
|
||||||
// make sure node.peers are not modified
|
// make sure node.peers are not modified
|
||||||
n.node.RLock()
|
n.node.RLock()
|
||||||
@ -733,8 +762,8 @@ func (n *network) processNetChan(listener tunnel.Listener) {
|
|||||||
case "connect":
|
case "connect":
|
||||||
// mark the time the message has been received
|
// mark the time the message has been received
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
pbNetConnect := &pbNet.Connect{}
|
|
||||||
|
|
||||||
|
pbNetConnect := &pbNet.Connect{}
|
||||||
if err := proto.Unmarshal(m.msg.Body, pbNetConnect); err != nil {
|
if err := proto.Unmarshal(m.msg.Body, pbNetConnect); err != nil {
|
||||||
log.Debugf("Network tunnel [%s] connect unmarshal error: %v", NetworkChannel, err)
|
log.Debugf("Network tunnel [%s] connect unmarshal error: %v", NetworkChannel, err)
|
||||||
continue
|
continue
|
||||||
@ -752,41 +781,73 @@ func (n *network) processNetChan(listener tunnel.Listener) {
|
|||||||
address: pbNetConnect.Node.Address,
|
address: pbNetConnect.Node.Address,
|
||||||
link: m.msg.Header["Micro-Link"],
|
link: m.msg.Header["Micro-Link"],
|
||||||
peers: make(map[string]*node),
|
peers: make(map[string]*node),
|
||||||
|
status: newStatus(),
|
||||||
lastSeen: now,
|
lastSeen: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
// update peer links
|
// 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 {
|
if err := n.updatePeerLinks(peer); err != nil {
|
||||||
log.Debugf("Network failed updating peer links: %s", err)
|
log.Debugf("Network failed updating peer links: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// add peer to the list of node peers
|
// 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)
|
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 {
|
if err := n.RefreshPeer(peer.id, peer.link, now); err != nil {
|
||||||
log.Debugf("Network failed refreshing peer %s: %v", peer.id, err)
|
log.Debugf("Network failed refreshing peer %s: %v", peer.id, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// we send the peer message because someone has sent connect
|
// we send the sync message because someone has sent connect
|
||||||
// and wants to know what's on the network. The faster we
|
// and wants to either connect or reconnect to the network
|
||||||
// respond the faster we start to converge
|
// The faster it gets the network config (routes and peer graph)
|
||||||
|
// the faster the network converges to a stable state
|
||||||
// get node peers down to MaxDepth encoded in protobuf
|
|
||||||
msg := PeersToProto(n.node, MaxDepth)
|
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
// advertise yourself to the new node
|
// get node peer graph to send back to the connecting node
|
||||||
if err := n.sendTo("peer", NetworkChannel, peer, msg); err != nil {
|
node := PeersToProto(n.node, MaxDepth)
|
||||||
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)
|
<-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,
|
||||||
|
}
|
||||||
|
|
||||||
// ask for the new nodes routes
|
// ask for the new nodes routes
|
||||||
if err := n.sendTo("solicit", ControlChannel, peer, msg); err != nil {
|
if err := n.sendTo("solicit", ControlChannel, peer, solicit); err != nil {
|
||||||
log.Debugf("Network failed to send solicit message: %s", err)
|
log.Debugf("Network failed to send solicit message: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -796,11 +857,6 @@ func (n *network) processNetChan(listener tunnel.Listener) {
|
|||||||
default:
|
default:
|
||||||
// don't block
|
// don't block
|
||||||
}
|
}
|
||||||
|
|
||||||
// advertise all the routes when a new node has connected
|
|
||||||
if err := n.router.Solicit(); err != nil {
|
|
||||||
log.Debugf("Network failed to solicit routes: %s", err)
|
|
||||||
}
|
|
||||||
}()
|
}()
|
||||||
case "peer":
|
case "peer":
|
||||||
// mark the time the message has been received
|
// mark the time the message has been received
|
||||||
@ -824,32 +880,37 @@ func (n *network) processNetChan(listener tunnel.Listener) {
|
|||||||
address: pbNetPeer.Node.Address,
|
address: pbNetPeer.Node.Address,
|
||||||
link: m.msg.Header["Micro-Link"],
|
link: m.msg.Header["Micro-Link"],
|
||||||
peers: make(map[string]*node),
|
peers: make(map[string]*node),
|
||||||
|
status: newPeerStatus(pbNetPeer),
|
||||||
lastSeen: now,
|
lastSeen: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
// update peer links
|
// 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 {
|
if err := n.updatePeerLinks(peer); err != nil {
|
||||||
log.Debugf("Network failed updating peer links: %s", err)
|
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 {
|
if err := n.node.AddPeer(peer); err == nil {
|
||||||
// send a solicit message when discovering new peer
|
|
||||||
msg := &pbRtr.Solicit{
|
|
||||||
Id: n.options.Id,
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
msg := PeersToProto(n.node, MaxDepth)
|
||||||
|
|
||||||
// advertise yourself to the peer
|
// advertise yourself to the peer
|
||||||
if err := n.sendTo("peer", NetworkChannel, peer, msg); err != nil {
|
if err := n.sendTo("peer", NetworkChannel, peer, msg); err != nil {
|
||||||
log.Debugf("Network failed to advertise peers: %v", err)
|
log.Debugf("Network failed to advertise peers: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait for a second
|
|
||||||
<-time.After(time.Millisecond * 100)
|
<-time.After(time.Millisecond * 100)
|
||||||
|
|
||||||
|
// send a solicit message when discovering new peer
|
||||||
|
solicit := &pbRtr.Solicit{
|
||||||
|
Id: n.options.Id,
|
||||||
|
}
|
||||||
|
|
||||||
// then solicit this peer
|
// then solicit this peer
|
||||||
if err := n.sendTo("solicit", ControlChannel, peer, msg); err != nil {
|
if err := n.sendTo("solicit", ControlChannel, peer, solicit); err != nil {
|
||||||
log.Debugf("Network failed to send solicit message: %s", err)
|
log.Debugf("Network failed to send solicit message: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -867,7 +928,7 @@ func (n *network) processNetChan(listener tunnel.Listener) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
continue
|
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 {
|
} else if err != ErrPeerExists {
|
||||||
log.Debugf("Network got error adding peer %v", err)
|
log.Debugf("Network got error adding peer %v", err)
|
||||||
continue
|
continue
|
||||||
@ -897,6 +958,75 @@ func (n *network) processNetChan(listener tunnel.Listener) {
|
|||||||
default:
|
default:
|
||||||
// don't block here
|
// 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),
|
||||||
|
status: newPeerStatus(pbNetSync.Peer),
|
||||||
|
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
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
// 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":
|
case "close":
|
||||||
pbNetClose := &pbNet.Close{}
|
pbNetClose := &pbNet.Close{}
|
||||||
if err := proto.Unmarshal(m.msg.Body, pbNetClose); err != nil {
|
if err := proto.Unmarshal(m.msg.Body, pbNetClose); err != nil {
|
||||||
@ -924,6 +1054,9 @@ func (n *network) processNetChan(listener tunnel.Listener) {
|
|||||||
log.Debugf("Network failed pruning peer %s routes: %v", peer.id, err)
|
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
|
// delete peer from the peerLinks
|
||||||
n.Lock()
|
n.Lock()
|
||||||
delete(n.peerLinks, pbNetClose.Node.Address)
|
delete(n.peerLinks, pbNetClose.Node.Address)
|
||||||
@ -976,12 +1109,15 @@ func (n *network) prunePeerRoutes(peer *node) error {
|
|||||||
// seen for a period of time. Also removes all the routes either originated by or routable
|
// seen for a period of time. Also removes all the routes either originated by or routable
|
||||||
// by the stale nodes. it also resolves nodes periodically and adds them to the tunnel
|
// by the stale nodes. it also resolves nodes periodically and adds them to the tunnel
|
||||||
func (n *network) manage() {
|
func (n *network) manage() {
|
||||||
|
rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
announce := time.NewTicker(AnnounceTime)
|
announce := time.NewTicker(AnnounceTime)
|
||||||
defer announce.Stop()
|
defer announce.Stop()
|
||||||
prune := time.NewTicker(PruneTime)
|
prune := time.NewTicker(PruneTime)
|
||||||
defer prune.Stop()
|
defer prune.Stop()
|
||||||
resolve := time.NewTicker(ResolveTime)
|
resolve := time.NewTicker(ResolveTime)
|
||||||
defer resolve.Stop()
|
defer resolve.Stop()
|
||||||
|
netsync := time.NewTicker(SyncTime)
|
||||||
|
defer netsync.Stop()
|
||||||
|
|
||||||
// list of links we've sent to
|
// list of links we've sent to
|
||||||
links := make(map[string]time.Time)
|
links := make(map[string]time.Time)
|
||||||
@ -1080,7 +1216,7 @@ func (n *network) manage() {
|
|||||||
|
|
||||||
// unknown link and peer so lets do the connect flow
|
// unknown link and peer so lets do the connect flow
|
||||||
if err := n.sendTo("connect", NetworkChannel, peer, msg); err != nil {
|
if err := n.sendTo("connect", NetworkChannel, peer, msg); err != nil {
|
||||||
log.Debugf("Network failed to advertise peer %s: %v", peer.id, err)
|
log.Debugf("Network failed to connect %s: %v", peer.id, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1129,6 +1265,46 @@ func (n *network) manage() {
|
|||||||
log.Debugf("Network failed deleting routes by %s: %v", route.Router, err)
|
log.Debugf("Network failed deleting routes by %s: %v", route.Router, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case <-netsync.C:
|
||||||
|
// get a list of node peers
|
||||||
|
peers := n.Peers()
|
||||||
|
// pick a random peer from the list of peers and request full sync
|
||||||
|
peer := n.node.GetPeerNode(peers[rnd.Intn(len(peers))].Id())
|
||||||
|
// skip if we can't find randmly selected peer
|
||||||
|
if peer == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
// get node peer graph to send back to the connecting node
|
||||||
|
node := PeersToProto(n.node, MaxDepth)
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}()
|
||||||
case <-resolve.C:
|
case <-resolve.C:
|
||||||
n.initNodes(false)
|
n.initNodes(false)
|
||||||
}
|
}
|
||||||
@ -1160,9 +1336,20 @@ func (n *network) sendTo(method, channel string, peer *node, msg proto.Message)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a unicast connection to the peer but don't do the open/accept flow
|
// Create a unicast connection to the peer but don't do the open/accept flow
|
||||||
c, err := n.tunnel.Dial(channel, tunnel.DialWait(false), tunnel.DialLink(peer.link))
|
c, err := n.tunnel.Dial(channel, tunnel.DialWait(false), tunnel.DialLink(peer.link))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if peerNode := n.GetPeerNode(peer.id); peerNode != nil {
|
||||||
|
log.Debugf("Network found peer %s: %v", peer.id, peerNode)
|
||||||
|
// update node status when error happens
|
||||||
|
peerNode.status.err.Update(err)
|
||||||
|
log.Debugf("Network increment node peer %p %v count to: %d", peerNode, peerNode, peerNode.status.Error().Count())
|
||||||
|
if count := peerNode.status.Error().Count(); count == MaxPeerErrors {
|
||||||
|
log.Debugf("Network node peer %v count exceeded %d: %d", peerNode, MaxPeerErrors, peerNode.status.Error().Count())
|
||||||
|
n.PrunePeer(peerNode.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
@ -1187,7 +1374,22 @@ func (n *network) sendTo(method, channel string, peer *node, msg proto.Message)
|
|||||||
tmsg.Header["Micro-Peer"] = peer.id
|
tmsg.Header["Micro-Peer"] = peer.id
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.Send(tmsg)
|
if err := c.Send(tmsg); err != nil {
|
||||||
|
// TODO: Lookup peer in our graph
|
||||||
|
if peerNode := n.GetPeerNode(peer.id); peerNode != nil {
|
||||||
|
log.Debugf("Network found peer %s: %v", peer.id, peerNode)
|
||||||
|
// update node status when error happens
|
||||||
|
peerNode.status.err.Update(err)
|
||||||
|
log.Debugf("Network increment node peer %p %v count to: %d", peerNode, peerNode, peerNode.status.Error().Count())
|
||||||
|
if count := peerNode.status.Error().Count(); count == MaxPeerErrors {
|
||||||
|
log.Debugf("Network node peer %v count exceeded %d: %d", peerNode, MaxPeerErrors, peerNode.status.Error().Count())
|
||||||
|
n.PrunePeer(peerNode.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendMsg sends a message to the tunnel channel
|
// sendMsg sends a message to the tunnel channel
|
||||||
@ -1318,6 +1520,9 @@ func (n *network) connect() {
|
|||||||
if !discovered {
|
if !discovered {
|
||||||
// recreate the clients because all the tunnel links are gone
|
// recreate the clients because all the tunnel links are gone
|
||||||
// so we haven't send discovery beneath
|
// so we haven't send discovery beneath
|
||||||
|
// NOTE: when starting the tunnel for the first time we might be recreating potentially
|
||||||
|
// well functioning tunnel clients as "discovered" will be false until the
|
||||||
|
// n.discovered channel is read at some point later on.
|
||||||
if err := n.createClients(); err != nil {
|
if err := n.createClients(); err != nil {
|
||||||
log.Debugf("Failed to recreate network/control clients: %v", err)
|
log.Debugf("Failed to recreate network/control clients: %v", err)
|
||||||
continue
|
continue
|
||||||
|
@ -19,11 +19,27 @@ var (
|
|||||||
AnnounceTime = 1 * time.Second
|
AnnounceTime = 1 * time.Second
|
||||||
// KeepAliveTime is the time in which we want to have sent a message to a peer
|
// KeepAliveTime is the time in which we want to have sent a message to a peer
|
||||||
KeepAliveTime = 30 * time.Second
|
KeepAliveTime = 30 * time.Second
|
||||||
|
// SyncTime is the time a network node requests full sync from the network
|
||||||
|
SyncTime = 1 * time.Minute
|
||||||
// PruneTime defines time interval to periodically check nodes that need to be pruned
|
// PruneTime defines time interval to periodically check nodes that need to be pruned
|
||||||
// due to their not announcing their presence within this time interval
|
// due to their not announcing their presence within this time interval
|
||||||
PruneTime = 90 * time.Second
|
PruneTime = 90 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Error is network node errors
|
||||||
|
type Error interface {
|
||||||
|
// Count is current count of errors
|
||||||
|
Count() int
|
||||||
|
// Msg is last error message
|
||||||
|
Msg() string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Status is node status
|
||||||
|
type Status interface {
|
||||||
|
// Error reports error status
|
||||||
|
Error() Error
|
||||||
|
}
|
||||||
|
|
||||||
// Node is network node
|
// Node is network node
|
||||||
type Node interface {
|
type Node interface {
|
||||||
// Id is node id
|
// Id is node id
|
||||||
@ -34,6 +50,8 @@ type Node interface {
|
|||||||
Peers() []Node
|
Peers() []Node
|
||||||
// Network is the network node is in
|
// Network is the network node is in
|
||||||
Network() Network
|
Network() Network
|
||||||
|
// Status returns node status
|
||||||
|
Status() Status
|
||||||
}
|
}
|
||||||
|
|
||||||
// Network is micro network
|
// Network is micro network
|
||||||
|
164
network/node.go
164
network/node.go
@ -21,6 +21,73 @@ var (
|
|||||||
ErrPeerNotFound = errors.New("peer not found")
|
ErrPeerNotFound = errors.New("peer not found")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// nerr tracks node errors
|
||||||
|
type nerr struct {
|
||||||
|
sync.RWMutex
|
||||||
|
count int
|
||||||
|
msg error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment increments node error count
|
||||||
|
func (e *nerr) Update(err error) {
|
||||||
|
e.Lock()
|
||||||
|
defer e.Unlock()
|
||||||
|
|
||||||
|
e.count++
|
||||||
|
e.msg = err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count returns node error count
|
||||||
|
func (e *nerr) Count() int {
|
||||||
|
e.RLock()
|
||||||
|
defer e.RUnlock()
|
||||||
|
|
||||||
|
return e.count
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *nerr) Msg() string {
|
||||||
|
e.RLock()
|
||||||
|
defer e.RUnlock()
|
||||||
|
|
||||||
|
if e.msg != nil {
|
||||||
|
return e.msg.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// status returns node status
|
||||||
|
type status struct {
|
||||||
|
sync.RWMutex
|
||||||
|
err *nerr
|
||||||
|
}
|
||||||
|
|
||||||
|
// newStatus creates
|
||||||
|
func newStatus() *status {
|
||||||
|
return &status{
|
||||||
|
err: new(nerr),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newPeerStatus(peer *pb.Peer) *status {
|
||||||
|
return &status{
|
||||||
|
err: &nerr{
|
||||||
|
count: int(peer.Node.Status.Error.Count),
|
||||||
|
msg: errors.New(peer.Node.Status.Error.Msg),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *status) Error() Error {
|
||||||
|
s.RLock()
|
||||||
|
defer s.RUnlock()
|
||||||
|
|
||||||
|
return &nerr{
|
||||||
|
count: s.err.count,
|
||||||
|
msg: s.err.msg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// node is network node
|
// node is network node
|
||||||
type node struct {
|
type node struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
@ -36,6 +103,10 @@ type node struct {
|
|||||||
network Network
|
network Network
|
||||||
// lastSeen keeps track of node lifetime and updates
|
// lastSeen keeps track of node lifetime and updates
|
||||||
lastSeen time.Time
|
lastSeen time.Time
|
||||||
|
// lastSync keeps track of node last sync request
|
||||||
|
lastSync time.Time
|
||||||
|
// err tracks node status
|
||||||
|
status *status
|
||||||
}
|
}
|
||||||
|
|
||||||
// Id is node ide
|
// Id is node ide
|
||||||
@ -53,6 +124,19 @@ func (n *node) Network() Network {
|
|||||||
return n.network
|
return n.network
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Status returns node status
|
||||||
|
func (n *node) Status() Status {
|
||||||
|
n.RLock()
|
||||||
|
defer n.RUnlock()
|
||||||
|
|
||||||
|
return &status{
|
||||||
|
err: &nerr{
|
||||||
|
count: n.status.err.count,
|
||||||
|
msg: n.status.err.msg,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// walk walks the node graph until some condition is met
|
// walk walks the node graph until some condition is met
|
||||||
func (n *node) walk(until func(peer *node) bool, action func(parent, peer *node)) map[string]*node {
|
func (n *node) walk(until func(peer *node) bool, action func(parent, peer *node)) map[string]*node {
|
||||||
// track the visited nodes
|
// track the visited nodes
|
||||||
@ -75,9 +159,9 @@ func (n *node) walk(until func(peer *node) bool, action func(parent, peer *node)
|
|||||||
// iterate through all of the node peers
|
// iterate through all of the node peers
|
||||||
// mark the visited nodes; enqueue the non-visted
|
// mark the visited nodes; enqueue the non-visted
|
||||||
for id, peer := range qnode.Value.(*node).peers {
|
for id, peer := range qnode.Value.(*node).peers {
|
||||||
|
action(qnode.Value.(*node), peer)
|
||||||
if _, ok := visited[id]; !ok {
|
if _, ok := visited[id]; !ok {
|
||||||
visited[id] = peer
|
visited[id] = peer
|
||||||
action(qnode.Value.(*node), peer)
|
|
||||||
queue.PushBack(peer)
|
queue.PushBack(peer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,7 +178,28 @@ func (n *node) AddPeer(peer *node) error {
|
|||||||
n.Lock()
|
n.Lock()
|
||||||
defer n.Unlock()
|
defer n.Unlock()
|
||||||
|
|
||||||
|
// get node topology: we need to check if the peer
|
||||||
|
// we are trying to add is already in our graph
|
||||||
|
top := n.getTopology(MaxDepth)
|
||||||
|
|
||||||
|
untilFoundPeer := func(n *node) bool {
|
||||||
|
return n.id == peer.id
|
||||||
|
}
|
||||||
|
|
||||||
|
justWalk := func(paent, node *node) {}
|
||||||
|
|
||||||
|
visited := top.walk(untilFoundPeer, justWalk)
|
||||||
|
|
||||||
|
peerNode, inTop := visited[peer.id]
|
||||||
|
|
||||||
if _, ok := n.peers[peer.id]; !ok {
|
if _, ok := n.peers[peer.id]; !ok {
|
||||||
|
if inTop {
|
||||||
|
// just create a new edge to the existing peer
|
||||||
|
// but make sure you update the peer link
|
||||||
|
peerNode.link = peer.link
|
||||||
|
n.peers[peer.id] = peerNode
|
||||||
|
return nil
|
||||||
|
}
|
||||||
n.peers[peer.id] = peer
|
n.peers[peer.id] = peer
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -127,7 +232,7 @@ func (n *node) UpdatePeer(peer *node) error {
|
|||||||
return ErrPeerNotFound
|
return ErrPeerNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// RefreshPeer updates node timestamp
|
// RefreshPeer updates node last seen timestamp
|
||||||
// It returns false if the peer has not been found.
|
// It returns false if the peer has not been found.
|
||||||
func (n *node) RefreshPeer(id, link string, now time.Time) error {
|
func (n *node) RefreshPeer(id, link string, now time.Time) error {
|
||||||
n.Lock()
|
n.Lock()
|
||||||
@ -146,6 +251,16 @@ func (n *node) RefreshPeer(id, link string, now time.Time) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RefreshSync refreshes nodes sync time
|
||||||
|
func (n *node) RefreshSync(now time.Time) error {
|
||||||
|
n.Lock()
|
||||||
|
defer n.Unlock()
|
||||||
|
|
||||||
|
n.lastSync = now
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Nodes returns a slice of all nodes in the whole node topology
|
// Nodes returns a slice of all nodes in the whole node topology
|
||||||
func (n *node) Nodes() []Node {
|
func (n *node) Nodes() []Node {
|
||||||
// we need to freeze the network graph here
|
// we need to freeze the network graph here
|
||||||
@ -217,7 +332,25 @@ func (n *node) DeletePeerNode(id string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PruneStalePeerNodes prune the peers that have not been seen for longer than given time
|
// PrunePeer prunes the peers with the given id
|
||||||
|
func (n *node) PrunePeer(id string) {
|
||||||
|
n.Lock()
|
||||||
|
defer n.Unlock()
|
||||||
|
|
||||||
|
untilNoMorePeers := func(node *node) bool {
|
||||||
|
return node == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
prunePeer := func(parent, node *node) {
|
||||||
|
if node.id != n.id && node.id == id {
|
||||||
|
delete(parent.peers, node.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
n.walk(untilNoMorePeers, prunePeer)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PruneStalePeerNodes prunes the peers that have not been seen for longer than pruneTime
|
||||||
// It returns a map of the the nodes that got pruned
|
// It returns a map of the the nodes that got pruned
|
||||||
func (n *node) PruneStalePeers(pruneTime time.Duration) map[string]*node {
|
func (n *node) PruneStalePeers(pruneTime time.Duration) map[string]*node {
|
||||||
n.Lock()
|
n.Lock()
|
||||||
@ -249,6 +382,7 @@ func (n *node) getTopology(depth uint) *node {
|
|||||||
address: n.address,
|
address: n.address,
|
||||||
peers: make(map[string]*node),
|
peers: make(map[string]*node),
|
||||||
network: n.network,
|
network: n.network,
|
||||||
|
status: n.status,
|
||||||
lastSeen: n.lastSeen,
|
lastSeen: n.lastSeen,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,9 +431,15 @@ func (n *node) Peers() []Node {
|
|||||||
// UnpackPeerTopology unpacks pb.Peer into node topology of given depth
|
// UnpackPeerTopology unpacks pb.Peer into node topology of given depth
|
||||||
func UnpackPeerTopology(pbPeer *pb.Peer, lastSeen time.Time, depth uint) *node {
|
func UnpackPeerTopology(pbPeer *pb.Peer, lastSeen time.Time, depth uint) *node {
|
||||||
peerNode := &node{
|
peerNode := &node{
|
||||||
id: pbPeer.Node.Id,
|
id: pbPeer.Node.Id,
|
||||||
address: pbPeer.Node.Address,
|
address: pbPeer.Node.Address,
|
||||||
peers: make(map[string]*node),
|
peers: make(map[string]*node),
|
||||||
|
status: &status{
|
||||||
|
err: &nerr{
|
||||||
|
count: int(pbPeer.Node.Status.Error.Count),
|
||||||
|
msg: errors.New(pbPeer.Node.Status.Error.Msg),
|
||||||
|
},
|
||||||
|
},
|
||||||
lastSeen: lastSeen,
|
lastSeen: lastSeen,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,6 +466,12 @@ func peerProtoTopology(peer Node, depth uint) *pb.Peer {
|
|||||||
node := &pb.Node{
|
node := &pb.Node{
|
||||||
Id: peer.Id(),
|
Id: peer.Id(),
|
||||||
Address: peer.Address(),
|
Address: peer.Address(),
|
||||||
|
Status: &pb.Status{
|
||||||
|
Error: &pb.Error{
|
||||||
|
Count: uint32(peer.Status().Error().Count()),
|
||||||
|
Msg: peer.Status().Error().Msg(),
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the network name if network is not nil
|
// set the network name if network is not nil
|
||||||
@ -361,6 +507,12 @@ func PeersToProto(node Node, depth uint) *pb.Peer {
|
|||||||
pbNode := &pb.Node{
|
pbNode := &pb.Node{
|
||||||
Id: node.Id(),
|
Id: node.Id(),
|
||||||
Address: node.Address(),
|
Address: node.Address(),
|
||||||
|
Status: &pb.Status{
|
||||||
|
Error: &pb.Error{
|
||||||
|
Count: uint32(node.Status().Error().Count()),
|
||||||
|
Msg: node.Status().Error().Msg(),
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the network name if network is not nil
|
// set the network name if network is not nil
|
||||||
|
@ -21,6 +21,7 @@ func testSetup() *node {
|
|||||||
address: testNodeAddress,
|
address: testNodeAddress,
|
||||||
peers: make(map[string]*node),
|
peers: make(map[string]*node),
|
||||||
network: newNetwork(Name(testNodeNetName)),
|
network: newNetwork(Name(testNodeNetName)),
|
||||||
|
status: newStatus(),
|
||||||
}
|
}
|
||||||
|
|
||||||
// add some peers to the node
|
// add some peers to the node
|
||||||
@ -30,6 +31,7 @@ func testSetup() *node {
|
|||||||
address: testNode.address + "-" + id,
|
address: testNode.address + "-" + id,
|
||||||
peers: make(map[string]*node),
|
peers: make(map[string]*node),
|
||||||
network: testNode.network,
|
network: testNode.network,
|
||||||
|
status: newStatus(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,6 +43,7 @@ func testSetup() *node {
|
|||||||
address: testNode.address + "-" + id,
|
address: testNode.address + "-" + id,
|
||||||
peers: make(map[string]*node),
|
peers: make(map[string]*node),
|
||||||
network: testNode.network,
|
network: testNode.network,
|
||||||
|
status: newStatus(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,21 +218,53 @@ func TestDeletePeerNode(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPruneStalePeerNodes(t *testing.T) {
|
func TestPrunePeer(t *testing.T) {
|
||||||
// complicated node graph
|
// complicated node graph
|
||||||
node := testSetup()
|
node := testSetup()
|
||||||
|
|
||||||
nodes := node.Nodes()
|
before := node.Nodes()
|
||||||
|
|
||||||
|
node.PrunePeer("peer3")
|
||||||
|
|
||||||
|
now := node.Nodes()
|
||||||
|
|
||||||
|
if len(now) != len(before)-1 {
|
||||||
|
t.Errorf("Expected pruned node count: %d, got: %d", len(before)-1, len(now))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPruneStalePeers(t *testing.T) {
|
||||||
|
// complicated node graph
|
||||||
|
node := testSetup()
|
||||||
|
nodes := node.Nodes()
|
||||||
|
// this will delete all nodes besides the root node
|
||||||
pruneTime := 10 * time.Millisecond
|
pruneTime := 10 * time.Millisecond
|
||||||
time.Sleep(pruneTime)
|
time.Sleep(pruneTime)
|
||||||
|
|
||||||
// should delete all nodes besides node
|
// should delete all nodes besides (root) node
|
||||||
pruned := node.PruneStalePeers(pruneTime)
|
pruned := node.PruneStalePeers(pruneTime)
|
||||||
|
|
||||||
if len(pruned) != len(nodes)-1 {
|
if len(pruned) != len(nodes)-1 {
|
||||||
t.Errorf("Expected pruned node count: %d, got: %d", len(nodes)-1, len(pruned))
|
t.Errorf("Expected pruned node count: %d, got: %d", len(nodes)-1, len(pruned))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// complicated node graph
|
||||||
|
node = testSetup()
|
||||||
|
nodes = node.Nodes()
|
||||||
|
|
||||||
|
// set prune time to 100ms and wait for half of it
|
||||||
|
pruneTime = 100 * time.Millisecond
|
||||||
|
time.Sleep(pruneTime)
|
||||||
|
|
||||||
|
// update the time of peer1
|
||||||
|
node.peers["peer1"].lastSeen = time.Now()
|
||||||
|
|
||||||
|
// should prune all but the root nodes and peer1
|
||||||
|
pruned = node.PruneStalePeers(pruneTime)
|
||||||
|
|
||||||
|
if len(pruned) != len(nodes)-2 {
|
||||||
|
t.Errorf("Expected pruned node count: %d, got: %d", len(nodes)-2, len(pruned))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnpackPeerTopology(t *testing.T) {
|
func TestUnpackPeerTopology(t *testing.T) {
|
||||||
@ -237,6 +272,9 @@ func TestUnpackPeerTopology(t *testing.T) {
|
|||||||
Node: &pb.Node{
|
Node: &pb.Node{
|
||||||
Id: "newPeer",
|
Id: "newPeer",
|
||||||
Address: "newPeerAddress",
|
Address: "newPeerAddress",
|
||||||
|
Status: &pb.Status{
|
||||||
|
Error: &pb.Error{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Peers: make([]*pb.Peer, 0),
|
Peers: make([]*pb.Peer, 0),
|
||||||
}
|
}
|
||||||
@ -252,12 +290,18 @@ func TestUnpackPeerTopology(t *testing.T) {
|
|||||||
pbPeer1Node := &pb.Node{
|
pbPeer1Node := &pb.Node{
|
||||||
Id: peer1.id,
|
Id: peer1.id,
|
||||||
Address: peer1.address,
|
Address: peer1.address,
|
||||||
|
Status: &pb.Status{
|
||||||
|
Error: &pb.Error{},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pbPeer111 := &pb.Peer{
|
pbPeer111 := &pb.Peer{
|
||||||
Node: &pb.Node{
|
Node: &pb.Node{
|
||||||
Id: "peer111",
|
Id: "peer111",
|
||||||
Address: "peer111Address",
|
Address: "peer111Address",
|
||||||
|
Status: &pb.Status{
|
||||||
|
Error: &pb.Error{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Peers: make([]*pb.Peer, 0),
|
Peers: make([]*pb.Peer, 0),
|
||||||
}
|
}
|
||||||
@ -266,6 +310,9 @@ func TestUnpackPeerTopology(t *testing.T) {
|
|||||||
Node: &pb.Node{
|
Node: &pb.Node{
|
||||||
Id: "peer121",
|
Id: "peer121",
|
||||||
Address: "peer121Address",
|
Address: "peer121Address",
|
||||||
|
Status: &pb.Status{
|
||||||
|
Error: &pb.Error{},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Peers: make([]*pb.Peer, 0),
|
Peers: make([]*pb.Peer, 0),
|
||||||
}
|
}
|
||||||
@ -292,6 +339,7 @@ func TestPeersToProto(t *testing.T) {
|
|||||||
address: testNodeAddress,
|
address: testNodeAddress,
|
||||||
peers: make(map[string]*node),
|
peers: make(map[string]*node),
|
||||||
network: newNetwork(Name(testNodeNetName)),
|
network: newNetwork(Name(testNodeNetName)),
|
||||||
|
status: newStatus(),
|
||||||
}
|
}
|
||||||
topCount := 0
|
topCount := 0
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// source: github.com/micro/go-micro/network/proto/network.proto
|
// source: network.proto
|
||||||
|
|
||||||
package go_micro_network
|
package go_micro_network
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ func (m *Query) Reset() { *m = Query{} }
|
|||||||
func (m *Query) String() string { return proto.CompactTextString(m) }
|
func (m *Query) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Query) ProtoMessage() {}
|
func (*Query) ProtoMessage() {}
|
||||||
func (*Query) Descriptor() ([]byte, []int) {
|
func (*Query) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_0b7953b26a7c4730, []int{0}
|
return fileDescriptor_8571034d60397816, []int{0}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Query) XXX_Unmarshal(b []byte) error {
|
func (m *Query) XXX_Unmarshal(b []byte) error {
|
||||||
@ -104,7 +104,7 @@ func (m *ConnectRequest) Reset() { *m = ConnectRequest{} }
|
|||||||
func (m *ConnectRequest) String() string { return proto.CompactTextString(m) }
|
func (m *ConnectRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ConnectRequest) ProtoMessage() {}
|
func (*ConnectRequest) ProtoMessage() {}
|
||||||
func (*ConnectRequest) Descriptor() ([]byte, []int) {
|
func (*ConnectRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_0b7953b26a7c4730, []int{1}
|
return fileDescriptor_8571034d60397816, []int{1}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ConnectRequest) XXX_Unmarshal(b []byte) error {
|
func (m *ConnectRequest) XXX_Unmarshal(b []byte) error {
|
||||||
@ -142,7 +142,7 @@ func (m *ConnectResponse) Reset() { *m = ConnectResponse{} }
|
|||||||
func (m *ConnectResponse) String() string { return proto.CompactTextString(m) }
|
func (m *ConnectResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ConnectResponse) ProtoMessage() {}
|
func (*ConnectResponse) ProtoMessage() {}
|
||||||
func (*ConnectResponse) Descriptor() ([]byte, []int) {
|
func (*ConnectResponse) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_0b7953b26a7c4730, []int{2}
|
return fileDescriptor_8571034d60397816, []int{2}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ConnectResponse) XXX_Unmarshal(b []byte) error {
|
func (m *ConnectResponse) XXX_Unmarshal(b []byte) error {
|
||||||
@ -176,7 +176,7 @@ func (m *NodesRequest) Reset() { *m = NodesRequest{} }
|
|||||||
func (m *NodesRequest) String() string { return proto.CompactTextString(m) }
|
func (m *NodesRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*NodesRequest) ProtoMessage() {}
|
func (*NodesRequest) ProtoMessage() {}
|
||||||
func (*NodesRequest) Descriptor() ([]byte, []int) {
|
func (*NodesRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_0b7953b26a7c4730, []int{3}
|
return fileDescriptor_8571034d60397816, []int{3}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *NodesRequest) XXX_Unmarshal(b []byte) error {
|
func (m *NodesRequest) XXX_Unmarshal(b []byte) error {
|
||||||
@ -217,7 +217,7 @@ func (m *NodesResponse) Reset() { *m = NodesResponse{} }
|
|||||||
func (m *NodesResponse) String() string { return proto.CompactTextString(m) }
|
func (m *NodesResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*NodesResponse) ProtoMessage() {}
|
func (*NodesResponse) ProtoMessage() {}
|
||||||
func (*NodesResponse) Descriptor() ([]byte, []int) {
|
func (*NodesResponse) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_0b7953b26a7c4730, []int{4}
|
return fileDescriptor_8571034d60397816, []int{4}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *NodesResponse) XXX_Unmarshal(b []byte) error {
|
func (m *NodesResponse) XXX_Unmarshal(b []byte) error {
|
||||||
@ -257,7 +257,7 @@ func (m *GraphRequest) Reset() { *m = GraphRequest{} }
|
|||||||
func (m *GraphRequest) String() string { return proto.CompactTextString(m) }
|
func (m *GraphRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*GraphRequest) ProtoMessage() {}
|
func (*GraphRequest) ProtoMessage() {}
|
||||||
func (*GraphRequest) Descriptor() ([]byte, []int) {
|
func (*GraphRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_0b7953b26a7c4730, []int{5}
|
return fileDescriptor_8571034d60397816, []int{5}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *GraphRequest) XXX_Unmarshal(b []byte) error {
|
func (m *GraphRequest) XXX_Unmarshal(b []byte) error {
|
||||||
@ -296,7 +296,7 @@ func (m *GraphResponse) Reset() { *m = GraphResponse{} }
|
|||||||
func (m *GraphResponse) String() string { return proto.CompactTextString(m) }
|
func (m *GraphResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*GraphResponse) ProtoMessage() {}
|
func (*GraphResponse) ProtoMessage() {}
|
||||||
func (*GraphResponse) Descriptor() ([]byte, []int) {
|
func (*GraphResponse) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_0b7953b26a7c4730, []int{6}
|
return fileDescriptor_8571034d60397816, []int{6}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *GraphResponse) XXX_Unmarshal(b []byte) error {
|
func (m *GraphResponse) XXX_Unmarshal(b []byte) error {
|
||||||
@ -336,7 +336,7 @@ func (m *RoutesRequest) Reset() { *m = RoutesRequest{} }
|
|||||||
func (m *RoutesRequest) String() string { return proto.CompactTextString(m) }
|
func (m *RoutesRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*RoutesRequest) ProtoMessage() {}
|
func (*RoutesRequest) ProtoMessage() {}
|
||||||
func (*RoutesRequest) Descriptor() ([]byte, []int) {
|
func (*RoutesRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_0b7953b26a7c4730, []int{7}
|
return fileDescriptor_8571034d60397816, []int{7}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *RoutesRequest) XXX_Unmarshal(b []byte) error {
|
func (m *RoutesRequest) XXX_Unmarshal(b []byte) error {
|
||||||
@ -375,7 +375,7 @@ func (m *RoutesResponse) Reset() { *m = RoutesResponse{} }
|
|||||||
func (m *RoutesResponse) String() string { return proto.CompactTextString(m) }
|
func (m *RoutesResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*RoutesResponse) ProtoMessage() {}
|
func (*RoutesResponse) ProtoMessage() {}
|
||||||
func (*RoutesResponse) Descriptor() ([]byte, []int) {
|
func (*RoutesResponse) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_0b7953b26a7c4730, []int{8}
|
return fileDescriptor_8571034d60397816, []int{8}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *RoutesResponse) XXX_Unmarshal(b []byte) error {
|
func (m *RoutesResponse) XXX_Unmarshal(b []byte) error {
|
||||||
@ -413,7 +413,7 @@ func (m *ServicesRequest) Reset() { *m = ServicesRequest{} }
|
|||||||
func (m *ServicesRequest) String() string { return proto.CompactTextString(m) }
|
func (m *ServicesRequest) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ServicesRequest) ProtoMessage() {}
|
func (*ServicesRequest) ProtoMessage() {}
|
||||||
func (*ServicesRequest) Descriptor() ([]byte, []int) {
|
func (*ServicesRequest) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_0b7953b26a7c4730, []int{9}
|
return fileDescriptor_8571034d60397816, []int{9}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ServicesRequest) XXX_Unmarshal(b []byte) error {
|
func (m *ServicesRequest) XXX_Unmarshal(b []byte) error {
|
||||||
@ -445,7 +445,7 @@ func (m *ServicesResponse) Reset() { *m = ServicesResponse{} }
|
|||||||
func (m *ServicesResponse) String() string { return proto.CompactTextString(m) }
|
func (m *ServicesResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*ServicesResponse) ProtoMessage() {}
|
func (*ServicesResponse) ProtoMessage() {}
|
||||||
func (*ServicesResponse) Descriptor() ([]byte, []int) {
|
func (*ServicesResponse) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_0b7953b26a7c4730, []int{10}
|
return fileDescriptor_8571034d60397816, []int{10}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ServicesResponse) XXX_Unmarshal(b []byte) error {
|
func (m *ServicesResponse) XXX_Unmarshal(b []byte) error {
|
||||||
@ -473,6 +473,164 @@ func (m *ServicesResponse) GetServices() []string {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type StatusRequest struct {
|
||||||
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
XXX_sizecache int32 `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *StatusRequest) Reset() { *m = StatusRequest{} }
|
||||||
|
func (m *StatusRequest) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*StatusRequest) ProtoMessage() {}
|
||||||
|
func (*StatusRequest) Descriptor() ([]byte, []int) {
|
||||||
|
return fileDescriptor_8571034d60397816, []int{11}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *StatusRequest) XXX_Unmarshal(b []byte) error {
|
||||||
|
return xxx_messageInfo_StatusRequest.Unmarshal(m, b)
|
||||||
|
}
|
||||||
|
func (m *StatusRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
|
return xxx_messageInfo_StatusRequest.Marshal(b, m, deterministic)
|
||||||
|
}
|
||||||
|
func (m *StatusRequest) XXX_Merge(src proto.Message) {
|
||||||
|
xxx_messageInfo_StatusRequest.Merge(m, src)
|
||||||
|
}
|
||||||
|
func (m *StatusRequest) XXX_Size() int {
|
||||||
|
return xxx_messageInfo_StatusRequest.Size(m)
|
||||||
|
}
|
||||||
|
func (m *StatusRequest) XXX_DiscardUnknown() {
|
||||||
|
xxx_messageInfo_StatusRequest.DiscardUnknown(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
var xxx_messageInfo_StatusRequest proto.InternalMessageInfo
|
||||||
|
|
||||||
|
type StatusResponse struct {
|
||||||
|
Status *Status `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"`
|
||||||
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
XXX_sizecache int32 `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *StatusResponse) Reset() { *m = StatusResponse{} }
|
||||||
|
func (m *StatusResponse) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*StatusResponse) ProtoMessage() {}
|
||||||
|
func (*StatusResponse) Descriptor() ([]byte, []int) {
|
||||||
|
return fileDescriptor_8571034d60397816, []int{12}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *StatusResponse) XXX_Unmarshal(b []byte) error {
|
||||||
|
return xxx_messageInfo_StatusResponse.Unmarshal(m, b)
|
||||||
|
}
|
||||||
|
func (m *StatusResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
|
return xxx_messageInfo_StatusResponse.Marshal(b, m, deterministic)
|
||||||
|
}
|
||||||
|
func (m *StatusResponse) XXX_Merge(src proto.Message) {
|
||||||
|
xxx_messageInfo_StatusResponse.Merge(m, src)
|
||||||
|
}
|
||||||
|
func (m *StatusResponse) XXX_Size() int {
|
||||||
|
return xxx_messageInfo_StatusResponse.Size(m)
|
||||||
|
}
|
||||||
|
func (m *StatusResponse) XXX_DiscardUnknown() {
|
||||||
|
xxx_messageInfo_StatusResponse.DiscardUnknown(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
var xxx_messageInfo_StatusResponse proto.InternalMessageInfo
|
||||||
|
|
||||||
|
func (m *StatusResponse) GetStatus() *Status {
|
||||||
|
if m != nil {
|
||||||
|
return m.Status
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error tracks network errors
|
||||||
|
type Error struct {
|
||||||
|
Count uint32 `protobuf:"varint,1,opt,name=count,proto3" json:"count,omitempty"`
|
||||||
|
Msg string `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"`
|
||||||
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
XXX_sizecache int32 `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Error) Reset() { *m = Error{} }
|
||||||
|
func (m *Error) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*Error) ProtoMessage() {}
|
||||||
|
func (*Error) Descriptor() ([]byte, []int) {
|
||||||
|
return fileDescriptor_8571034d60397816, []int{13}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Error) XXX_Unmarshal(b []byte) error {
|
||||||
|
return xxx_messageInfo_Error.Unmarshal(m, b)
|
||||||
|
}
|
||||||
|
func (m *Error) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
|
return xxx_messageInfo_Error.Marshal(b, m, deterministic)
|
||||||
|
}
|
||||||
|
func (m *Error) XXX_Merge(src proto.Message) {
|
||||||
|
xxx_messageInfo_Error.Merge(m, src)
|
||||||
|
}
|
||||||
|
func (m *Error) XXX_Size() int {
|
||||||
|
return xxx_messageInfo_Error.Size(m)
|
||||||
|
}
|
||||||
|
func (m *Error) XXX_DiscardUnknown() {
|
||||||
|
xxx_messageInfo_Error.DiscardUnknown(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
var xxx_messageInfo_Error proto.InternalMessageInfo
|
||||||
|
|
||||||
|
func (m *Error) GetCount() uint32 {
|
||||||
|
if m != nil {
|
||||||
|
return m.Count
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Error) GetMsg() string {
|
||||||
|
if m != nil {
|
||||||
|
return m.Msg
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Status is node status
|
||||||
|
type Status struct {
|
||||||
|
Error *Error `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"`
|
||||||
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
XXX_sizecache int32 `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Status) Reset() { *m = Status{} }
|
||||||
|
func (m *Status) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*Status) ProtoMessage() {}
|
||||||
|
func (*Status) Descriptor() ([]byte, []int) {
|
||||||
|
return fileDescriptor_8571034d60397816, []int{14}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Status) XXX_Unmarshal(b []byte) error {
|
||||||
|
return xxx_messageInfo_Status.Unmarshal(m, b)
|
||||||
|
}
|
||||||
|
func (m *Status) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
|
return xxx_messageInfo_Status.Marshal(b, m, deterministic)
|
||||||
|
}
|
||||||
|
func (m *Status) XXX_Merge(src proto.Message) {
|
||||||
|
xxx_messageInfo_Status.Merge(m, src)
|
||||||
|
}
|
||||||
|
func (m *Status) XXX_Size() int {
|
||||||
|
return xxx_messageInfo_Status.Size(m)
|
||||||
|
}
|
||||||
|
func (m *Status) XXX_DiscardUnknown() {
|
||||||
|
xxx_messageInfo_Status.DiscardUnknown(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
var xxx_messageInfo_Status proto.InternalMessageInfo
|
||||||
|
|
||||||
|
func (m *Status) GetError() *Error {
|
||||||
|
if m != nil {
|
||||||
|
return m.Error
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Node is network node
|
// Node is network node
|
||||||
type Node struct {
|
type Node struct {
|
||||||
// node id
|
// node id
|
||||||
@ -482,17 +640,19 @@ type Node struct {
|
|||||||
// the network
|
// the network
|
||||||
Network string `protobuf:"bytes,3,opt,name=network,proto3" json:"network,omitempty"`
|
Network string `protobuf:"bytes,3,opt,name=network,proto3" json:"network,omitempty"`
|
||||||
// associated metadata
|
// associated metadata
|
||||||
Metadata map[string]string `protobuf:"bytes,4,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
Metadata map[string]string `protobuf:"bytes,4,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
// node status
|
||||||
XXX_unrecognized []byte `json:"-"`
|
Status *Status `protobuf:"bytes,5,opt,name=status,proto3" json:"status,omitempty"`
|
||||||
XXX_sizecache int32 `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
XXX_sizecache int32 `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Node) Reset() { *m = Node{} }
|
func (m *Node) Reset() { *m = Node{} }
|
||||||
func (m *Node) String() string { return proto.CompactTextString(m) }
|
func (m *Node) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Node) ProtoMessage() {}
|
func (*Node) ProtoMessage() {}
|
||||||
func (*Node) Descriptor() ([]byte, []int) {
|
func (*Node) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_0b7953b26a7c4730, []int{11}
|
return fileDescriptor_8571034d60397816, []int{15}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Node) XXX_Unmarshal(b []byte) error {
|
func (m *Node) XXX_Unmarshal(b []byte) error {
|
||||||
@ -541,6 +701,13 @@ func (m *Node) GetMetadata() map[string]string {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Node) GetStatus() *Status {
|
||||||
|
if m != nil {
|
||||||
|
return m.Status
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Connect is sent when the node connects to the network
|
// Connect is sent when the node connects to the network
|
||||||
type Connect struct {
|
type Connect struct {
|
||||||
// network mode
|
// network mode
|
||||||
@ -554,7 +721,7 @@ func (m *Connect) Reset() { *m = Connect{} }
|
|||||||
func (m *Connect) String() string { return proto.CompactTextString(m) }
|
func (m *Connect) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Connect) ProtoMessage() {}
|
func (*Connect) ProtoMessage() {}
|
||||||
func (*Connect) Descriptor() ([]byte, []int) {
|
func (*Connect) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_0b7953b26a7c4730, []int{12}
|
return fileDescriptor_8571034d60397816, []int{16}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Connect) XXX_Unmarshal(b []byte) error {
|
func (m *Connect) XXX_Unmarshal(b []byte) error {
|
||||||
@ -595,7 +762,7 @@ func (m *Close) Reset() { *m = Close{} }
|
|||||||
func (m *Close) String() string { return proto.CompactTextString(m) }
|
func (m *Close) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Close) ProtoMessage() {}
|
func (*Close) ProtoMessage() {}
|
||||||
func (*Close) Descriptor() ([]byte, []int) {
|
func (*Close) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_0b7953b26a7c4730, []int{13}
|
return fileDescriptor_8571034d60397816, []int{17}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Close) XXX_Unmarshal(b []byte) error {
|
func (m *Close) XXX_Unmarshal(b []byte) error {
|
||||||
@ -638,7 +805,7 @@ func (m *Peer) Reset() { *m = Peer{} }
|
|||||||
func (m *Peer) String() string { return proto.CompactTextString(m) }
|
func (m *Peer) String() string { return proto.CompactTextString(m) }
|
||||||
func (*Peer) ProtoMessage() {}
|
func (*Peer) ProtoMessage() {}
|
||||||
func (*Peer) Descriptor() ([]byte, []int) {
|
func (*Peer) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_0b7953b26a7c4730, []int{14}
|
return fileDescriptor_8571034d60397816, []int{18}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Peer) XXX_Unmarshal(b []byte) error {
|
func (m *Peer) XXX_Unmarshal(b []byte) error {
|
||||||
@ -673,6 +840,56 @@ func (m *Peer) GetPeers() []*Peer {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sync is network sync message
|
||||||
|
type Sync struct {
|
||||||
|
// peer origin
|
||||||
|
Peer *Peer `protobuf:"bytes,1,opt,name=peer,proto3" json:"peer,omitempty"`
|
||||||
|
// node routes
|
||||||
|
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:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Sync) Reset() { *m = Sync{} }
|
||||||
|
func (m *Sync) String() string { return proto.CompactTextString(m) }
|
||||||
|
func (*Sync) ProtoMessage() {}
|
||||||
|
func (*Sync) Descriptor() ([]byte, []int) {
|
||||||
|
return fileDescriptor_8571034d60397816, []int{19}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Sync) XXX_Unmarshal(b []byte) error {
|
||||||
|
return xxx_messageInfo_Sync.Unmarshal(m, b)
|
||||||
|
}
|
||||||
|
func (m *Sync) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
|
return xxx_messageInfo_Sync.Marshal(b, m, deterministic)
|
||||||
|
}
|
||||||
|
func (m *Sync) XXX_Merge(src proto.Message) {
|
||||||
|
xxx_messageInfo_Sync.Merge(m, src)
|
||||||
|
}
|
||||||
|
func (m *Sync) XXX_Size() int {
|
||||||
|
return xxx_messageInfo_Sync.Size(m)
|
||||||
|
}
|
||||||
|
func (m *Sync) XXX_DiscardUnknown() {
|
||||||
|
xxx_messageInfo_Sync.DiscardUnknown(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
var xxx_messageInfo_Sync proto.InternalMessageInfo
|
||||||
|
|
||||||
|
func (m *Sync) GetPeer() *Peer {
|
||||||
|
if m != nil {
|
||||||
|
return m.Peer
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Sync) GetRoutes() []*proto1.Route {
|
||||||
|
if m != nil {
|
||||||
|
return m.Routes
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
proto.RegisterType((*Query)(nil), "go.micro.network.Query")
|
proto.RegisterType((*Query)(nil), "go.micro.network.Query")
|
||||||
proto.RegisterType((*ConnectRequest)(nil), "go.micro.network.ConnectRequest")
|
proto.RegisterType((*ConnectRequest)(nil), "go.micro.network.ConnectRequest")
|
||||||
@ -685,53 +902,63 @@ func init() {
|
|||||||
proto.RegisterType((*RoutesResponse)(nil), "go.micro.network.RoutesResponse")
|
proto.RegisterType((*RoutesResponse)(nil), "go.micro.network.RoutesResponse")
|
||||||
proto.RegisterType((*ServicesRequest)(nil), "go.micro.network.ServicesRequest")
|
proto.RegisterType((*ServicesRequest)(nil), "go.micro.network.ServicesRequest")
|
||||||
proto.RegisterType((*ServicesResponse)(nil), "go.micro.network.ServicesResponse")
|
proto.RegisterType((*ServicesResponse)(nil), "go.micro.network.ServicesResponse")
|
||||||
|
proto.RegisterType((*StatusRequest)(nil), "go.micro.network.StatusRequest")
|
||||||
|
proto.RegisterType((*StatusResponse)(nil), "go.micro.network.StatusResponse")
|
||||||
|
proto.RegisterType((*Error)(nil), "go.micro.network.Error")
|
||||||
|
proto.RegisterType((*Status)(nil), "go.micro.network.Status")
|
||||||
proto.RegisterType((*Node)(nil), "go.micro.network.Node")
|
proto.RegisterType((*Node)(nil), "go.micro.network.Node")
|
||||||
proto.RegisterMapType((map[string]string)(nil), "go.micro.network.Node.MetadataEntry")
|
proto.RegisterMapType((map[string]string)(nil), "go.micro.network.Node.MetadataEntry")
|
||||||
proto.RegisterType((*Connect)(nil), "go.micro.network.Connect")
|
proto.RegisterType((*Connect)(nil), "go.micro.network.Connect")
|
||||||
proto.RegisterType((*Close)(nil), "go.micro.network.Close")
|
proto.RegisterType((*Close)(nil), "go.micro.network.Close")
|
||||||
proto.RegisterType((*Peer)(nil), "go.micro.network.Peer")
|
proto.RegisterType((*Peer)(nil), "go.micro.network.Peer")
|
||||||
|
proto.RegisterType((*Sync)(nil), "go.micro.network.Sync")
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() { proto.RegisterFile("network.proto", fileDescriptor_8571034d60397816) }
|
||||||
proto.RegisterFile("github.com/micro/go-micro/network/proto/network.proto", fileDescriptor_0b7953b26a7c4730)
|
|
||||||
}
|
|
||||||
|
|
||||||
var fileDescriptor_0b7953b26a7c4730 = []byte{
|
var fileDescriptor_8571034d60397816 = []byte{
|
||||||
// 576 bytes of a gzipped FileDescriptorProto
|
// 678 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0x61, 0x6a, 0xdb, 0x4c,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0xdd, 0x4e, 0xdb, 0x30,
|
||||||
0x10, 0x8d, 0x2c, 0xcb, 0x76, 0xe6, 0x8b, 0xfd, 0xb9, 0x4b, 0x49, 0x85, 0x7e, 0xb4, 0xee, 0xe2,
|
0x14, 0xa6, 0x6d, 0x52, 0xe0, 0x8c, 0x14, 0x66, 0x4d, 0x2c, 0xca, 0xc5, 0xe8, 0x2c, 0x2e, 0xd0,
|
||||||
0x1f, 0xa1, 0x34, 0x32, 0x24, 0x04, 0x4a, 0x4d, 0x43, 0x20, 0x94, 0x42, 0x21, 0x21, 0x55, 0x2e,
|
0x34, 0xd2, 0x09, 0x34, 0x6d, 0x1a, 0x1a, 0x42, 0x43, 0x68, 0xd2, 0x24, 0x10, 0x4b, 0x5f, 0x60,
|
||||||
0x50, 0xc5, 0x1a, 0x6c, 0x93, 0x58, 0xeb, 0xac, 0xd6, 0x09, 0x3e, 0x41, 0x8f, 0xd0, 0x33, 0xf5,
|
0x21, 0xb1, 0x4a, 0x05, 0x8d, 0x8b, 0xe3, 0x80, 0xfa, 0x04, 0x7b, 0xd3, 0xbd, 0xc4, 0x6e, 0x26,
|
||||||
0x56, 0x65, 0x77, 0x47, 0x8a, 0x1d, 0xcb, 0xa2, 0xf9, 0xe7, 0xd1, 0xbc, 0xf7, 0x66, 0x67, 0xe6,
|
0xdb, 0x27, 0x21, 0xa1, 0x49, 0x57, 0xee, 0x72, 0xec, 0xef, 0x3b, 0xc7, 0xe7, 0xef, 0x0b, 0x38,
|
||||||
0x8d, 0xe1, 0x64, 0x3c, 0x55, 0x93, 0xc5, 0x4d, 0x38, 0x12, 0xb3, 0xc1, 0x6c, 0x3a, 0x92, 0x62,
|
0x09, 0x93, 0x0f, 0x5c, 0xdc, 0xf8, 0x53, 0xc1, 0x25, 0x27, 0x5b, 0x23, 0xee, 0x4f, 0xc6, 0x91,
|
||||||
0x30, 0x16, 0x87, 0xf6, 0x47, 0x8a, 0xea, 0x51, 0xc8, 0xdb, 0xc1, 0x5c, 0x0a, 0x55, 0x44, 0xa1,
|
0xe0, 0x3e, 0x9e, 0x7b, 0x47, 0xa3, 0xb1, 0xbc, 0xce, 0xae, 0xfc, 0x88, 0x4f, 0x06, 0xfa, 0x66,
|
||||||
0x89, 0x58, 0x77, 0x2c, 0x42, 0x83, 0x0a, 0xe9, 0x7b, 0x30, 0xdc, 0x2e, 0x24, 0xc5, 0x42, 0xa1,
|
0x30, 0xe2, 0xfb, 0xe6, 0x43, 0xf0, 0x4c, 0x32, 0x31, 0x48, 0x99, 0xb8, 0x1f, 0x47, 0x6c, 0xa0,
|
||||||
0x1c, 0x64, 0x28, 0x1f, 0xa6, 0x23, 0x24, 0x3d, 0xfb, 0xd1, 0xca, 0xf1, 0x5f, 0x0e, 0x78, 0x3f,
|
0x3d, 0xe0, 0xa1, 0x71, 0x47, 0x7f, 0xb7, 0xc0, 0xfe, 0x99, 0x31, 0x31, 0x23, 0x2e, 0xac, 0x22,
|
||||||
0x16, 0x28, 0x97, 0xcc, 0x87, 0x26, 0xe1, 0x7c, 0xa7, 0xe7, 0x1c, 0xec, 0x46, 0x79, 0xa8, 0x33,
|
0xce, 0x6d, 0xf5, 0x5b, 0x7b, 0xeb, 0x41, 0x6e, 0xaa, 0x9b, 0x30, 0x8e, 0x05, 0x4b, 0x53, 0xb7,
|
||||||
0x71, 0x92, 0x48, 0xcc, 0x32, 0xbf, 0x66, 0x33, 0x14, 0xea, 0xcc, 0x38, 0x56, 0xf8, 0x18, 0x2f,
|
0x6d, 0x6e, 0xd0, 0x54, 0x37, 0xa3, 0x50, 0xb2, 0x87, 0x70, 0xe6, 0x76, 0xcc, 0x0d, 0x9a, 0x64,
|
||||||
0x7d, 0xd7, 0x66, 0x28, 0x64, 0xfb, 0xd0, 0xb0, 0x75, 0xfc, 0xba, 0x49, 0x50, 0xa4, 0x19, 0xf4,
|
0x1b, 0xba, 0x26, 0x8e, 0x6b, 0xe9, 0x0b, 0xb4, 0x14, 0x03, 0xdf, 0xed, 0xda, 0x86, 0x81, 0x26,
|
||||||
0x6e, 0xdf, 0xb3, 0x0c, 0x0a, 0xf9, 0x29, 0x74, 0xce, 0x45, 0x9a, 0xe2, 0x48, 0x45, 0x78, 0xbf,
|
0x3d, 0x86, 0xde, 0x29, 0x4f, 0x12, 0x16, 0xc9, 0x80, 0xdd, 0x65, 0x2c, 0x95, 0xe4, 0x3d, 0xd8,
|
||||||
0xc0, 0x4c, 0xb1, 0x8f, 0xe0, 0xa5, 0x22, 0xc1, 0xcc, 0x77, 0x7a, 0xee, 0xc1, 0x7f, 0x47, 0xfb,
|
0x09, 0x8f, 0x59, 0xea, 0xb6, 0xfa, 0x9d, 0xbd, 0x17, 0x07, 0xdb, 0xfe, 0xd3, 0xd4, 0xfd, 0x0b,
|
||||||
0xe1, 0xf3, 0xd6, 0xc3, 0x4b, 0x91, 0x60, 0x64, 0x41, 0xfc, 0x15, 0xfc, 0x5f, 0xf0, 0xb3, 0xb9,
|
0x1e, 0xb3, 0xc0, 0x80, 0xe8, 0x4b, 0xd8, 0x2c, 0xf8, 0xe9, 0x94, 0x27, 0x29, 0xa3, 0xbb, 0xb0,
|
||||||
0x48, 0x33, 0xe4, 0x7d, 0xd8, 0xd3, 0x88, 0x2c, 0x17, 0x7c, 0x0d, 0x5e, 0x82, 0x73, 0x35, 0x31,
|
0xa1, 0x10, 0x69, 0xee, 0xf0, 0x15, 0xd8, 0x31, 0x9b, 0xca, 0x6b, 0x9d, 0xa0, 0x13, 0x18, 0x83,
|
||||||
0x0d, 0xb6, 0x23, 0x1b, 0xf0, 0x2f, 0xd0, 0x26, 0x94, 0xa5, 0xbd, 0xb0, 0x6e, 0x1f, 0xf6, 0xbe,
|
0x7e, 0x05, 0x07, 0x51, 0x86, 0xf6, 0xcc, 0xb8, 0xbb, 0xb0, 0xf1, 0x5d, 0x84, 0xd3, 0xeb, 0xc5,
|
||||||
0xc9, 0x78, 0x3e, 0xa9, 0x2e, 0x32, 0x84, 0x36, 0xa1, 0xa8, 0xc8, 0x07, 0xa8, 0x4b, 0x21, 0x94,
|
0x41, 0x8e, 0xc0, 0x41, 0x14, 0x06, 0x79, 0x07, 0x96, 0xe0, 0x5c, 0x6a, 0x54, 0x6d, 0x8c, 0x4b,
|
||||||
0x41, 0x95, 0xd6, 0xb8, 0x42, 0x94, 0x91, 0xc1, 0xf0, 0x53, 0x68, 0x47, 0x7a, 0x7c, 0x45, 0x23,
|
0xc6, 0x44, 0xa0, 0x31, 0xf4, 0x18, 0x9c, 0x40, 0x95, 0xaf, 0x48, 0x64, 0x1f, 0xec, 0x3b, 0xd5,
|
||||||
0x87, 0xe0, 0xdd, 0xeb, 0xa5, 0x11, 0xfb, 0xcd, 0x26, 0xdb, 0xec, 0x34, 0xb2, 0x28, 0x7e, 0x06,
|
0x34, 0x64, 0xbf, 0x9e, 0x67, 0xeb, 0x9e, 0x06, 0x06, 0x45, 0x4f, 0xa0, 0x97, 0xf3, 0x31, 0xba,
|
||||||
0x9d, 0x9c, 0x4f, 0xd5, 0x43, 0x5a, 0x4f, 0x49, 0x8f, 0x64, 0x0f, 0x43, 0xa0, 0xb5, 0x99, 0xe1,
|
0x8f, 0xed, 0xa9, 0xc9, 0x11, 0xc7, 0x43, 0x13, 0xb0, 0x6d, 0xba, 0xb8, 0x43, 0x33, 0x0d, 0xf9,
|
||||||
0x5e, 0x5b, 0x37, 0xe4, 0x6f, 0xe0, 0x21, 0x74, 0x9f, 0x3e, 0x91, 0x6c, 0x00, 0x2d, 0x32, 0x8d,
|
0x1b, 0xa8, 0x0f, 0x5b, 0x8f, 0x47, 0xe8, 0xd6, 0x83, 0x35, 0x1c, 0x1a, 0xe3, 0x78, 0x3d, 0x28,
|
||||||
0x15, 0xde, 0x8d, 0x8a, 0x98, 0xff, 0x71, 0xa0, 0xae, 0xe7, 0xc6, 0x3a, 0x50, 0x9b, 0x26, 0xe4,
|
0x6c, 0xba, 0x09, 0xce, 0x50, 0x86, 0x32, 0x2b, 0x1c, 0x7c, 0x83, 0x5e, 0x7e, 0x80, 0xf4, 0x0f,
|
||||||
0xb1, 0xda, 0x34, 0xa9, 0xb6, 0x57, 0x6e, 0x16, 0x77, 0xcd, 0x2c, 0xec, 0x0c, 0x5a, 0x33, 0x54,
|
0xd0, 0x4d, 0xf5, 0x09, 0xe6, 0xe5, 0xce, 0xe7, 0x85, 0x0c, 0xc4, 0xd1, 0x01, 0xd8, 0x67, 0x42,
|
||||||
0x71, 0x12, 0xab, 0xd8, 0xaf, 0x9b, 0x0e, 0xfa, 0xe5, 0x5b, 0x0a, 0x2f, 0x08, 0xf6, 0x35, 0x55,
|
0x70, 0xa1, 0xaa, 0x1e, 0xf1, 0x2c, 0x91, 0x79, 0xd5, 0xb5, 0x41, 0xb6, 0xa0, 0x33, 0x49, 0x47,
|
||||||
0x72, 0x19, 0x15, 0xac, 0x60, 0x08, 0xed, 0xb5, 0x14, 0xeb, 0x82, 0x7b, 0x8b, 0x4b, 0x7a, 0x97,
|
0x38, 0xb5, 0xea, 0x93, 0x7e, 0x82, 0xae, 0x71, 0xa1, 0x6a, 0xc8, 0x14, 0xb5, 0xb9, 0x86, 0xda,
|
||||||
0xfe, 0xa9, 0x37, 0xf9, 0x10, 0xdf, 0x2d, 0x90, 0x9e, 0x65, 0x83, 0xcf, 0xb5, 0x4f, 0x0e, 0x3f,
|
0x73, 0x60, 0x50, 0xf4, 0x6f, 0x0b, 0x2c, 0xd5, 0x76, 0xd2, 0x83, 0xf6, 0x38, 0xc6, 0x15, 0x69,
|
||||||
0x81, 0x26, 0x79, 0x4d, 0xef, 0x51, 0xfb, 0x60, 0xfb, 0x1e, 0x8d, 0x57, 0x0c, 0x86, 0x1f, 0x83,
|
0x8f, 0xe3, 0xc5, 0xdb, 0x91, 0xcf, 0x7a, 0xa7, 0x32, 0xeb, 0xe4, 0x04, 0xd6, 0x26, 0x4c, 0x86,
|
||||||
0x77, 0x7e, 0x27, 0xec, 0xf2, 0xff, 0x99, 0xf4, 0x13, 0xea, 0xda, 0x0a, 0x2f, 0xe1, 0x68, 0x07,
|
0x71, 0x28, 0x43, 0xd7, 0xd2, 0x0d, 0xd8, 0xad, 0x1f, 0x32, 0xff, 0x1c, 0x61, 0x67, 0x89, 0x14,
|
||||||
0xcf, 0x11, 0xa5, 0x1e, 0xa8, 0x5b, 0xe1, 0x2e, 0x0b, 0x3a, 0xfa, 0xed, 0x42, 0xf3, 0x92, 0x06,
|
0xb3, 0xa0, 0x60, 0x95, 0x4a, 0x65, 0x2f, 0x57, 0x2a, 0xef, 0x08, 0x9c, 0x8a, 0x33, 0x55, 0x9c,
|
||||||
0x7b, 0xf5, 0xd4, 0x59, 0x6f, 0x93, 0xb5, 0x7e, 0xa0, 0xc1, 0xfb, 0x0a, 0x04, 0x9d, 0xe0, 0x0e,
|
0x1b, 0x36, 0xc3, 0x4c, 0xd4, 0xa7, 0x2a, 0xe2, 0x7d, 0x78, 0x9b, 0x31, 0x4c, 0xc4, 0x18, 0x5f,
|
||||||
0xfb, 0x0e, 0x9e, 0x71, 0x3e, 0x7b, 0xbb, 0x89, 0x5e, 0x3d, 0x9c, 0xe0, 0xdd, 0xd6, 0xfc, 0xaa,
|
0xda, 0x9f, 0x5b, 0xf4, 0x23, 0xac, 0xe2, 0x72, 0xa9, 0xc1, 0x55, 0x83, 0xdf, 0x3c, 0xb8, 0x7a,
|
||||||
0x96, 0x39, 0xd5, 0x32, 0xad, 0xd5, 0x4b, 0x2f, 0xd3, 0x5a, 0xbb, 0x71, 0xbe, 0xc3, 0x2e, 0xa0,
|
0x39, 0x34, 0x86, 0x1e, 0x82, 0x7d, 0x7a, 0xcb, 0xcd, 0xb4, 0x2f, 0x4d, 0xfa, 0x05, 0x96, 0x9a,
|
||||||
0x61, 0x8f, 0x82, 0x95, 0x80, 0xd7, 0xce, 0x2d, 0xe8, 0x6d, 0x07, 0x14, 0x72, 0xd7, 0xd0, 0xca,
|
0xfd, 0xe7, 0x70, 0xd4, 0xca, 0x4e, 0x19, 0x13, 0xaa, 0x05, 0x9d, 0x05, 0xeb, 0x64, 0x40, 0xf4,
|
||||||
0xcf, 0x81, 0x95, 0xcc, 0xe5, 0xd9, 0xf5, 0x04, 0xbc, 0x0a, 0x92, 0x8b, 0xde, 0x34, 0xcc, 0x9f,
|
0x0a, 0xac, 0xe1, 0x2c, 0x89, 0x54, 0x04, 0x75, 0xf0, 0xbf, 0x1d, 0x54, 0x98, 0xd2, 0xc6, 0xb4,
|
||||||
0xf4, 0xf1, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa7, 0x5b, 0x0a, 0x25, 0x2c, 0x06, 0x00, 0x00,
|
0x97, 0xd9, 0x98, 0x83, 0x3f, 0x1d, 0x58, 0xbd, 0xc0, 0x76, 0x5f, 0x3e, 0x56, 0xaf, 0x3f, 0x1f,
|
||||||
|
0xa4, 0xaa, 0x7a, 0xde, 0xdb, 0x05, 0x08, 0xd4, 0xb5, 0x15, 0xf2, 0x03, 0x6c, 0x2d, 0x27, 0xe4,
|
||||||
|
0xcd, 0x3c, 0xba, 0xac, 0x46, 0xde, 0x4e, 0xe3, 0x7d, 0xd9, 0x97, 0xd6, 0xbf, 0x3a, 0x5f, 0x65,
|
||||||
|
0xf9, 0xac, 0xf3, 0x55, 0x11, 0x4e, 0xba, 0x42, 0xce, 0xa1, 0x6b, 0x94, 0x86, 0xd4, 0x80, 0x2b,
|
||||||
|
0x1a, 0xe6, 0xf5, 0x9b, 0x01, 0x85, 0xbb, 0x21, 0xac, 0xe5, 0x1a, 0x43, 0x6a, 0xea, 0xf2, 0x44,
|
||||||
|
0x92, 0x3c, 0xba, 0x08, 0x52, 0x7e, 0x23, 0x4a, 0xc0, 0x4e, 0xe3, 0xd2, 0x34, 0xbf, 0xb1, 0x2a,
|
||||||
|
0x59, 0x74, 0xe5, 0xaa, 0xab, 0x7f, 0xa4, 0x87, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x11, 0x45,
|
||||||
|
0xe6, 0xf4, 0xa8, 0x07, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Code generated by protoc-gen-micro. DO NOT EDIT.
|
// Code generated by protoc-gen-micro. DO NOT EDIT.
|
||||||
// source: github.com/micro/go-micro/network/proto/network.proto
|
// source: network.proto
|
||||||
|
|
||||||
package go_micro_network
|
package go_micro_network
|
||||||
|
|
||||||
@ -45,6 +45,8 @@ type NetworkService interface {
|
|||||||
Routes(ctx context.Context, in *RoutesRequest, opts ...client.CallOption) (*RoutesResponse, error)
|
Routes(ctx context.Context, in *RoutesRequest, opts ...client.CallOption) (*RoutesResponse, error)
|
||||||
// Returns a list of known services based on routes
|
// Returns a list of known services based on routes
|
||||||
Services(ctx context.Context, in *ServicesRequest, opts ...client.CallOption) (*ServicesResponse, error)
|
Services(ctx context.Context, in *ServicesRequest, opts ...client.CallOption) (*ServicesResponse, error)
|
||||||
|
// Status returns network status
|
||||||
|
Status(ctx context.Context, in *StatusRequest, opts ...client.CallOption) (*StatusResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type networkService struct {
|
type networkService struct {
|
||||||
@ -115,6 +117,16 @@ func (c *networkService) Services(ctx context.Context, in *ServicesRequest, opts
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *networkService) Status(ctx context.Context, in *StatusRequest, opts ...client.CallOption) (*StatusResponse, error) {
|
||||||
|
req := c.c.NewRequest(c.name, "Network.Status", in)
|
||||||
|
out := new(StatusResponse)
|
||||||
|
err := c.c.Call(ctx, req, out, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Server API for Network service
|
// Server API for Network service
|
||||||
|
|
||||||
type NetworkHandler interface {
|
type NetworkHandler interface {
|
||||||
@ -128,6 +140,8 @@ type NetworkHandler interface {
|
|||||||
Routes(context.Context, *RoutesRequest, *RoutesResponse) error
|
Routes(context.Context, *RoutesRequest, *RoutesResponse) error
|
||||||
// Returns a list of known services based on routes
|
// Returns a list of known services based on routes
|
||||||
Services(context.Context, *ServicesRequest, *ServicesResponse) error
|
Services(context.Context, *ServicesRequest, *ServicesResponse) error
|
||||||
|
// Status returns network status
|
||||||
|
Status(context.Context, *StatusRequest, *StatusResponse) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func RegisterNetworkHandler(s server.Server, hdlr NetworkHandler, opts ...server.HandlerOption) error {
|
func RegisterNetworkHandler(s server.Server, hdlr NetworkHandler, opts ...server.HandlerOption) error {
|
||||||
@ -137,6 +151,7 @@ func RegisterNetworkHandler(s server.Server, hdlr NetworkHandler, opts ...server
|
|||||||
Nodes(ctx context.Context, in *NodesRequest, out *NodesResponse) error
|
Nodes(ctx context.Context, in *NodesRequest, out *NodesResponse) error
|
||||||
Routes(ctx context.Context, in *RoutesRequest, out *RoutesResponse) error
|
Routes(ctx context.Context, in *RoutesRequest, out *RoutesResponse) error
|
||||||
Services(ctx context.Context, in *ServicesRequest, out *ServicesResponse) error
|
Services(ctx context.Context, in *ServicesRequest, out *ServicesResponse) error
|
||||||
|
Status(ctx context.Context, in *StatusRequest, out *StatusResponse) error
|
||||||
}
|
}
|
||||||
type Network struct {
|
type Network struct {
|
||||||
network
|
network
|
||||||
@ -168,3 +183,7 @@ func (h *networkHandler) Routes(ctx context.Context, in *RoutesRequest, out *Rou
|
|||||||
func (h *networkHandler) Services(ctx context.Context, in *ServicesRequest, out *ServicesResponse) error {
|
func (h *networkHandler) Services(ctx context.Context, in *ServicesRequest, out *ServicesResponse) error {
|
||||||
return h.NetworkHandler.Services(ctx, in, out)
|
return h.NetworkHandler.Services(ctx, in, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *networkHandler) Status(ctx context.Context, in *StatusRequest, out *StatusResponse) error {
|
||||||
|
return h.NetworkHandler.Status(ctx, in, out)
|
||||||
|
}
|
||||||
|
@ -6,16 +6,18 @@ import "github.com/micro/go-micro/router/service/proto/router.proto";
|
|||||||
|
|
||||||
// Network service is usesd to gain visibility into networks
|
// Network service is usesd to gain visibility into networks
|
||||||
service Network {
|
service Network {
|
||||||
// Connect to the network
|
// Connect to the network
|
||||||
rpc Connect(ConnectRequest) returns (ConnectResponse) {};
|
rpc Connect(ConnectRequest) returns (ConnectResponse) {};
|
||||||
// Returns the entire network graph
|
// Returns the entire network graph
|
||||||
rpc Graph(GraphRequest) returns (GraphResponse) {};
|
rpc Graph(GraphRequest) returns (GraphResponse) {};
|
||||||
// Returns a list of known nodes in the network
|
// Returns a list of known nodes in the network
|
||||||
rpc Nodes(NodesRequest) returns (NodesResponse) {};
|
rpc Nodes(NodesRequest) returns (NodesResponse) {};
|
||||||
// Returns a list of known routes in the network
|
// Returns a list of known routes in the network
|
||||||
rpc Routes(RoutesRequest) returns (RoutesResponse) {};
|
rpc Routes(RoutesRequest) returns (RoutesResponse) {};
|
||||||
// Returns a list of known services based on routes
|
// Returns a list of known services based on routes
|
||||||
rpc Services(ServicesRequest) returns (ServicesResponse) {};
|
rpc Services(ServicesRequest) returns (ServicesResponse) {};
|
||||||
|
// Status returns network status
|
||||||
|
rpc Status(StatusRequest) returns (StatusResponse) {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query is passed in a LookupRequest
|
// Query is passed in a LookupRequest
|
||||||
@ -69,6 +71,23 @@ message ServicesResponse {
|
|||||||
repeated string services = 1;
|
repeated string services = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message StatusRequest {}
|
||||||
|
|
||||||
|
message StatusResponse {
|
||||||
|
Status status = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error tracks network errors
|
||||||
|
message Error {
|
||||||
|
uint32 count = 1;
|
||||||
|
string msg = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Status is node status
|
||||||
|
message Status {
|
||||||
|
Error error = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Node is network node
|
// Node is network node
|
||||||
message Node {
|
message Node {
|
||||||
// node id
|
// node id
|
||||||
@ -79,6 +98,8 @@ message Node {
|
|||||||
string network = 3;
|
string network = 3;
|
||||||
// associated metadata
|
// associated metadata
|
||||||
map<string,string> metadata = 4;
|
map<string,string> metadata = 4;
|
||||||
|
// node status
|
||||||
|
Status status = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect is sent when the node connects to the network
|
// Connect is sent when the node connects to the network
|
||||||
@ -100,3 +121,11 @@ message Peer {
|
|||||||
// node peers
|
// node peers
|
||||||
repeated Peer peers = 2;
|
repeated Peer peers = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sync is network sync message
|
||||||
|
message Sync {
|
||||||
|
// peer origin
|
||||||
|
Peer peer = 1;
|
||||||
|
// node routes
|
||||||
|
repeated go.micro.router.Route routes = 2;
|
||||||
|
}
|
||||||
|
@ -384,7 +384,7 @@ func (t *tun) process() {
|
|||||||
// if the link is not connected skip it
|
// if the link is not connected skip it
|
||||||
if !connected {
|
if !connected {
|
||||||
log.Debugf("Link for node %s not connected", id)
|
log.Debugf("Link for node %s not connected", id)
|
||||||
err = errors.New("link not connected")
|
err = ErrLinkDisconnected
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,14 +392,14 @@ func (t *tun) process() {
|
|||||||
// and the message is being sent outbound via
|
// and the message is being sent outbound via
|
||||||
// a dialled connection don't use this link
|
// a dialled connection don't use this link
|
||||||
if loopback && msg.outbound {
|
if loopback && msg.outbound {
|
||||||
err = errors.New("link is loopback")
|
err = ErrLinkLoopback
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the message was being returned by the loopback listener
|
// if the message was being returned by the loopback listener
|
||||||
// send it back up the loopback link only
|
// send it back up the loopback link only
|
||||||
if msg.loopback && !loopback {
|
if msg.loopback && !loopback {
|
||||||
err = errors.New("link is not loopback")
|
err = ErrLinkRemote
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,7 +414,7 @@ func (t *tun) process() {
|
|||||||
// this is where we explicitly set the link
|
// this is where we explicitly set the link
|
||||||
// in a message received via the listen method
|
// in a message received via the listen method
|
||||||
if len(msg.link) > 0 && id != msg.link {
|
if len(msg.link) > 0 && id != msg.link {
|
||||||
err = errors.New("link not found")
|
err = ErrLinkNotFound
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,12 @@ var (
|
|||||||
ErrDiscoverChan = errors.New("failed to discover channel")
|
ErrDiscoverChan = errors.New("failed to discover channel")
|
||||||
// ErrLinkNotFound is returned when a link is specified at dial time and does not exist
|
// ErrLinkNotFound is returned when a link is specified at dial time and does not exist
|
||||||
ErrLinkNotFound = errors.New("link not found")
|
ErrLinkNotFound = errors.New("link not found")
|
||||||
|
// ErrLinkDisconnected is returned when a link we attempt to send to is disconnected
|
||||||
|
ErrLinkDisconnected = errors.New("link not connected")
|
||||||
|
// ErrLinkLoppback is returned when attempting to send an outbound message over loopback link
|
||||||
|
ErrLinkLoopback = errors.New("link is loopback")
|
||||||
|
// ErrLinkRemote is returned when attempting to send a loopback message over remote link
|
||||||
|
ErrLinkRemote = errors.New("link is remote")
|
||||||
// ErrReadTimeout is a timeout on session.Recv
|
// ErrReadTimeout is a timeout on session.Recv
|
||||||
ErrReadTimeout = errors.New("read timeout")
|
ErrReadTimeout = errors.New("read timeout")
|
||||||
// ErrDecryptingData is for when theres a nonce error
|
// ErrDecryptingData is for when theres a nonce error
|
||||||
|
33
util/proto/proto.go
Normal file
33
util/proto/proto.go
Normal 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,
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user