Nodes, Peers and Topology methods for node

Topology accepts an argument to define the depth of the topology
requested from the network. proto definitions have been modified
accordingly, too.
This commit is contained in:
Milos Gajdos 2019-09-10 18:32:25 +01:00
parent cbce5490d7
commit 16fcf1fbda
No known key found for this signature in database
GPG Key ID: 8B31058CC55DFD4F
7 changed files with 463 additions and 123 deletions

View File

@ -3,7 +3,6 @@ package handler
import ( import (
"context" "context"
"sort"
"github.com/micro/go-micro/errors" "github.com/micro/go-micro/errors"
"github.com/micro/go-micro/network" "github.com/micro/go-micro/network"
@ -18,65 +17,33 @@ type Network struct {
// ListNodes returns a list of all accessible nodes in the network // ListNodes returns a list of all accessible nodes in the network
func (n *Network) ListNodes(ctx context.Context, req *pbNet.ListRequest, resp *pbNet.ListResponse) error { func (n *Network) ListNodes(ctx context.Context, req *pbNet.ListRequest, resp *pbNet.ListResponse) error {
nodes := n.Network.Nodes() networkNodes := n.Network.Nodes()
var respNodes []*pbNet.Node var nodes []*pbNet.Node
for _, node := range nodes { for _, networkNode := range networkNodes {
respNode := &pbNet.Node{ node := &pbNet.Node{
Id: node.Id(), Id: networkNode.Id(),
Address: node.Address(), Address: networkNode.Address(),
} }
respNodes = append(respNodes, respNode) nodes = append(nodes, node)
} }
resp.Nodes = respNodes resp.Nodes = nodes
return nil return nil
} }
// ListPeers returns a list of all the nodes the node has a direct link with // ListPeers returns a list of all the nodes the node has a direct link with
func (n *Network) ListPeers(ctx context.Context, req *pbNet.PeerRequest, resp *pbNet.PeerResponse) error { func (n *Network) ListPeers(ctx context.Context, req *pbNet.PeerRequest, resp *pbNet.PeerResponse) error {
// extract the id of the node to query nodePeers := n.Network.Peers()
id := req.Id
// if no id is passed, we assume local node
if id == "" {
id = n.Network.Id()
}
// get all the nodes in the network var peers []*pbNet.Node
nodes := n.Network.Nodes() for _, nodePeer := range nodePeers {
peer := &pbNet.Node{
// sort the slice of nodes Id: nodePeer.Id(),
sort.Slice(nodes, func(i, j int) bool { return nodes[i].Id() <= nodes[j].Id() }) Address: nodePeer.Address(),
// find a node with a given id
i := sort.Search(len(nodes), func(j int) bool { return nodes[j].Id() >= id })
var nodePeers []*pbNet.Node
// collect all the node peers into slice
if i < len(nodes) && nodes[i].Id() == id {
for _, peer := range nodes[i].Peers() {
// don't return yourself in response
if peer.Id() == n.Network.Id() {
continue
}
pbPeer := &pbNet.Node{
Id: peer.Id(),
Address: peer.Address(),
}
nodePeers = append(nodePeers, pbPeer)
} }
} peers = append(peers, peer)
// requested node
node := &pbNet.Node{
Id: nodes[i].Id(),
Address: nodes[i].Address(),
}
// creaate peers answer
peers := &pbNet.Peers{
Node: node,
Peers: nodePeers,
} }
resp.Peers = peers resp.Peers = peers
@ -84,6 +51,43 @@ func (n *Network) ListPeers(ctx context.Context, req *pbNet.PeerRequest, resp *p
return nil return nil
} }
// Topology returns a list of nodes in node topology i.e. it returns all (in)directly reachable nodes from this node
func (n *Network) Topology(ctx context.Context, req *pbNet.TopologyRequest, resp *pbNet.TopologyResponse) error {
// NOTE: we are downcasting here
depth := uint(req.Depth)
if depth <= 0 {
depth = network.MaxDepth
}
// get topology
topNodes := n.Network.Topology(depth)
var nodes []*pbNet.Node
for _, topNode := range topNodes {
// creaate peers answer
pbNode := &pbNet.Node{
Id: topNode.Id(),
Address: topNode.Address(),
}
nodes = append(nodes, pbNode)
}
// network node
node := &pbNet.Node{
Id: n.Network.Id(),
Address: n.Network.Address(),
}
topology := &pbNet.Topology{
Node: node,
Nodes: nodes,
}
resp.Topology = topology
return nil
}
// ListRoutes returns a list of routing table routes // ListRoutes returns a list of routing table routes
func (n *Network) ListRoutes(ctx context.Context, req *pbRtr.Request, resp *pbRtr.ListResponse) error { func (n *Network) ListRoutes(ctx context.Context, req *pbRtr.Request, resp *pbRtr.ListResponse) error {
routes, err := n.Network.Options().Router.Table().List() routes, err := n.Network.Options().Router.Table().List()

View File

@ -46,6 +46,8 @@ type Network interface {
Connect() error Connect() error
// Nodes returns list of network nodes // Nodes returns list of network nodes
Nodes() []Node Nodes() []Node
// Topology returns a list of all reachable nodes up to depth
Topology(depth uint) []Node
// Close stops the tunnel and resolving // Close stops the tunnel and resolving
Close() error Close() error
// Client is micro client // Client is micro client

View File

@ -3,15 +3,16 @@ package network
import ( import (
"container/list" "container/list"
"errors" "errors"
"sort"
"sync" "sync"
"time" "time"
pbNet "github.com/micro/go-micro/network/proto" pb "github.com/micro/go-micro/network/proto"
) )
var ( var (
// MaxDepth defines max depth of peer topology // MaxDepth defines max depth of peer topology
MaxDepth = 3 MaxDepth uint = 3
) )
// node is network node // node is network node
@ -98,6 +99,7 @@ func (n *node) Peers() []Node {
network: peer.network, network: peer.network,
} }
// NOTE: we do not care about peer's peers // NOTE: we do not care about peer's peers
// we only collect the node's peers i.e. its adjacent nodes
peers = append(peers, p) peers = append(peers, p)
} }
n.RUnlock() n.RUnlock()
@ -105,17 +107,49 @@ func (n *node) Peers() []Node {
return peers return peers
} }
// Topology returns a slice of all nodes in reachable by node up to given depth
func (n *node) Topology(depth uint) []Node {
// get all the nodes
nodes := n.Nodes()
n.RLock()
// sort the slice of nodes
sort.Slice(nodes, func(i, j int) bool { return nodes[i].Id() <= nodes[j].Id() })
// find the node with our id
i := sort.Search(len(nodes), func(j int) bool { return nodes[j].Id() >= n.id })
// TODO: finish implementing this
var topology []Node
// collect all the reachable nodes into slice
if i < len(nodes) && nodes[i].Id() == n.id {
for _, peer := range nodes[i].Peers() {
// don't return yourself
if peer.Id() == n.id {
continue
}
topNode := &node{
id: peer.Id(),
address: peer.Address(),
}
topology = append(topology, topNode)
}
}
n.RUnlock()
return topology
}
// getProtoTopology returns node peers up to given depth encoded in protobufs // getProtoTopology returns node peers up to given depth encoded in protobufs
// NOTE: this method is NOT thread-safe, so make sure you serialize access to it // NOTE: this method is NOT thread-safe, so make sure you serialize access to it
func (n *node) getProtoTopology(depth int) (*pbNet.Peer, error) { func (n *node) getProtoTopology(depth uint) (*pb.Peer, error) {
node := &pbNet.Node{ node := &pb.Node{
Id: n.id, Id: n.id,
Address: n.address, Address: n.address,
} }
pbPeers := &pbNet.Peer{ pbPeers := &pb.Peer{
Node: node, Node: node,
Peers: make([]*pbNet.Peer, 0), Peers: make([]*pb.Peer, 0),
} }
// return if have either reached the depth or have no more peers // return if have either reached the depth or have no more peers
@ -126,7 +160,7 @@ func (n *node) getProtoTopology(depth int) (*pbNet.Peer, error) {
// decrement the depth // decrement the depth
depth-- depth--
var peers []*pbNet.Peer var peers []*pb.Peer
for _, peer := range n.peers { for _, peer := range n.peers {
// get peers of the node peers // get peers of the node peers
// NOTE: this is [not] a recursive call // NOTE: this is [not] a recursive call
@ -144,9 +178,9 @@ func (n *node) getProtoTopology(depth int) (*pbNet.Peer, error) {
return pbPeers, nil return pbPeers, nil
} }
// unpackPeer unpacks pbNet.Peer into node topology of given depth // unpackPeer unpacks pb.Peer into node topology of given depth
// NOTE: this method is NOT thread-safe, so make sure you serialize access to it // NOTE: this method is NOT thread-safe, so make sure you serialize access to it
func unpackPeer(pbPeer *pbNet.Peer, depth int) *node { func unpackPeer(pbPeer *pb.Peer, depth uint) *node {
peerNode := &node{ peerNode := &node{
id: pbPeer.Node.Id, id: pbPeer.Node.Id,
address: pbPeer.Node.Address, address: pbPeer.Node.Address,
@ -174,7 +208,7 @@ func unpackPeer(pbPeer *pbNet.Peer, depth int) *node {
// updatePeer updates node peer up to given depth // updatePeer updates node peer up to given depth
// NOTE: this method is not thread safe, so make sure you serialize access to it // NOTE: this method is not thread safe, so make sure you serialize access to it
func (n *node) updatePeerTopology(pbPeer *pbNet.Peer, depth int) error { func (n *node) updatePeerTopology(pbPeer *pb.Peer, depth uint) error {
if pbPeer == nil { if pbPeer == nil {
return errors.New("peer not initialized") return errors.New("peer not initialized")
} }

174
network/node_test.go Normal file
View File

@ -0,0 +1,174 @@
package network
import "testing"
var (
testNodeId = "testNode"
testNodeAddress = "testAddress"
testNodeNetName = "testNetwork"
testNodePeerIds = []string{"peer1", "peer2", "peer3"}
testPeerOfPeerIds = []string{"peer11", "peer12"}
)
func testSetup() *node {
testNode := &node{
id: testNodeId,
address: testNodeAddress,
peers: make(map[string]*node),
network: newNetwork(Name(testNodeNetName)),
}
// add some peers to the node
for _, id := range testNodePeerIds {
testNode.peers[id] = &node{
id: id,
address: testNode.address + "-" + id,
peers: make(map[string]*node),
network: testNode.network,
}
}
// add peers to peer1
// NOTE: these are peers of peers!
for _, id := range testPeerOfPeerIds {
testNode.peers["peer1"].peers[id] = &node{
id: id,
address: testNode.address + "-" + id,
peers: make(map[string]*node),
network: testNode.network,
}
}
// connect peer1 with peer2
testNode.peers["peer1"].peers["peer2"] = testNode.peers["peer2"]
// connect peer2 with peer3
testNode.peers["peer2"].peers["peer3"] = testNode.peers["peer3"]
return testNode
}
func TestNodeId(t *testing.T) {
node := testSetup()
if node.Id() != testNodeId {
t.Errorf("Expected id: %s, found: %s", testNodeId, node.Id())
}
}
func TestNodeAddress(t *testing.T) {
node := testSetup()
if node.Address() != testNodeAddress {
t.Errorf("Expected address: %s, found: %s", testNodeAddress, node.Address())
}
}
func TestNodeNetwork(t *testing.T) {
node := testSetup()
if node.Network().Name() != testNodeNetName {
t.Errorf("Expected network: %s, found: %s", testNodeNetName, node.Network().Name())
}
}
func TestNodes(t *testing.T) {
// single node
single := &node{
id: testNodeId,
address: testNodeAddress,
peers: make(map[string]*node),
network: newNetwork(Name(testNodeNetName)),
}
// get all the nodes including yourself
nodes := single.Nodes()
nodeCount := 1
if len(nodes) != nodeCount {
t.Errorf("Expected to find %d nodes, found: %d", nodeCount, len(nodes))
}
// complicated node graph
node := testSetup()
// get all the nodes including yourself
nodes = node.Nodes()
// compile a list of ids of all nodes in the network into map for easy indexing
nodeIds := make(map[string]bool)
// add yourself
nodeIds[node.id] = true
// add peer Ids
for _, id := range testNodePeerIds {
nodeIds[id] = true
}
// add peer1 peers i.e. peers of peer
for _, id := range testPeerOfPeerIds {
nodeIds[id] = true
}
// we should return the correct number of nodes
if len(nodes) != len(nodeIds) {
t.Errorf("Expected %d nodes, found: %d", len(nodeIds), len(nodes))
}
// iterate through the list of nodes and makes sure all have been returned
for _, node := range nodes {
if _, ok := nodeIds[node.Id()]; !ok {
t.Errorf("Expected to find %s node", node.Id())
}
}
}
func TestPeers(t *testing.T) {
// single node
single := &node{
id: testNodeId,
address: testNodeAddress,
peers: make(map[string]*node),
network: newNetwork(Name(testNodeNetName)),
}
// get all the nodes including yourself
peers := single.Peers()
peerCount := 0
if len(peers) != peerCount {
t.Errorf("Expected to find %d peers, found: %d", peerCount, len(peers))
}
// complicated node graph
node := testSetup()
// get all the nodes including yourself
peers = node.Peers()
// compile a list of ids of all nodes in the network into map for easy indexing
peerIds := make(map[string]bool)
// add peer Ids
for _, id := range testNodePeerIds {
peerIds[id] = true
}
// we should return the correct number of peers
if len(peers) != len(peerIds) {
t.Errorf("Expected %d nodes, found: %d", len(peerIds), len(peers))
}
// iterate through the list of peers and makes sure all have been returned
for _, peer := range peers {
if _, ok := peerIds[peer.Id()]; !ok {
t.Errorf("Expected to find %s peer", node.Id())
}
}
}
func TestTopology(t *testing.T) {
// single node
single := &node{
id: testNodeId,
address: testNodeAddress,
peers: make(map[string]*node),
network: newNetwork(Name(testNodeNetName)),
}
// get all the nodes including yourself
topology := single.Topology(MaxDepth)
// you should not be in your topology
topCount := 0
if len(topology) != topCount {
t.Errorf("Expected to find %d nodes, found: %d", topCount, len(topology))
}
}

View File

@ -37,6 +37,7 @@ var _ server.Option
type NetworkService interface { type NetworkService interface {
ListNodes(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) ListNodes(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error)
ListPeers(ctx context.Context, in *PeerRequest, opts ...client.CallOption) (*PeerResponse, error) ListPeers(ctx context.Context, in *PeerRequest, opts ...client.CallOption) (*PeerResponse, error)
Topology(ctx context.Context, in *TopologyRequest, opts ...client.CallOption) (*TopologyResponse, error)
ListRoutes(ctx context.Context, in *proto1.Request, opts ...client.CallOption) (*proto1.ListResponse, error) ListRoutes(ctx context.Context, in *proto1.Request, opts ...client.CallOption) (*proto1.ListResponse, error)
} }
@ -78,6 +79,16 @@ func (c *networkService) ListPeers(ctx context.Context, in *PeerRequest, opts ..
return out, nil return out, nil
} }
func (c *networkService) Topology(ctx context.Context, in *TopologyRequest, opts ...client.CallOption) (*TopologyResponse, error) {
req := c.c.NewRequest(c.name, "Network.Topology", in)
out := new(TopologyResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *networkService) ListRoutes(ctx context.Context, in *proto1.Request, opts ...client.CallOption) (*proto1.ListResponse, error) { func (c *networkService) ListRoutes(ctx context.Context, in *proto1.Request, opts ...client.CallOption) (*proto1.ListResponse, error) {
req := c.c.NewRequest(c.name, "Network.ListRoutes", in) req := c.c.NewRequest(c.name, "Network.ListRoutes", in)
out := new(proto1.ListResponse) out := new(proto1.ListResponse)
@ -93,6 +104,7 @@ func (c *networkService) ListRoutes(ctx context.Context, in *proto1.Request, opt
type NetworkHandler interface { type NetworkHandler interface {
ListNodes(context.Context, *ListRequest, *ListResponse) error ListNodes(context.Context, *ListRequest, *ListResponse) error
ListPeers(context.Context, *PeerRequest, *PeerResponse) error ListPeers(context.Context, *PeerRequest, *PeerResponse) error
Topology(context.Context, *TopologyRequest, *TopologyResponse) error
ListRoutes(context.Context, *proto1.Request, *proto1.ListResponse) error ListRoutes(context.Context, *proto1.Request, *proto1.ListResponse) error
} }
@ -100,6 +112,7 @@ func RegisterNetworkHandler(s server.Server, hdlr NetworkHandler, opts ...server
type network interface { type network interface {
ListNodes(ctx context.Context, in *ListRequest, out *ListResponse) error ListNodes(ctx context.Context, in *ListRequest, out *ListResponse) error
ListPeers(ctx context.Context, in *PeerRequest, out *PeerResponse) error ListPeers(ctx context.Context, in *PeerRequest, out *PeerResponse) error
Topology(ctx context.Context, in *TopologyRequest, out *TopologyResponse) error
ListRoutes(ctx context.Context, in *proto1.Request, out *proto1.ListResponse) error ListRoutes(ctx context.Context, in *proto1.Request, out *proto1.ListResponse) error
} }
type Network struct { type Network struct {
@ -121,6 +134,10 @@ func (h *networkHandler) ListPeers(ctx context.Context, in *PeerRequest, out *Pe
return h.NetworkHandler.ListPeers(ctx, in, out) return h.NetworkHandler.ListPeers(ctx, in, out)
} }
func (h *networkHandler) Topology(ctx context.Context, in *TopologyRequest, out *TopologyResponse) error {
return h.NetworkHandler.Topology(ctx, in, out)
}
func (h *networkHandler) ListRoutes(ctx context.Context, in *proto1.Request, out *proto1.ListResponse) error { func (h *networkHandler) ListRoutes(ctx context.Context, in *proto1.Request, out *proto1.ListResponse) error {
return h.NetworkHandler.ListRoutes(ctx, in, out) return h.NetworkHandler.ListRoutes(ctx, in, out)
} }

View File

@ -137,7 +137,7 @@ func (m *PeerRequest) GetId() string {
// PeerResponse is returned by ListPeers // PeerResponse is returned by ListPeers
type PeerResponse struct { type PeerResponse struct {
Peers *Peers `protobuf:"bytes,1,opt,name=peers,proto3" json:"peers,omitempty"` Peers []*Node `protobuf:"bytes,1,rep,name=peers,proto3" json:"peers,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -168,59 +168,99 @@ func (m *PeerResponse) XXX_DiscardUnknown() {
var xxx_messageInfo_PeerResponse proto.InternalMessageInfo var xxx_messageInfo_PeerResponse proto.InternalMessageInfo
func (m *PeerResponse) GetPeers() *Peers { func (m *PeerResponse) GetPeers() []*Node {
if m != nil { if m != nil {
return m.Peers return m.Peers
} }
return nil return nil
} }
// Peers are node peers // TopologyRequest list node topology
type Peers struct { type TopologyRequest struct {
// network node // node id
Node *Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
// node peers // topology depth
Peers []*Node `protobuf:"bytes,2,rep,name=peers,proto3" json:"peers,omitempty"` Depth uint64 `protobuf:"varint,2,opt,name=depth,proto3" json:"depth,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
} }
func (m *Peers) Reset() { *m = Peers{} } func (m *TopologyRequest) Reset() { *m = TopologyRequest{} }
func (m *Peers) String() string { return proto.CompactTextString(m) } func (m *TopologyRequest) String() string { return proto.CompactTextString(m) }
func (*Peers) ProtoMessage() {} func (*TopologyRequest) ProtoMessage() {}
func (*Peers) Descriptor() ([]byte, []int) { func (*TopologyRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_8571034d60397816, []int{4} return fileDescriptor_8571034d60397816, []int{4}
} }
func (m *Peers) XXX_Unmarshal(b []byte) error { func (m *TopologyRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Peers.Unmarshal(m, b) return xxx_messageInfo_TopologyRequest.Unmarshal(m, b)
} }
func (m *Peers) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { func (m *TopologyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Peers.Marshal(b, m, deterministic) return xxx_messageInfo_TopologyRequest.Marshal(b, m, deterministic)
} }
func (m *Peers) XXX_Merge(src proto.Message) { func (m *TopologyRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_Peers.Merge(m, src) xxx_messageInfo_TopologyRequest.Merge(m, src)
} }
func (m *Peers) XXX_Size() int { func (m *TopologyRequest) XXX_Size() int {
return xxx_messageInfo_Peers.Size(m) return xxx_messageInfo_TopologyRequest.Size(m)
} }
func (m *Peers) XXX_DiscardUnknown() { func (m *TopologyRequest) XXX_DiscardUnknown() {
xxx_messageInfo_Peers.DiscardUnknown(m) xxx_messageInfo_TopologyRequest.DiscardUnknown(m)
} }
var xxx_messageInfo_Peers proto.InternalMessageInfo var xxx_messageInfo_TopologyRequest proto.InternalMessageInfo
func (m *Peers) GetNode() *Node { func (m *TopologyRequest) GetId() string {
if m != nil { if m != nil {
return m.Node return m.Id
} }
return nil return ""
} }
func (m *Peers) GetPeers() []*Node { func (m *TopologyRequest) GetDepth() uint64 {
if m != nil { if m != nil {
return m.Peers return m.Depth
}
return 0
}
// TopologyResponse is returned by Topology
type TopologyResponse struct {
Topology *Topology `protobuf:"bytes,1,opt,name=topology,proto3" json:"topology,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *TopologyResponse) Reset() { *m = TopologyResponse{} }
func (m *TopologyResponse) String() string { return proto.CompactTextString(m) }
func (*TopologyResponse) ProtoMessage() {}
func (*TopologyResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_8571034d60397816, []int{5}
}
func (m *TopologyResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_TopologyResponse.Unmarshal(m, b)
}
func (m *TopologyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_TopologyResponse.Marshal(b, m, deterministic)
}
func (m *TopologyResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_TopologyResponse.Merge(m, src)
}
func (m *TopologyResponse) XXX_Size() int {
return xxx_messageInfo_TopologyResponse.Size(m)
}
func (m *TopologyResponse) XXX_DiscardUnknown() {
xxx_messageInfo_TopologyResponse.DiscardUnknown(m)
}
var xxx_messageInfo_TopologyResponse proto.InternalMessageInfo
func (m *TopologyResponse) GetTopology() *Topology {
if m != nil {
return m.Topology
} }
return nil return nil
} }
@ -240,7 +280,7 @@ 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_8571034d60397816, []int{5} return fileDescriptor_8571034d60397816, []int{6}
} }
func (m *Node) XXX_Unmarshal(b []byte) error { func (m *Node) XXX_Unmarshal(b []byte) error {
@ -275,6 +315,56 @@ func (m *Node) GetAddress() string {
return "" return ""
} }
// Topology is used to nnounce node neighbourhood
type Topology struct {
// network node
Node *Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"`
// neighbours
Nodes []*Node `protobuf:"bytes,2,rep,name=nodes,proto3" json:"nodes,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Topology) Reset() { *m = Topology{} }
func (m *Topology) String() string { return proto.CompactTextString(m) }
func (*Topology) ProtoMessage() {}
func (*Topology) Descriptor() ([]byte, []int) {
return fileDescriptor_8571034d60397816, []int{7}
}
func (m *Topology) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Topology.Unmarshal(m, b)
}
func (m *Topology) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Topology.Marshal(b, m, deterministic)
}
func (m *Topology) XXX_Merge(src proto.Message) {
xxx_messageInfo_Topology.Merge(m, src)
}
func (m *Topology) XXX_Size() int {
return xxx_messageInfo_Topology.Size(m)
}
func (m *Topology) XXX_DiscardUnknown() {
xxx_messageInfo_Topology.DiscardUnknown(m)
}
var xxx_messageInfo_Topology proto.InternalMessageInfo
func (m *Topology) GetNode() *Node {
if m != nil {
return m.Node
}
return nil
}
func (m *Topology) GetNodes() []*Node {
if m != nil {
return m.Nodes
}
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
@ -288,7 +378,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_8571034d60397816, []int{6} return fileDescriptor_8571034d60397816, []int{8}
} }
func (m *Connect) XXX_Unmarshal(b []byte) error { func (m *Connect) XXX_Unmarshal(b []byte) error {
@ -329,7 +419,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_8571034d60397816, []int{7} return fileDescriptor_8571034d60397816, []int{9}
} }
func (m *Close) XXX_Unmarshal(b []byte) error { func (m *Close) XXX_Unmarshal(b []byte) error {
@ -370,7 +460,7 @@ func (m *Solicit) Reset() { *m = Solicit{} }
func (m *Solicit) String() string { return proto.CompactTextString(m) } func (m *Solicit) String() string { return proto.CompactTextString(m) }
func (*Solicit) ProtoMessage() {} func (*Solicit) ProtoMessage() {}
func (*Solicit) Descriptor() ([]byte, []int) { func (*Solicit) Descriptor() ([]byte, []int) {
return fileDescriptor_8571034d60397816, []int{8} return fileDescriptor_8571034d60397816, []int{10}
} }
func (m *Solicit) XXX_Unmarshal(b []byte) error { func (m *Solicit) XXX_Unmarshal(b []byte) error {
@ -413,7 +503,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_8571034d60397816, []int{9} return fileDescriptor_8571034d60397816, []int{11}
} }
func (m *Peer) XXX_Unmarshal(b []byte) error { func (m *Peer) XXX_Unmarshal(b []byte) error {
@ -453,8 +543,10 @@ func init() {
proto.RegisterType((*ListResponse)(nil), "go.micro.network.ListResponse") proto.RegisterType((*ListResponse)(nil), "go.micro.network.ListResponse")
proto.RegisterType((*PeerRequest)(nil), "go.micro.network.PeerRequest") proto.RegisterType((*PeerRequest)(nil), "go.micro.network.PeerRequest")
proto.RegisterType((*PeerResponse)(nil), "go.micro.network.PeerResponse") proto.RegisterType((*PeerResponse)(nil), "go.micro.network.PeerResponse")
proto.RegisterType((*Peers)(nil), "go.micro.network.Peers") proto.RegisterType((*TopologyRequest)(nil), "go.micro.network.TopologyRequest")
proto.RegisterType((*TopologyResponse)(nil), "go.micro.network.TopologyResponse")
proto.RegisterType((*Node)(nil), "go.micro.network.Node") proto.RegisterType((*Node)(nil), "go.micro.network.Node")
proto.RegisterType((*Topology)(nil), "go.micro.network.Topology")
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((*Solicit)(nil), "go.micro.network.Solicit") proto.RegisterType((*Solicit)(nil), "go.micro.network.Solicit")
@ -464,28 +556,31 @@ func init() {
func init() { proto.RegisterFile("network.proto", fileDescriptor_8571034d60397816) } func init() { proto.RegisterFile("network.proto", fileDescriptor_8571034d60397816) }
var fileDescriptor_8571034d60397816 = []byte{ var fileDescriptor_8571034d60397816 = []byte{
// 353 bytes of a gzipped FileDescriptorProto // 412 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x93, 0x51, 0x4f, 0xc2, 0x30, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x94, 0xdf, 0x8a, 0xd3, 0x40,
0x10, 0xc7, 0x19, 0x32, 0x17, 0x6e, 0x60, 0x4c, 0x1f, 0x74, 0x21, 0x99, 0x21, 0x7d, 0x22, 0x46, 0x14, 0xc6, 0x37, 0x31, 0x35, 0xdb, 0x13, 0x57, 0x97, 0x41, 0x24, 0x14, 0x2a, 0x75, 0xae, 0x8a,
0x86, 0x81, 0xf0, 0xa6, 0x4f, 0x3c, 0xf8, 0x42, 0x88, 0x99, 0x5f, 0x40, 0xd8, 0x2e, 0xd8, 0x08, 0x68, 0x2a, 0x2d, 0xab, 0x37, 0xde, 0xed, 0x85, 0x20, 0xcb, 0x22, 0xa9, 0x0f, 0xa0, 0xcd, 0x0c,
0x3b, 0x6c, 0x4b, 0xfc, 0xd6, 0x7e, 0x06, 0xd3, 0x76, 0x44, 0x84, 0xcc, 0x84, 0xc4, 0xb7, 0xde, 0x69, 0xb0, 0xcd, 0x89, 0x33, 0x53, 0xc4, 0xe7, 0xf3, 0xc5, 0x64, 0xfe, 0xa4, 0x89, 0xa6, 0xa9,
0xdd, 0xff, 0x7e, 0x77, 0x6d, 0xef, 0xa0, 0x5d, 0xa0, 0xfe, 0x24, 0xf9, 0x9e, 0x6c, 0x24, 0x69, 0xe6, 0xae, 0x67, 0xce, 0xf9, 0x7e, 0x5f, 0x72, 0xfa, 0x4d, 0xe0, 0xaa, 0xe4, 0xea, 0x07, 0x8a,
0x62, 0x97, 0x4b, 0x4a, 0xd6, 0x22, 0x93, 0x94, 0x94, 0xfe, 0xce, 0x68, 0x29, 0xf4, 0xdb, 0x76, 0x6f, 0x49, 0x25, 0x50, 0x21, 0xb9, 0xce, 0x31, 0xd9, 0x17, 0x99, 0xc0, 0xc4, 0x9d, 0x4f, 0x56,
0x91, 0x64, 0xb4, 0x1e, 0xd8, 0xc8, 0x60, 0x49, 0x7d, 0x77, 0x90, 0xb4, 0xd5, 0x28, 0x07, 0x36, 0x79, 0xa1, 0xb6, 0x87, 0x4d, 0x92, 0xe1, 0x7e, 0x61, 0x3a, 0x8b, 0x1c, 0x5f, 0xdb, 0x1f, 0x02,
0xb3, 0x34, 0x1c, 0x86, 0xb7, 0x21, 0x9c, 0x0a, 0xa5, 0x53, 0xfc, 0xd8, 0xa2, 0xd2, 0xfc, 0x01, 0x0f, 0x8a, 0x8b, 0x85, 0x51, 0xba, 0xc2, 0x62, 0xe8, 0x15, 0x44, 0x77, 0x85, 0x54, 0x29, 0xff,
0x5a, 0xce, 0x54, 0x1b, 0x2a, 0x14, 0xb2, 0x3b, 0xf0, 0x0b, 0xca, 0x51, 0x45, 0x5e, 0xf7, 0xac, 0x7e, 0xe0, 0x52, 0xd1, 0xf7, 0xf0, 0xc8, 0x96, 0xb2, 0xc2, 0x52, 0x72, 0xf2, 0x0a, 0x46, 0x25,
0x17, 0x0e, 0xaf, 0x92, 0xc3, 0xaa, 0xc9, 0x8c, 0x72, 0x4c, 0x9d, 0x88, 0xc7, 0x10, 0x3e, 0x23, 0x32, 0x2e, 0x63, 0x6f, 0xf6, 0x60, 0x1e, 0x2d, 0x9f, 0x25, 0x7f, 0xbb, 0x26, 0xf7, 0xc8, 0x78,
0xca, 0x12, 0xc6, 0x2e, 0xa0, 0x2e, 0xf2, 0xc8, 0xeb, 0x7a, 0xbd, 0x66, 0x5a, 0x17, 0x39, 0x7f, 0x6a, 0x87, 0xe8, 0x14, 0xa2, 0x4f, 0x9c, 0x0b, 0x07, 0x23, 0x8f, 0xc1, 0x2f, 0x58, 0xec, 0xcd,
0x84, 0x96, 0x0b, 0x97, 0xf0, 0x3e, 0xf8, 0x1b, 0x44, 0xa9, 0xac, 0x24, 0x1c, 0x5e, 0x1f, 0xc3, 0xbc, 0xf9, 0x38, 0xf5, 0x0b, 0xa6, 0xe1, 0xb6, 0xdd, 0xc0, 0x2b, 0xce, 0xc5, 0x3f, 0xe1, 0x66,
0x8d, 0x5c, 0xa5, 0x4e, 0xc5, 0xe7, 0xe0, 0x5b, 0x9b, 0xdd, 0x42, 0xc3, 0xd4, 0x2b, 0xd3, 0xaa, 0x88, 0xbe, 0x83, 0x27, 0x9f, 0xb1, 0xc2, 0x1d, 0xe6, 0x3f, 0x7b, 0x0c, 0xc8, 0x53, 0x18, 0x31,
0x7a, 0xb2, 0x1a, 0x73, 0x01, 0x57, 0xa3, 0xfe, 0xf7, 0x05, 0x5c, 0x89, 0x7b, 0x68, 0x18, 0xf3, 0x5e, 0xa9, 0x6d, 0xec, 0xcf, 0xbc, 0x79, 0x90, 0xda, 0x82, 0x7e, 0x84, 0xeb, 0x46, 0xe8, 0xac,
0xb0, 0x73, 0x16, 0x41, 0x30, 0xcf, 0x73, 0x89, 0xca, 0x70, 0x8c, 0x73, 0x67, 0xf2, 0x31, 0x04, 0xdf, 0xc2, 0xa5, 0x72, 0x67, 0x46, 0x1f, 0x2d, 0x27, 0x5d, 0xf7, 0xa3, 0xea, 0x38, 0x4b, 0xdf,
0x13, 0x2a, 0x0a, 0xcc, 0xf4, 0x29, 0x6d, 0xf1, 0x11, 0xf8, 0x93, 0x15, 0x29, 0x3c, 0x29, 0x69, 0x40, 0xa0, 0x9f, 0xa9, 0xe3, 0x1c, 0x43, 0xf8, 0x95, 0x31, 0xc1, 0xa5, 0x34, 0xde, 0xe3, 0xb4,
0x0c, 0xc1, 0x0b, 0xad, 0x44, 0x26, 0x4e, 0xab, 0xf5, 0x0a, 0x0d, 0xf3, 0x6e, 0xff, 0xfc, 0x6c, 0x2e, 0x29, 0x83, 0xcb, 0x9a, 0x43, 0x5e, 0x42, 0xa0, 0x17, 0xe5, 0x1c, 0xfb, 0xde, 0xd7, 0xcc,
0xf6, 0x27, 0x9d, 0x68, 0xf8, 0xe5, 0x41, 0x30, 0x73, 0x7e, 0x36, 0x85, 0xa6, 0x99, 0x20, 0xc3, 0x34, 0x9b, 0xf7, 0xff, 0x67, 0xf3, 0x37, 0x10, 0xde, 0x62, 0x59, 0xf2, 0x4c, 0x0d, 0x31, 0xa1,
0x52, 0x2c, 0x3e, 0xce, 0xdb, 0x9b, 0xb6, 0xce, 0x4d, 0x55, 0xd8, 0x0d, 0x08, 0xaf, 0xed, 0x68, 0x2b, 0x18, 0xdd, 0xee, 0x50, 0xf2, 0x41, 0xa2, 0x1b, 0x08, 0xd7, 0xb8, 0x2b, 0xb2, 0x62, 0x98,
0xee, 0xdf, 0xe3, 0x8a, 0x2e, 0xaa, 0x69, 0xfb, 0xe3, 0xc6, 0x6b, 0xec, 0x09, 0xc0, 0xf2, 0xcd, 0xd7, 0x17, 0x08, 0xf4, 0xbf, 0x3f, 0x74, 0x09, 0x36, 0x21, 0xbd, 0x4b, 0x30, 0x81, 0xb2, 0x43,
0x02, 0x28, 0x16, 0xfd, 0xe8, 0xcb, 0x95, 0xd8, 0x91, 0xe2, 0xa3, 0xc8, 0xef, 0xb6, 0x16, 0xe7, 0xcb, 0x5f, 0x3e, 0x84, 0xf7, 0xf6, 0x9c, 0xdc, 0xc1, 0x58, 0x07, 0x59, 0xb3, 0x24, 0x99, 0x76,
0x76, 0x79, 0x46, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xaf, 0xb8, 0x9b, 0x3f, 0x94, 0x03, 0x00, 0x75, 0xad, 0xd0, 0x4f, 0x9e, 0xf7, 0xb5, 0x6d, 0x58, 0xe8, 0x45, 0x4d, 0xd3, 0x66, 0x27, 0x69,
0x00, 0xad, 0xd4, 0x9f, 0xa2, 0xb5, 0x53, 0x4f, 0x2f, 0xc8, 0xba, 0x15, 0x89, 0x17, 0x67, 0x62, 0xe7,
0x80, 0xf4, 0xdc, 0xc8, 0x11, 0xfa, 0x01, 0xc0, 0x3c, 0xb4, 0xbe, 0xdc, 0x92, 0xc4, 0x8d, 0xc6,
0x5d, 0xf7, 0x9a, 0x36, 0xed, 0x74, 0xfe, 0x7c, 0xd7, 0xcd, 0x43, 0xf3, 0x61, 0x58, 0xfd, 0x0e,
0x00, 0x00, 0xff, 0xff, 0xdc, 0xcf, 0x08, 0x89, 0x70, 0x04, 0x00, 0x00,
} }

View File

@ -8,6 +8,7 @@ import "github.com/micro/go-micro/router/proto/router.proto";
service Network { service Network {
rpc ListNodes(ListRequest) returns (ListResponse) {}; rpc ListNodes(ListRequest) returns (ListResponse) {};
rpc ListPeers(PeerRequest) returns (PeerResponse) {}; rpc ListPeers(PeerRequest) returns (PeerResponse) {};
rpc Topology(TopologyRequest) returns (TopologyResponse) {};
rpc ListRoutes(go.micro.router.Request) returns (go.micro.router.ListResponse) {}; rpc ListRoutes(go.micro.router.Request) returns (go.micro.router.ListResponse) {};
} }
@ -28,15 +29,20 @@ message PeerRequest {
// PeerResponse is returned by ListPeers // PeerResponse is returned by ListPeers
message PeerResponse { message PeerResponse {
Peers peers = 1; repeated Node peers = 1;
} }
// Peers are node peers // TopologyRequest list node topology
message Peers { message TopologyRequest {
// network node // node id
Node node = 1; string id = 1;
// node peers // topology depth
repeated Node peers = 2; uint64 depth = 2;
}
// TopologyResponse is returned by Topology
message TopologyResponse {
Topology topology = 1;
} }
// Node is network node // Node is network node
@ -47,6 +53,14 @@ message Node {
string address = 2; string address = 2;
} }
// Topology is used to nnounce node neighbourhood
message Topology {
// network node
Node node = 1;
// neighbours
repeated Node nodes = 2;
}
// Connect is sent when the node connects to the network // Connect is sent when the node connects to the network
message Connect { message Connect {
// network mode // network mode