-
Notifications
You must be signed in to change notification settings - Fork 0
/
options.go
242 lines (203 loc) · 6.22 KB
/
options.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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
package gopaxos
import (
"encoding/binary"
"net"
"os"
)
// Options is the global config of paxos.
type Options struct {
//optional
//User-specified paxoslog storage.
//Default is nil
LogStorage LogStorage
//optional
//If poLogStorage == nil, sLogStoragePath is required.
LogStoragePath string
//optional
//If true, the write will be flushed from the operating system
//buffer cache before the write is considered complete.
//If this flag is true, writes will be slower.
//
//If this flag is false, and the machine crashes, some recent
//writes may be lost. Note that if it is just the process that
//crashes (i.e., the machine does not reboot), no writes will be
//lost even if sync==false. Because of the data lost, we not guarantee consistence.
//
//Default is true.
Sync bool
//optional
//Default is 0.
//This means the write will skip flush at most iSyncInterval times.
//That also means you will lost at most iSyncInterval count's paxos log.
SyncInterval int
//optional
//User-specified network.
Network Network
//optional
//Our default network use udp and tcp combination, a message we use udp or tcp to send decide by a threshold.
//Message size under iUDPMaxSize we use udp to send.
//Default is 4096.
UDPMaxSize uint64
//optional
//We support to run multi phxpaxos on one process.
//One paxos group here means one independent phxpaxos. Any two phxpaxos(paxos group) only share network, no other.
//There is no communication between any two paxos group.
//Default is 1.
GroupCount int
//required
//Self node's ip/port.
MyNode NodeInfo
//required
//All nodes's ip/port with a paxos set(usually three or five nodes).
NodeInfoList NodeInfoList
//optional
//Only bUseMembership == true, we use option's sliNodeInfoList to init paxos membership,
//after that, paxos will remember all nodeinfos, so second time you can run paxos without sliNodeInfoList,
//and you can only change membership by the api.
//
//Default is false.
//if bUseMembership == false, that means every time you run paxos will use vecNodeList to build a new membership.
//when you change membership by a new vecNodeList, we don't guarantee consistence.
//
//For test, you can set false.
//But when you use it to real services, remember to set true.
UseMembership bool
//While membership change, phxpaxos will call this function.
//Default is nil.
MembershipChangeCallback MembershipChangeCallback
//optional
//One phxpaxos can mounting multi state machines.
//This vector include different phxpaxos's state machines list.
GroupSMInfoList GroupSMInfoList
//optional
Breakpoint Breakpoint
//optional
//If use this mode, that means you propose large value(maybe large than 5M means large) much more.
//Large value means long latency, long timeout, this mode will fit it.
//Default is false
IsLargeValueMode bool
//optional
//All followers's ip/port, and follow to node's ip/port.
//Follower only learn but not participation paxos algorithmic process.
//Default is empty.
FollowerNodeInfoList FollowerNodeInfoList
//optional
//Notice, this function must be thread safe!
//if pLogFunc == nil, we will print log to standard ouput.
LogFunc LogFunc
//optional
//If you use your own log function, then you control loglevel yourself, ignore this.
//Check log.go to find 5 level.
//Default is LogLevel::LogLevel_None, that means print no log.
LogLevel LogLevel
//optional
//If you use checkpoint replayer feature, set as true.
//Default is false;
IsUseCheckpointRePlayer bool
//optional
//Only bUseBatchPropose is true can use API BatchPropose in node.h
//Default is false;
IsUseBatchPropose bool
//optional
//Only bOpenChangeValueBeforePropose is true, that will callback sm's function(BeforePropose).
//Default is false;
IsOpenChangeValueBeforePropose bool
}
func NewOptions() *Options {
return &Options{
LogStorage: nil,
LogStoragePath: "",
Sync: true,
SyncInterval: 0,
Network: nil,
UDPMaxSize: 4096,
GroupCount: 1,
UseMembership: false,
MembershipChangeCallback: nil,
Breakpoint: nil,
IsLargeValueMode: false,
LogFunc: nil,
LogLevel: LogLevel_None,
IsUseCheckpointRePlayer: false,
IsUseBatchPropose: false,
IsOpenChangeValueBeforePropose: false,
}
}
const nullNode = uint64(0)
type NodeInfo struct {
iNodeId uint64
sIP string
iPort int
}
func NewNodeInfo(iNodeId uint64, ip string, port int) *NodeInfo {
return &NodeInfo{
iNodeId: iNodeId,
sIP: ip,
iPort: port,
}
}
func (n *NodeInfo) GetNodeID() uint64 {
return n.iNodeId
}
func (n *NodeInfo) GetIP() string {
return n.sIP
}
func (n *NodeInfo) GetPort() int {
return n.iPort
}
func (n *NodeInfo) SetIPPort(ip string, port int) *NodeInfo {
n.sIP = ip
n.iPort = port
n.makeNodeID()
return n
}
func (n *NodeInfo) SetNodeID(iNodeId uint64) *NodeInfo {
n.iNodeId = iNodeId
n.parseNodeID()
return n
}
func (n *NodeInfo) makeNodeID() {
if n.sIP == "" {
n.sIP = "0.0.0.0"
}
bip := net.ParseIP(n.sIP).To4()
if len(bip) < 4 {
lPLErr("ip format error: %s", n.sIP)
os.Exit(1)
}
iip := uint64(binary.LittleEndian.Uint32(bip))
n.iNodeId = uint64((iip << 32) | uint64(n.iPort))
}
func (n *NodeInfo) parseNodeID() {
n.iPort = int(n.iNodeId) & 0xFFFFFFFF
buf := make([]byte, 4)
binary.LittleEndian.PutUint32(buf, uint32(n.iNodeId>>32))
n.sIP = net.IPv4(buf[0], buf[1], buf[2], buf[3]).String()
}
type FollowerNodeInfo struct {
MyNode NodeInfo
FollowNode NodeInfo
}
type NodeInfoList []*NodeInfo
type FollowerNodeInfoList []*FollowerNodeInfo
type GroupSMInfo struct {
//required
//GroupIdx interval is [0, GroupCount)
GroupIdx int
//optional
//One paxos group can mounting multi state machines.
SMList []StateMachine
//optional
//Master election is a internal state machine.
//Set IsUseMaster as true to open master election feature.
//Default is false.
IsUseMaster bool
}
func NewGroupInfo() *GroupSMInfo {
return &GroupSMInfo{
GroupIdx: -1,
IsUseMaster: false,
}
}
type GroupSMInfoList []*GroupSMInfo
type MembershipChangeCallback func(int, NodeInfoList)