/
cluster.go
175 lines (143 loc) · 3.52 KB
/
cluster.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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
package cluster
import (
"encoding/json"
zmq "github.com/pebbe/zmq4"
"io/ioutil"
"strconv"
)
type server struct {
Serverid int `json:"serverid"`
Portno int `json:"portno"`
}
type serverlist struct {
RunningServer []server
}
const (
BROADCAST int = -1
)
type Envelope struct {
// On the sender side, Pid identifies the receiving peer. If instead, Pid is
// set to cluster.BROADCAST, the message is sent to all peers. On the receiver side, the
// Id is always set to the original sender. If the Id is not found, the message is silently dropped
Pid int
// An id that globally and uniquely identifies the message, meant for duplicate detection at
// higher levels. It is opaque to this package.
// the actual message.
Msgtype string
Msg []byte
}
type Server interface {
// Id of this server
Pid() int
// array of other servers' ids in the same cluster
Peers() map[int]int
// the channel to use to send messages to other peers
// Note that there are no guarantees of message delivery, and messages
// are silently dropped
Outbox() chan *Envelope
// the channel to receive messages from other peers.
Inbox() chan *Envelope
}
type Servernode struct {
sid int
pid int
Ownsocks *zmq.Socket
peers map[int]int
outbox chan *Envelope
inbox chan *Envelope
peersocks map[int]*zmq.Socket
}
func (s Servernode) Pid() int {
return s.pid
}
func (s Servernode) Peers() map[int]int {
return s.peers
}
func (s Servernode) Outbox() chan *Envelope {
return s.outbox
}
func (s Servernode) Inbox() chan *Envelope {
return s.inbox
}
var mapofservers map[int]int
func (s Servernode)SendMessage(){
var tempinstance Envelope
for {
tempinstance = *<-s.outbox
msg,err:=json.Marshal(tempinstance)
if err!=nil{
panic(err)
}
if tempinstance.Pid==BROADCAST{
for _,sock:= range s.peersocks{
sock.SendBytes(msg,zmq.DONTWAIT)
}
}else{
tempsock:=s.peersocks[mapofservers[tempinstance.Pid]]
tempsock.SendBytes(msg,zmq.DONTWAIT)
}
}
}
func (s Servernode)RecieveMessage(responder *zmq.Socket){
for {
msgbytes,err:=responder.RecvBytes(0)
var data Envelope
if err!=nil{
panic(err)
}
err1:=json.Unmarshal(msgbytes,&data)
if err1 !=nil {
panic("panic in Unmarshling the data")
}
s.inbox <- &data
}
}
func New(serverid int,filename string) Servernode {
var data serverlist
content, err := ioutil.ReadFile(filename)
if err != nil {
panic(err)
}
err = json.Unmarshal(content, &data)
if err != nil {
panic("Error parsing json File")
}
mapofservers = make(map[int]int)
for i := 0; i <len(data.RunningServer); i++ {
mapofservers[data.RunningServer[i].Serverid] = data.RunningServer[i].Portno
}
var s Servernode
s.peers=make(map[int]int)
s.peersocks=make(map[int]*zmq.Socket)
_, exist := mapofservers[serverid]
if exist != true {
panic("Error in creation of new server instance")
}
s.sid = serverid
s.pid = mapofservers[serverid]
s.outbox = make(chan *Envelope)
s.inbox = make(chan *Envelope)
var responder *zmq.Socket
var requester *zmq.Socket
for id, port:= range mapofservers{
if id ==serverid {
responder, err= zmq.NewSocket(zmq.PULL)
s.Ownsocks = responder
responder.Bind("tcp://*:"+strconv.Itoa(port))
if err != nil {
panic("Problem Binding Server")
}
}else{
requester, err = zmq.NewSocket(zmq.PUSH);
if err != nil {
panic("Problem Binding Server")
}
requester.Connect("tcp://localhost:"+strconv.Itoa(port))
s.peers[id]=port
s.peersocks[port]=requester
}
}
go s.SendMessage()
go s.RecieveMessage(responder)
return s
}