/
helpers.go
137 lines (117 loc) · 3.71 KB
/
helpers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright © 2018 Charles Corebtt <nafredy@gmail.com>
//
package service
import "log"
// MessageToNode converts NodeMessage{} to Node{}
func (s *Server) MessageToNode(inNode *NodeMessage) *Node {
newNode := &Node{
Name: inNode.Name,
Host: inNode.Host,
Port: int(inNode.Port),
}
return newNode
}
// NodeToMessage converts Node{} to NodeMessage{}
func (s *Server) NodeToMessage(inNode *Node) *NodeMessage {
newNode := &NodeMessage{
Name: inNode.Name,
Host: inNode.Host,
Port: int32(inNode.Port),
}
return newNode
}
// CheckPoolForNode checks my pool for a nodes name and port
func (s *Server) CheckPoolForNode(node *NodeMessage) bool {
poolNames := make(map[string]int)
// If we already know the server we don't have to do aything
for _, poolNode := range s.Me.Pool.nodes {
poolNames[poolNode.Name] = poolNode.Port
}
if _, ok := poolNames[node.Name]; ok { //&& val == int(node.Port) saving this for now
return true
}
return false
}
// InformPoolOfNodes informs the entire pool of changes to its pool
func (s *Server) InformPoolOfNodes() error {
// Give each of my nodes my phonebook, minus themselves
if len(s.Me.Pool.nodes) > 0 {
log.Printf("[network] Informing my bootnodes of their graph...\n")
for i := range s.Me.Pool.nodes {
log.Printf("[network] Sending %s my phonebook...\n", s.Me.Pool.nodes[i].Name)
ierr := s.informNode(s.Me.Pool.nodes[i])
if ierr != nil {
log.Printf("[network] Informing failed: %v\n", ierr)
return ierr
}
log.Printf("[network] %s and I have swapped phonebooks.\n", s.Me.Pool.nodes[i].Name)
}
}
return nil
}
// AskPeersForNode asks the peers for a node
func (s *Server) AskPeersForNode(name string, exclude []string) error {
log.Printf("I am not familiar with %s, so I am going to ask my peers...", name)
OUTER:
for _, thisNode := range s.Me.Pool.nodes {
log.Printf("[asking]: %s", thisNode.Name)
log.Printf("[asking] Excluding: %s", exclude)
for _, e := range exclude {
if e == thisNode.Name {
continue OUTER
}
}
log.Printf("Asking %s for %s", thisNode.Name, name)
found, ferr := s.requestNode(thisNode, name, exclude)
if ferr != nil {
log.Printf("%v", ferr)
exclude = append(exclude, thisNode.Name)
continue
}
s.AddNodeToPool(found)
break
}
return nil
}
// CheckPoolForNodeByName checks my pool for nodes by name
func (s *Server) CheckPoolForNodeByName(name string) (*NodeMessage, bool) {
for _, node := range s.Me.Pool.nodes {
if node.Name == name {
return s.NodeToMessage(node), true
}
}
return &NodeMessage{}, false
}
// AddNodeToPool checks for a nodes existence in its pool and adds if it doesn't
func (s *Server) AddNodeToPool(node *NodeMessage) error {
// need to think on this, it feels wrong
if !s.CheckPoolForNode(node) {
log.Printf("[%s@%s:%d] is new to me. Adding to my phonebook.\n", node.Name, node.Host, node.Port)
s.Me.Pool.nodes = append(s.Me.Pool.nodes, s.MessageToNode(node))
}
return nil
}
// BuildInformPool builds the pool in a format for gRPC
func (s *Server) BuildInformPool(name string, port int) *NodeInformMessage {
// TODO: Fix this variables to be a struct, but must think on it
// This was the quickest path for me
// On a future refactor once everything is working I will shift this
// burden on to the recipients
// Our basic inform payload
informPayload := &NodeInformMessage{
Informer: &NodeMessage{
Name: s.Name,
Host: s.Host,
Port: int32(s.Port),
},
Pool: []*NodeMessage{},
}
// Iter through our nodes, rip out our destination, and pack the rest
for _, poolNode := range s.Me.Pool.nodes {
if poolNode.Name == name && poolNode.Port == port {
continue
}
informPayload.Pool = append(informPayload.Pool, s.NodeToMessage(poolNode))
}
return informPayload
}