-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
140 lines (115 loc) · 3.32 KB
/
main.go
File metadata and controls
140 lines (115 loc) · 3.32 KB
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
138
139
140
package main
// This file contains the main function for the program. The node is initialized, the two UDP monitors are started,
// and the RPC server is started for MP1 querying
import (
"context"
"fmt"
"net"
"os/signal"
"strconv"
"log"
"net/http"
"net/rpc"
"os"
"time"
"gitlab.engr.illinois.edu/cs425mps/MP3/logQuery/rpc_export"
"gitlab.engr.illinois.edu/cs425mps/MP3/membership"
"gitlab.engr.illinois.edu/cs425mps/MP3/membership/node"
)
// UniversalLog for logging events
var UniversalLog *log.Logger
// UDPPort for all nodes
var UDPPort = 31337
// IntroPort is used for introduction
var IntroPort = 33333
// HashRingSize is how big our hashring is
const HashRingSize = 4294967296
func main() {
myNode, err := node.InitNode(os.Stdin) // Initialize the current node
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
if err := myNode.Start(ctx); err != nil { // Start the node's helper functions and monitors
myNode.Logger.Println(err)
}
UniversalLog = myNode.Logger // Start logger
// Generate a chan to send kill signal
killSignal := make(chan bool, 1)
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
// Contact introduction node to get initial membership list
host, err := os.Hostname()
if err != nil {
UniversalLog.Fatal("Couldn't get hostname")
}
rpcID := -1
if len(host) > 17 {
rpcID, _ = strconv.Atoi(host[15:17])
}
me := node.OtherNode{
NodeID: myNode.NodeID,
Hostname: myNode.Hostname,
TCPPort: myNode.TCPPort,
UDPPort: myNode.UDPPort,
UDPAddr: myNode.UDPAddr,
}
myNode.Members.Add(me) // Add ourself to our membership list
membership.StartNode(myNode)
// Set pointers in RPC Export
rpc_export.SetKill(&killSignal)
rpc_export.SetLogger(UniversalLog)
rpc_export.SetNodeID(rpcID)
// Make node for RPC Export
rpcNode := new(rpc_export.Node)
// Export all RPC Calls
rpc.Register(rpcNode)
// rpc.HandleHTTP()
l, e := net.Listen("tcp", fmt.Sprintf(":%d", 10000+rpcID))
if e != nil {
UniversalLog.Fatal("TCP Server Listen Error:", e)
}
// Handle RPC Calls
go http.Serve(l, nil)
rpcNode2 := new(node.RPCNode)
// Export all RPC Calls
rpc.Register(rpcNode2)
rpc.HandleHTTP()
l2, e := net.Listen("tcp", fmt.Sprintf(":%d", 20000+rpcID))
if e != nil {
UniversalLog.Fatal("TCP Server Listen Error:", e)
}
// Handle RPC Calls
go http.Serve(l2, nil)
// Send Join
baseMsg := &node.Message{
NodeID: myNode.NodeID,
Hostname: host,
UDPPort: 31337,
Orig: "JOIN," + strconv.FormatUint(myNode.NodeID, 10) + "," + host,
}
joinMsg := &node.JoinMessage{
Message: baseMsg,
TCPPort: 10000 + rpcID,
}
myNode.Neighbors.L.Lock()
for i := 1; i < 11; i++ { // Ask for introductions from all available nodes
err := myNode.AskForIntroduction(IntroPort, i)
if err != nil {
fmt.Print("Error asking for introduction ")
fmt.Println(err)
continue
}
}
time.Sleep(500 * time.Millisecond) // Wait for member lists to come in before sending joins
err = myNode.SendJoin(joinMsg) // Tell other nodes in the network that we want to join
myNode.Neighbors.L.Unlock() // Release lock and start failure detection
if err != nil {
UniversalLog.Fatal("Failed to send 'Join' to neighbors!", err)
}
select { // Catches interrupts so we can end the program
case <-interrupt:
UniversalLog.Printf("@ Node Terminated Normally @")
os.Exit(0)
}
}