Skip to content

Commit 268785f

Browse files
committed
Sentinel-10: kvraft comment thru
1 parent 729fa45 commit 268785f

File tree

4 files changed

+103
-102
lines changed

4 files changed

+103
-102
lines changed

kvraft/client.go

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,25 @@ import (
77

88
"github.com/ReshiAdavan/Sentinel/rpc"
99
)
10+
11+
// Clerk is a client for a Raft-based key-value store.
1012
type Clerk struct {
11-
servers []*rpc.ClientEnd
12-
mu sync.Mutex
13-
clientId int64
14-
requestId int64
15-
leader int
13+
servers []*rpc.ClientEnd // List of RPC client endpoints for the Raft servers.
14+
mu sync.Mutex // Mutex to protect concurrent access to the next fields.
15+
clientId int64 // Unique client identifier.
16+
requestId int64 // Incrementing request ID to distinguish different requests from the same client.
17+
leader int // Index of the server believed to be the leader.
1618
}
1719

20+
// nrand generates a random 62-bit integer, used for generating unique client IDs.
1821
func nrand() int64 {
1922
max := big.NewInt(int64(1) << 62)
2023
bigx, _ := rand.Int(rand.Reader, max)
2124
x := bigx.Int64()
2225
return x
2326
}
2427

28+
// MakeClerk initializes a new Clerk instance with a list of server RPC endpoints.
2529
func MakeClerk(servers []*rpc.ClientEnd) *Clerk {
2630
ck := new(Clerk)
2731
ck.servers = servers
@@ -32,64 +36,68 @@ func MakeClerk(servers []*rpc.ClientEnd) *Clerk {
3236
}
3337

3438
/*
35-
* Fetch the current value for a key.
36-
* Returns "" if the key does not exist.
37-
* Keeps trying forever in the face of all other errors
38-
* The types of args and reply (including whether they are pointers)
39-
must match the declared types of the RPC handler function's
40-
arguments and reply must be passed as a pointer.
39+
* Get fetches the current value for a key from the key-value store.
40+
* It returns an empty string if the key does not exist.
41+
* The function retries indefinitely in case of errors, trying to find the correct leader.
4142
*/
42-
4343
func (ck *Clerk) Get(key string) string {
4444
args := GetArgs{}
4545
args.Key = key
4646
args.ClientId = ck.clientId
47+
48+
// Locking to ensure that requestId is incremented atomically.
4749
ck.mu.Lock()
4850
args.RequestId = ck.requestId
4951
ck.requestId++
5052
ck.mu.Unlock()
5153

52-
for ; ; ck.leader = (ck.leader + 1) % len(ck.servers) {
54+
// Keep trying different servers until a valid response is received.
55+
for {
5356
server := ck.servers[ck.leader]
5457
reply := GetReply{}
5558
ok := server.Call("KVServer.Get", &args, &reply)
5659
if ok && !reply.WrongLeader {
5760
return reply.Value
5861
}
62+
ck.leader = (ck.leader + 1) % len(ck.servers)
5963
}
6064
}
6165

6266
/*
63-
* Shared by Put and Append.
64-
* The types of args and reply (including whether they are pointers)
65-
must match the declared types of the RPC handler function's
66-
arguments and reply must be passed as a pointer.
67+
* PutAppend either puts a new value for a key or appends to an existing value, based on the operation type.
68+
* This is a helper function used by both Put and Append.
6769
*/
68-
6970
func (ck *Clerk) PutAppend(key string, value string, op string) {
7071
args := PutAppendArgs{}
7172
args.Key = key
7273
args.Value = value
7374
args.Command = op
7475
args.ClientId = ck.clientId
76+
77+
// Locking to ensure that requestId is incremented atomically.
7578
ck.mu.Lock()
7679
args.RequestId = ck.requestId
7780
ck.requestId++
7881
ck.mu.Unlock()
7982

80-
for ; ; ck.leader = (ck.leader + 1) % len(ck.servers) {
83+
// Keep trying different servers until a valid response is received.
84+
for {
8185
server := ck.servers[ck.leader]
8286
reply := PutAppendReply{}
8387
ok := server.Call("KVServer.PutAppend", &args, &reply)
8488
if ok && !reply.WrongLeader {
8589
return
8690
}
91+
ck.leader = (ck.leader + 1) % len(ck.servers)
8792
}
8893
}
8994

95+
// Put inserts or updates the value for a given key in the key-value store.
9096
func (ck *Clerk) Put(key string, value string) {
9197
ck.PutAppend(key, value, "put")
9298
}
99+
100+
// Append appends the given value to the existing value for a given key in the key-value store.
93101
func (ck *Clerk) Append(key string, value string) {
94102
ck.PutAppend(key, value, "append")
95103
}

kvraft/common.go

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,39 @@
11
package raftkv
22

3+
// Constants defining possible error states.
34
const (
4-
OK = "OK"
5-
ErrNoKey = "ErrNoKey"
5+
OK = "OK" // Indicates successful operation.
6+
ErrNoKey = "ErrNoKey" // Indicates that the requested key does not exist in the key-value store.
67
)
78

9+
// Err is a custom type representing an error string.
810
type Err string
911

10-
// Put or Append
12+
// PutAppendArgs defines the arguments structure for Put and Append operations.
1113
type PutAppendArgs struct {
12-
Key string
13-
Value string
14-
Command string // "Put" or "Append"
15-
ClientId int64
16-
RequestId int64
14+
Key string // Key in the key-value store.
15+
Value string // Value to be associated with the key.
16+
Command string // Operation type: "Put" or "Append".
17+
ClientId int64 // Unique client identifier to differentiate requests.
18+
RequestId int64 // Unique request identifier for idempotency.
1719
}
1820

21+
// PutAppendReply defines the reply structure for Put and Append operations.
1922
type PutAppendReply struct {
20-
WrongLeader bool
21-
Err Err
23+
WrongLeader bool // Flag to indicate if the operation reached a non-leader server.
24+
Err Err // Error status of the operation.
2225
}
2326

27+
// GetArgs defines the arguments structure for Get operation.
2428
type GetArgs struct {
25-
Key string
26-
ClientId int64
27-
RequestId int64
29+
Key string // Key to retrieve from the key-value store.
30+
ClientId int64 // Unique client identifier.
31+
RequestId int64 // Unique request identifier.
2832
}
2933

34+
// GetReply defines the reply structure for Get operation.
3035
type GetReply struct {
31-
WrongLeader bool
32-
Err Err
33-
Value string
36+
WrongLeader bool // Flag to indicate if the operation reached a non-leader server.
37+
Err Err // Error status of the operation.
38+
Value string // The value retrieved for the key, if any.
3439
}

kvraft/config.go

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@ import (
1919
"github.com/ReshiAdavan/Sentinel/raft"
2020
)
2121

22+
// randstring generates a random string of a specified length.
2223
func randstring(n int) string {
2324
b := make([]byte, 2*n)
2425
crand.Read(b)
2526
s := base64.URLEncoding.EncodeToString(b)
2627
return s[0:n]
2728
}
2829

29-
// Randomize server handles
30+
// random_handles shuffles the server handles for load balancing or test randomness.
3031
func random_handles(kvh []*rpc.ClientEnd) []*rpc.ClientEnd {
3132
sa := make([]*rpc.ClientEnd, len(kvh))
3233
copy(sa, kvh)
@@ -37,6 +38,7 @@ func random_handles(kvh []*rpc.ClientEnd) []*rpc.ClientEnd {
3738
return sa
3839
}
3940

41+
// config holds the configuration for a set of raft servers and clients for testing.
4042
type config struct {
4143
mu sync.Mutex
4244
t *testing.T
@@ -55,6 +57,7 @@ type config struct {
5557
ops int32 // number of clerk get/put/append method calls
5658
}
5759

60+
// cleanup terminates all the servers in the configuration.
5861
func (cfg *config) cleanup() {
5962
cfg.mu.Lock()
6063
defer cfg.mu.Unlock()
@@ -65,7 +68,7 @@ func (cfg *config) cleanup() {
6568
}
6669
}
6770

68-
// Maximum log size across all servers
71+
// LogSize calculates the maximum log size across all servers.
6972
func (cfg *config) LogSize() int {
7073
logsize := 0
7174
for i := 0; i < cfg.n; i++ {
@@ -77,7 +80,7 @@ func (cfg *config) LogSize() int {
7780
return logsize
7881
}
7982

80-
// Maximum snapshot size across all servers
83+
// SnapshotSize calculates the maximum snapshot size across all servers.
8184
func (cfg *config) SnapshotSize() int {
8285
snapshotsize := 0
8386
for i := 0; i < cfg.n; i++ {
@@ -89,10 +92,7 @@ func (cfg *config) SnapshotSize() int {
8992
return snapshotsize
9093
}
9194

92-
/*
93-
* Attach server i to servers listed in to caller must hold cfg.mu
94-
*/
95-
95+
// connectUnlocked connects server i to the servers listed in `to`. Caller must hold cfg.mu.
9696
func (cfg *config) connectUnlocked(i int, to []int) {
9797
// log.Printf("connect peer %d to %v\n", i, to)
9898

@@ -115,10 +115,7 @@ func (cfg *config) connect(i int, to []int) {
115115
cfg.connectUnlocked(i, to)
116116
}
117117

118-
/*
119-
* Detach server i from the servers listed in from caller must hold cfg.mu
120-
*/
121-
118+
// disconnectUnlocked disconnects server i from the servers listed in `from`. Caller must hold cfg.mu.
122119
func (cfg *config) disconnectUnlocked(i int, from []int) {
123120
// log.Printf("disconnect peer %d from %v\n", i, from)
124121

@@ -145,6 +142,7 @@ func (cfg *config) disconnect(i int, from []int) {
145142
cfg.disconnectUnlocked(i, from)
146143
}
147144

145+
// All returns a slice of all server indices.
148146
func (cfg *config) All() []int {
149147
all := make([]int, cfg.n)
150148
for i := 0; i < cfg.n; i++ {
@@ -153,6 +151,7 @@ func (cfg *config) All() []int {
153151
return all
154152
}
155153

154+
// ConnectAll connects all servers in the configuration.
156155
func (cfg *config) ConnectAll() {
157156
cfg.mu.Lock()
158157
defer cfg.mu.Unlock()
@@ -161,7 +160,7 @@ func (cfg *config) ConnectAll() {
161160
}
162161
}
163162

164-
// Sets up 2 partitions with connectivity between servers in each partition.
163+
// partition sets up 2 partitions with connectivity between servers in each partition.
165164
func (cfg *config) partition(p1 []int, p2 []int) {
166165
cfg.mu.Lock()
167166
defer cfg.mu.Unlock()
@@ -176,10 +175,7 @@ func (cfg *config) partition(p1 []int, p2 []int) {
176175
}
177176
}
178177

179-
/*
180-
* Create a clerk with clerk specific server names.
181-
* Give it connections to all of the servers, but for now enable only connections to servers in to[].
182-
*/
178+
// makeClient creates a clerk with specific server names and connections.
183179
func (cfg *config) makeClient(to []int) *Clerk {
184180
cfg.mu.Lock()
185181
defer cfg.mu.Unlock()
@@ -211,7 +207,7 @@ func (cfg *config) deleteClient(ck *Clerk) {
211207
delete(cfg.clerks, ck)
212208
}
213209

214-
// caller should hold cfg.mu
210+
// ConnectClientUnlocked connects a client to specified servers. Caller should hold cfg.mu.
215211
func (cfg *config) ConnectClientUnlocked(ck *Clerk, to []int) {
216212
// log.Printf("ConnectClient %v to %v\n", ck, to)
217213
endnames := cfg.clerks[ck]
@@ -221,13 +217,14 @@ func (cfg *config) ConnectClientUnlocked(ck *Clerk, to []int) {
221217
}
222218
}
223219

220+
// ConnectClient wraps ConnectClientUnlocked with mutex locking.
224221
func (cfg *config) ConnectClient(ck *Clerk, to []int) {
225222
cfg.mu.Lock()
226223
defer cfg.mu.Unlock()
227224
cfg.ConnectClientUnlocked(ck, to)
228225
}
229226

230-
// caller should hold cfg.mu
227+
// DisconnectClientUnlocked disconnects a client from specified servers. Caller should hold cfg.mu.
231228
func (cfg *config) DisconnectClientUnlocked(ck *Clerk, from []int) {
232229
// log.Printf("DisconnectClient %v from %v\n", ck, from)
233230
endnames := cfg.clerks[ck]
@@ -237,13 +234,14 @@ func (cfg *config) DisconnectClientUnlocked(ck *Clerk, from []int) {
237234
}
238235
}
239236

237+
// DisconnectClient wraps DisconnectClientUnlocked with mutex locking.
240238
func (cfg *config) DisconnectClient(ck *Clerk, from []int) {
241239
cfg.mu.Lock()
242240
defer cfg.mu.Unlock()
243241
cfg.DisconnectClientUnlocked(ck, from)
244242
}
245243

246-
// Shutdown a server by isolating it
244+
// ShutdownServer isolates and shuts down a specified server.
247245
func (cfg *config) ShutdownServer(i int) {
248246
cfg.mu.Lock()
249247
defer cfg.mu.Unlock()
@@ -327,7 +325,7 @@ func (cfg *config) Leader() (bool, int) {
327325
return false, 0
328326
}
329327

330-
// Partition servers into 2 groups and put current leader in minority
328+
// make_partition partitions the servers, ensuring the current leader is in the minority.
331329
func (cfg *config) make_partition() ([]int, []int) {
332330
_, l := cfg.Leader()
333331
p1 := make([]int, cfg.n/2+1)
@@ -379,15 +377,12 @@ func make_config(t *testing.T, n int, unreliable bool, maxraftstate int) *config
379377
return cfg
380378
}
381379

380+
// rpcTotal returns the total number of RPC calls made.
382381
func (cfg *config) rpcTotal() int {
383382
return cfg.net.GetTotalCount()
384383
}
385384

386-
/*
387-
* Start a Test.
388-
* Print the Test message.
389-
*/
390-
385+
// begin starts a test and prints the test message.
391386
func (cfg *config) begin(description string) {
392387
fmt.Printf("%s ...\n", description)
393388
cfg.t0 = time.Now()
@@ -404,15 +399,12 @@ func (cfg *config) begin(description string) {
404399
}()
405400
}
406401

402+
// op records an operation performed by a clerk.
407403
func (cfg *config) op() {
408404
atomic.AddInt32(&cfg.ops, 1)
409405
}
410406

411-
/*
412-
* End a Test -- the fact that we got here means there was no failure.
413-
* Print the Passed message, and some performance numbers.
414-
*/
415-
407+
// end concludes a test, prints performance numbers, and checks for timeouts.
416408
func (cfg *config) end() {
417409
atomic.AddInt32(&cfg.testNum, 1) // suppress two-minute timeout
418410

0 commit comments

Comments
 (0)