Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
cs733
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Sushant Mahajan
cs733
Commits
9574763b
Commit
9574763b
authored
Feb 10, 2015
by
Harshit Pande
Browse files
Options
Browse Files
Download
Plain Diff
fixed conflicts in raft.go with cluster configuration
parents
1eb4542d
aafa7ab8
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
141 additions
and
65 deletions
+141
-65
assignment2/src/raft/kvstore.go
assignment2/src/raft/kvstore.go
+8
-3
assignment2/src/raft/raft.go
assignment2/src/raft/raft.go
+68
-43
assignment2/src/server.go
assignment2/src/server.go
+20
-9
assignment2/src/server_test.go
assignment2/src/server_test.go
+45
-10
No files found.
assignment2/src/raft/kvstore.go
View file @
9574763b
...
@@ -2,6 +2,7 @@ package raft
...
@@ -2,6 +2,7 @@ package raft
import
(
import
(
"bytes"
"bytes"
"encoding/gob"
"log"
"log"
"net"
"net"
"strconv"
"strconv"
...
@@ -193,10 +194,14 @@ func MonitorCommitChannel(ch chan LogEntry) {
...
@@ -193,10 +194,14 @@ func MonitorCommitChannel(ch chan LogEntry) {
temp
:=
<-
ch
temp
:=
<-
ch
conn
:=
temp
.
(
*
LogEntryData
)
.
conn
conn
:=
temp
.
(
*
LogEntryData
)
.
conn
cmd
:=
new
(
utils
.
Command
)
cmd
:=
new
(
utils
.
Command
)
if
err
:=
cmd
.
GobDecode
(
temp
.
Data
());
err
!=
nil
{
log
.
Fatal
(
"Error decoding command!"
)
buffer
:=
bytes
.
NewBuffer
(
temp
.
GetData
())
dec
:=
gob
.
NewDecoder
(
buffer
)
if
err
:=
dec
.
Decode
(
cmd
);
err
!=
nil
{
log
.
Fatal
(
"Error decoding command!"
,
err
)
}
}
ParseInput
(
conn
,
cmd
)
ParseInput
(
conn
,
cmd
)
//Debug()
}
}
}
}
...
@@ -498,7 +503,7 @@ func performDelete(conn net.Conn, tokens []string) int {
...
@@ -498,7 +503,7 @@ func performDelete(conn net.Conn, tokens []string) int {
*arguments: none
*arguments: none
*return: none
*return: none
*/
*/
func
d
ebug
()
{
func
D
ebug
()
{
logger
.
Println
(
"----start debug----"
)
logger
.
Println
(
"----start debug----"
)
for
key
,
val
:=
range
(
*
table
)
.
dictionary
{
for
key
,
val
:=
range
(
*
table
)
.
dictionary
{
logger
.
Println
(
key
,
val
)
logger
.
Println
(
key
,
val
)
...
...
assignment2/src/raft/raft.go
View file @
9574763b
...
@@ -19,6 +19,8 @@ const (
...
@@ -19,6 +19,8 @@ const (
// Logger
// Logger
var
Info
*
log
.
Logger
var
Info
*
log
.
Logger
var
lsn
Lsn
// Flag for enabling/disabling logging functionality
// Flag for enabling/disabling logging functionality
var
DEBUG
=
true
var
DEBUG
=
true
...
@@ -43,30 +45,27 @@ type SharedLog interface {
...
@@ -43,30 +45,27 @@ type SharedLog interface {
}
}
type
Raft
struct
{
type
Raft
struct
{
log_a
rray
[]
*
LogEntryData
LogA
rray
[]
*
LogEntryData
commitCh
chan
LogEntry
commitCh
chan
LogEntry
cluster
_c
onfig
*
ClusterConfig
//cluster
cluster
C
onfig
*
ClusterConfig
//cluster
id
int
//this server id
id
int
//this server id
sync
.
RWMutex
sync
.
RWMutex
}
}
type
LogEntry
interface
{
type
LogEntry
interface
{
Lsn
()
Lsn
GetLsn
()
Lsn
Data
()
[]
byte
GetData
()
[]
byte
Committed
()
bool
GetCommitted
()
bool
SetCommitted
(
status
bool
)
}
}
type
LogEntryData
struct
{
type
LogEntryData
struct
{
i
d
Lsn
I
d
Lsn
d
ata
[]
byte
D
ata
[]
byte
c
ommitted
bool
C
ommitted
bool
conn
net
.
Conn
conn
net
.
Conn
}
}
type
Args
struct
{
X
int
}
type
Reply
struct
{
type
Reply
struct
{
X
int
X
int
}
}
...
@@ -79,18 +78,31 @@ func GetClusterConfig() *ClusterConfig {
...
@@ -79,18 +78,31 @@ func GetClusterConfig() *ClusterConfig {
return
cluster_config
return
cluster_config
}
}
func
NewRaft
(
config
*
ClusterConfig
,
thisServerId
int
,
commitCh
chan
LogEntry
)
(
*
Raft
,
error
)
{
func
NewRaft
(
config
*
ClusterConfig
,
thisServerId
int
,
commitCh
chan
LogEntry
,
logger
*
log
.
Logger
)
(
*
Raft
,
error
)
{
rft
:=
new
(
Raft
)
rft
:=
new
(
Raft
)
rft
.
commitCh
=
commitCh
rft
.
commitCh
=
commitCh
rft
.
cluster_config
=
config
rft
.
clusterConfig
=
config
cluster_config
=
config
rft
.
id
=
thisServerId
rft
.
id
=
thisServerId
Info
=
logger
lsn
=
0
return
rft
,
nil
return
rft
,
nil
}
}
func
NewLogEntry
(
data
[]
byte
,
committed
bool
,
conn
net
.
Conn
)
*
LogEntryData
{
entry
:=
new
(
LogEntryData
)
entry
.
Id
=
lsn
entry
.
Data
=
data
entry
.
conn
=
conn
entry
.
Committed
=
committed
lsn
++
return
entry
}
//goroutine that monitors channel to check if the majority of servers have replied
//goroutine that monitors channel to check if the majority of servers have replied
func
monitorAckChannel
(
rft
*
Raft
,
ack_ch
<-
chan
int
,
log_entry
LogEntry
,
majCh
chan
bool
)
{
func
monitorAckChannel
(
rft
*
Raft
,
ack_ch
<-
chan
int
,
log_entry
LogEntry
,
majCh
chan
bool
)
{
acks_received
:=
0
acks_received
:=
0
num_servers
:=
len
(
rft
.
cluster
_c
onfig
.
Servers
)
num_servers
:=
len
(
rft
.
cluster
C
onfig
.
Servers
)
required_acks
:=
num_servers
/
2
required_acks
:=
num_servers
/
2
up
:=
make
(
chan
bool
,
1
)
up
:=
make
(
chan
bool
,
1
)
err
:=
false
err
:=
false
...
@@ -103,9 +115,12 @@ func monitorAckChannel(rft *Raft, ack_ch <-chan int, log_entry LogEntry, majCh c
...
@@ -103,9 +115,12 @@ func monitorAckChannel(rft *Raft, ack_ch <-chan int, log_entry LogEntry, majCh c
for
{
for
{
select
{
select
{
case
temp
:=
<-
ack_ch
:
case
temp
:=
<-
ack_ch
:
Info
.
Println
(
"Ack Received:"
,
temp
)
acks_received
+=
temp
acks_received
+=
temp
if
acks_received
==
required_acks
{
if
acks_received
==
required_acks
{
rft
.
log_array
[
log_entry
.
(
*
LogEntryData
)
.
id
]
.
committed
=
true
Info
.
Println
(
"Majority Achieved"
,
log_entry
.
(
*
LogEntryData
)
.
Id
)
rft
.
LogArray
[
log_entry
.
(
*
LogEntryData
)
.
Id
]
.
Committed
=
true
//Info.Println(rft.LogArray)
rft
.
commitCh
<-
log_entry
rft
.
commitCh
<-
log_entry
majCh
<-
true
majCh
<-
true
err
=
true
err
=
true
...
@@ -113,6 +128,7 @@ func monitorAckChannel(rft *Raft, ack_ch <-chan int, log_entry LogEntry, majCh c
...
@@ -113,6 +128,7 @@ func monitorAckChannel(rft *Raft, ack_ch <-chan int, log_entry LogEntry, majCh c
}
}
case
<-
up
:
case
<-
up
:
Info
.
Println
(
"Error"
)
err
=
true
err
=
true
break
break
}
}
...
@@ -122,47 +138,56 @@ func monitorAckChannel(rft *Raft, ack_ch <-chan int, log_entry LogEntry, majCh c
...
@@ -122,47 +138,56 @@ func monitorAckChannel(rft *Raft, ack_ch <-chan int, log_entry LogEntry, majCh c
}
}
}
}
//make LogEntryData implement the
//make LogEntryData implement the
LogEntry Interface
func
(
entry
*
LogEntryData
)
Lsn
()
Lsn
{
func
(
entry
*
LogEntryData
)
Get
Lsn
()
Lsn
{
return
entry
.
i
d
return
entry
.
I
d
}
}
func
(
entry
*
LogEntryData
)
Data
()
[]
byte
{
func
(
entry
*
LogEntryData
)
Get
Data
()
[]
byte
{
return
entry
.
d
ata
return
entry
.
D
ata
}
}
func
(
entry
*
LogEntryData
)
Committed
()
bool
{
func
(
entry
*
LogEntryData
)
GetCommitted
()
bool
{
return
entry
.
committed
return
entry
.
Committed
}
func
(
entry
*
LogEntryData
)
SetCommitted
(
committed
bool
)
{
entry
.
Committed
=
committed
}
//make rpc call to followers
func
doRPCCall
(
ackChan
chan
int
,
hostname
string
,
logPort
int
,
temp
*
LogEntryData
)
{
client
,
err
:=
rpc
.
Dial
(
"tcp"
,
hostname
+
":"
+
strconv
.
Itoa
(
logPort
))
if
err
!=
nil
{
Info
.
Fatal
(
"Dialing:"
,
err
)
}
reply
:=
new
(
Reply
)
args
:=
temp
Info
.
Println
(
"RPC Called"
,
logPort
)
appendCall
:=
client
.
Go
(
"AppendEntries.AppendEntriesRPC"
,
args
,
reply
,
nil
)
//let go allocate done channel
appendCall
=
<-
appendCall
.
Done
Info
.
Println
(
"Reply"
,
appendCall
,
reply
.
X
)
ackChan
<-
reply
.
X
}
}
//make raft implement the append function
//make raft implement the append function
func
(
rft
*
Raft
)
Append
(
data
[]
byte
,
conn
net
.
Conn
)
(
LogEntry
,
error
)
{
func
(
rft
*
Raft
)
Append
(
data
[]
byte
,
conn
net
.
Conn
)
(
LogEntry
,
error
)
{
Info
.
Println
(
"Append Called"
)
if
rft
.
id
!=
1
{
if
rft
.
id
!=
1
{
return
nil
,
ErrRedirect
(
1
)
return
nil
,
ErrRedirect
(
1
)
}
}
temp
:=
new
(
LogEntryData
)
defer
rft
.
Unlock
()
temp
.
id
=
1
rft
.
Lock
()
temp
.
committed
=
false
temp
:=
NewLogEntry
(
data
,
false
,
conn
)
temp
.
data
=
data
temp
.
conn
=
conn
rft
.
LogArray
=
append
(
rft
.
LogArray
,
temp
)
rft
.
log_array
=
append
(
rft
.
log_array
,
temp
)
ackChan
:=
make
(
chan
int
)
ackChan
:=
make
(
chan
int
)
majChan
:=
make
(
chan
bool
)
majChan
:=
make
(
chan
bool
)
go
monitorAckChannel
(
rft
,
ackChan
,
temp
,
majChan
)
go
monitorAckChannel
(
rft
,
ackChan
,
temp
,
majChan
)
for
_
,
server
:=
range
cluster_config
.
Servers
[
1
:
]
{
for
_
,
server
:=
range
rft
.
clusterConfig
.
Servers
[
1
:
]
{
go
func
(
ackChan
chan
int
)
{
doRPCCall
(
ackChan
,
server
.
Hostname
,
server
.
LogPort
,
temp
)
client
,
err
:=
rpc
.
Dial
(
"tcp"
,
server
.
Hostname
+
":"
+
strconv
.
Itoa
(
server
.
LogPort
))
if
err
!=
nil
{
Info
.
Fatal
(
"Dialing:"
,
err
)
}
reply
:=
new
(
Reply
)
args
:=
temp
appendCall
:=
client
.
Go
(
"AppendEntries.AppendEntriesRPC"
,
args
,
reply
,
nil
)
//let go allocate done channel
appendCall
=
<-
appendCall
.
Done
ackChan
<-
reply
.
X
}(
ackChan
)
}
}
if
<-
majChan
{
if
<-
majChan
{
...
...
assignment2/src/server.go
View file @
9574763b
...
@@ -16,8 +16,7 @@ import (
...
@@ -16,8 +16,7 @@ import (
// Logger
// Logger
var
Info
*
log
.
Logger
var
Info
*
log
.
Logger
// Flag for enabling/disabling logging functionality
var
rft
*
raft
.
Raft
var
DEBUG
=
true
type
AppendEntries
struct
{}
type
AppendEntries
struct
{}
...
@@ -59,8 +58,17 @@ type Reply struct {
...
@@ -59,8 +58,17 @@ type Reply struct {
X
int
X
int
}
}
func
(
t
*
AppendEntries
)
AppendEntriesRPC
(
args
*
raft
.
LogEntry
,
reply
*
Reply
)
error
{
func
(
t
*
AppendEntries
)
AppendEntriesRPC
(
args
*
raft
.
LogEntryData
,
reply
*
Reply
)
error
{
Info
.
Println
(
"RPC invoked"
)
Info
.
Println
(
"Append Entries RPC invoked"
,
(
*
args
)
.
GetLsn
(),
(
*
args
)
.
GetData
(),
(
*
args
)
.
GetCommitted
())
rft
.
LogArray
=
append
(
rft
.
LogArray
,
raft
.
NewLogEntry
((
*
args
)
.
GetData
(),
(
*
args
)
.
GetCommitted
(),
nil
))
reply
.
X
=
1
return
nil
}
func
(
t
*
AppendEntries
)
CommitRPC
(
args
*
raft
.
LogEntry
,
reply
*
Reply
)
error
{
Info
.
Println
(
"Commit RPC invoked"
)
rft
.
LogArray
[(
*
args
)
.
GetLsn
()]
.
SetCommitted
(
true
)
reply
.
X
=
1
reply
.
X
=
1
return
nil
return
nil
}
}
...
@@ -84,12 +92,11 @@ func initInterServerCommunication(server *raft.ServerConfig, rft *raft.Raft, ch
...
@@ -84,12 +92,11 @@ func initInterServerCommunication(server *raft.ServerConfig, rft *raft.Raft, ch
}
}
// Initialize Logger
// Initialize Logger
func
initLogger
(
serverId
int
)
{
func
initLogger
(
serverId
int
,
toDebug
bool
)
{
// Logger Initializaion
// Logger Initializaion
if
!
DEBUG
{
if
!
toDebug
{
Info
=
log
.
New
(
ioutil
.
Discard
,
"INFO: "
,
log
.
Ldate
|
log
.
Ltime
|
log
.
Lshortfile
)
Info
=
log
.
New
(
ioutil
.
Discard
,
"INFO: "
,
log
.
Ldate
|
log
.
Ltime
|
log
.
Lshortfile
)
}
else
{
}
else
{
Info
=
log
.
New
(
os
.
Stdout
,
"INFO: "
,
log
.
Ldate
|
log
.
Ltime
|
log
.
Lshortfile
)
Info
=
log
.
New
(
os
.
Stdout
,
"INFO: "
,
log
.
Ldate
|
log
.
Ltime
|
log
.
Lshortfile
)
}
}
...
@@ -120,7 +127,11 @@ func main() {
...
@@ -120,7 +127,11 @@ func main() {
Info
.
Println
(
"argument "
,
os
.
Args
[
1
],
"is not string"
)
Info
.
Println
(
"argument "
,
os
.
Args
[
1
],
"is not string"
)
}
}
initLogger
(
sid
)
if
len
(
os
.
Args
)
>
3
{
initLogger
(
sid
,
true
)
}
else
{
initLogger
(
sid
,
false
)
}
Info
.
Println
(
"Starting"
)
Info
.
Println
(
"Starting"
)
serverCount
,
err2
:=
strconv
.
Atoi
((
os
.
Args
[
2
]))
serverCount
,
err2
:=
strconv
.
Atoi
((
os
.
Args
[
2
]))
...
@@ -132,7 +143,7 @@ func main() {
...
@@ -132,7 +143,7 @@ func main() {
clusterConfig
,
_
:=
raft
.
NewClusterConfig
(
serverCount
)
clusterConfig
,
_
:=
raft
.
NewClusterConfig
(
serverCount
)
commitCh
:=
make
(
chan
raft
.
LogEntry
)
commitCh
:=
make
(
chan
raft
.
LogEntry
)
rft
,
_
:=
raft
.
NewRaft
(
clusterConfig
,
sid
,
commitCh
)
rft
,
_
=
raft
.
NewRaft
(
clusterConfig
,
sid
,
commitCh
,
Info
)
raft
.
InitKVStore
(
Info
)
raft
.
InitKVStore
(
Info
)
go
raft
.
MonitorCommitChannel
(
commitCh
)
//for kvstore
go
raft
.
MonitorCommitChannel
(
commitCh
)
//for kvstore
...
...
assignment2/src/server_test.go
View file @
9574763b
...
@@ -4,7 +4,7 @@ package main
...
@@ -4,7 +4,7 @@ package main
import
(
import
(
"bytes"
"bytes"
"fmt"
//
"fmt"
"net"
"net"
"net/rpc"
"net/rpc"
"os"
"os"
...
@@ -39,6 +39,8 @@ func TestAll(t *testing.T) {
...
@@ -39,6 +39,8 @@ func TestAll(t *testing.T) {
//test no reply
//test no reply
testNoReply
(
t
)
testNoReply
(
t
)
testSet
(
t
)
}
}
//run servers
//run servers
...
@@ -63,7 +65,7 @@ func testConnectFollower(t *testing.T) {
...
@@ -63,7 +65,7 @@ func testConnectFollower(t *testing.T) {
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Error
(
"Error in connecting the server at port: "
+
strconv
.
Itoa
(
server_port
))
t
.
Error
(
"Error in connecting the server at port: "
+
strconv
.
Itoa
(
server_port
))
}
else
{
}
else
{
time
.
Sleep
(
time
.
Millisecond
)
//
time.Sleep(time.Millisecond)
sending
:=
[]
byte
(
"set mykey1 100 3
\r\n
lul
\r\n
"
)
sending
:=
[]
byte
(
"set mykey1 100 3
\r\n
lul
\r\n
"
)
port
:=
strconv
.
Itoa
(
raft
.
CLIENT_PORT
+
1
)
port
:=
strconv
.
Itoa
(
raft
.
CLIENT_PORT
+
1
)
expecting
:=
[]
byte
(
"ERR_REDIRECT 127.0.0.1 "
+
port
+
"
\r\n
"
)
expecting
:=
[]
byte
(
"ERR_REDIRECT 127.0.0.1 "
+
port
+
"
\r\n
"
)
...
@@ -80,7 +82,7 @@ func testConnectFollower(t *testing.T) {
...
@@ -80,7 +82,7 @@ func testConnectFollower(t *testing.T) {
)
)
}
}
conn
.
Close
()
conn
.
Close
()
time
.
Sleep
(
time
.
Millisecond
)
//
time.Sleep(time.Millisecond)
}
}
}
}
}
}
...
@@ -99,13 +101,13 @@ func testNoReply(t *testing.T) {
...
@@ -99,13 +101,13 @@ func testNoReply(t *testing.T) {
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Error
(
"Error in connecting the server at port: "
+
strconv
.
Itoa
(
server_port
))
t
.
Error
(
"Error in connecting the server at port: "
+
strconv
.
Itoa
(
server_port
))
}
else
{
}
else
{
time
.
Sleep
(
time
.
Millisecond
)
//
time.Sleep(time.Millisecond)
for
_
,
pair
:=
range
noreply_cases
{
for
_
,
pair
:=
range
noreply_cases
{
conn
.
Write
(
pair
.
to_server
)
conn
.
Write
(
pair
.
to_server
)
buffer
:=
make
([]
byte
,
1024
)
buffer
:=
make
([]
byte
,
1024
)
conn
.
Read
(
buffer
)
conn
.
Read
(
buffer
)
n
:=
bytes
.
Index
(
buffer
,
[]
byte
{
0
})
n
:=
bytes
.
Index
(
buffer
,
[]
byte
{
0
})
fmt
.
Println
(
buffer
)
//
fmt.Println(buffer)
if
!
bytes
.
Equal
(
buffer
[
:
n
],
pair
.
from_server
)
{
if
!
bytes
.
Equal
(
buffer
[
:
n
],
pair
.
from_server
)
{
t
.
Error
(
t
.
Error
(
"For"
,
pair
.
to_server
,
string
(
pair
.
to_server
),
"For"
,
pair
.
to_server
,
string
(
pair
.
to_server
),
...
@@ -115,7 +117,40 @@ func testNoReply(t *testing.T) {
...
@@ -115,7 +117,40 @@ func testNoReply(t *testing.T) {
}
}
}
}
conn
.
Close
()
conn
.
Close
()
time
.
Sleep
(
time
.
Millisecond
)
//time.Sleep(time.Millisecond)
}
}
//noreply option is not more valid with set and cas
//client should get command error from the server if it sends 'no reply' option
func
testSet
(
t
*
testing
.
T
)
{
var
noreply_cases
=
[]
Testpair
{
{[]
byte
(
"set mykey1 100 3
\r\n
add
\r\n
"
),
[]
byte
(
"OK 1
\r\n
"
)},
}
server_port
:=
raft
.
CLIENT_PORT
+
1
conn
,
err
:=
net
.
Dial
(
"tcp"
,
":"
+
strconv
.
Itoa
(
server_port
))
if
err
!=
nil
{
t
.
Error
(
"Error in connecting the server at port: "
+
strconv
.
Itoa
(
server_port
))
}
else
{
//time.Sleep(time.Millisecond)
for
_
,
pair
:=
range
noreply_cases
{
conn
.
Write
(
pair
.
to_server
)
buffer
:=
make
([]
byte
,
1024
)
conn
.
Read
(
buffer
)
n
:=
bytes
.
Index
(
buffer
,
[]
byte
{
0
})
//fmt.Println(buffer)
if
!
bytes
.
Equal
(
buffer
[
:
n
],
pair
.
from_server
)
{
t
.
Error
(
"For"
,
pair
.
to_server
,
string
(
pair
.
to_server
),
"expected"
,
pair
.
from_server
,
string
(
pair
.
from_server
),
"got"
,
buffer
[
:
n
],
string
(
buffer
[
:
n
]),
)
}
}
conn
.
Close
()
//time.Sleep(time.Millisecond)
}
}
}
}
...
@@ -190,24 +225,24 @@ func monitorPresentChannel(presentChan chan bool, t *testing.T) {
...
@@ -190,24 +225,24 @@ func monitorPresentChannel(presentChan chan bool, t *testing.T) {
// Add some dummy entries in raft.ClusterConfig such that majority is not achieved
// Add some dummy entries in raft.ClusterConfig such that majority is not achieved
// Expected: Time out should occur after 5 sec and log entry table should not be updated
// Expected: Time out should occur after 5 sec and log entry table should not be updated
func
CommandNotCommittedWithoutMajority
()
{
func
test
CommandNotCommittedWithoutMajority
()
{
}
}
// Expected: Log entry table updated with the new entry
// Expected: Log entry table updated with the new entry
func
CommandCommittedWithMajority
()
{
func
test
CommandCommittedWithMajority
()
{
}
}
// Multiple clients sending different requests
// Multiple clients sending different requests
// Expected: Log entry table updated
// Expected: Log entry table updated
func
ConcurrentManyClientsToLeader
()
{
func
test
ConcurrentManyClientsToLeader
()
{
}
}
// Single client sending 100 requests one after another
// Single client sending 100 requests one after another
// Expected: Log entry table updated
// Expected: Log entry table updated
func
ConcurrentClientManyRequestsToLeader
()
{
func
test
ConcurrentClientManyRequestsToLeader
()
{
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment