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
5e03357b
Commit
5e03357b
authored
Feb 09, 2015
by
Bharath Radhakrishnan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fixed compilation issues and general housekeeping
parent
40cf442d
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
153 additions
and
201 deletions
+153
-201
assignment2/src/connhandler/connhandler.go
assignment2/src/connhandler/connhandler.go
+50
-6
assignment2/src/kvstore/kvstore.go
assignment2/src/kvstore/kvstore.go
+86
-85
assignment2/src/raft/raft.go
assignment2/src/raft/raft.go
+0
-83
assignment2/src/runner.go
assignment2/src/runner.go
+1
-8
assignment2/src/server.go
assignment2/src/server.go
+9
-12
assignment2/src/utils/utils.go
assignment2/src/utils/utils.go
+7
-7
No files found.
assignment2/src/connhandler.go
→
assignment2/src/connhandler
/connhandler
.go
View file @
5e03357b
package
handler
package
connhandler
import
(
"bufio"
"bytes"
"encoding/gob"
"kvstore"
"net"
"raft"
"strconv"
"strings"
"time"
"utils"
)
/*
*Helper function to read value or cause timeout after READ_TIMEOUT seconds
...
...
@@ -13,7 +26,7 @@ func readValue(ch chan []byte, n uint64) ([]byte, bool) {
up
:=
make
(
chan
bool
,
1
)
//after 5 seconds passed reading value, we'll just send err to client
go
func
()
{
time
.
Sleep
(
READ_TIMEOUT
*
time
.
Second
)
time
.
Sleep
(
kvstore
.
READ_TIMEOUT
*
time
.
Second
)
up
<-
true
}()
...
...
@@ -100,21 +113,52 @@ func MyRead(ch chan []byte, conn net.Conn) {
*/
func
Write
(
conn
net
.
Conn
,
msg
string
)
{
buf
:=
[]
byte
(
msg
)
buf
=
append
(
buf
,
[]
byte
(
CRLF
)
...
)
buf
=
append
(
buf
,
[]
byte
(
kvstore
.
CRLF
)
...
)
conn
.
Write
(
buf
)
}
func
handleClient
(
conn
net
.
Conn
)
{
func
HandleClient
(
conn
net
.
Conn
,
rft
*
raft
.
Raft
)
{
defer
conn
.
Close
()
//channel for every connection for every client
ch
:=
make
(
chan
[]
byte
)
go
m
yRead
(
ch
,
conn
)
go
M
yRead
(
ch
,
conn
)
for
{
command
:=
new
(
utils
.
Command
)
msg
:=
<-
ch
if
len
(
msg
)
==
0
{
continue
}
//kvstore.ParseInput(conn, string(msg), table, ch)
command
.
Cmd
=
msg
flag
:=
false
nr
:=
uint64
(
0
)
tokens
:=
strings
.
Fields
(
string
(
msg
))
if
kvstore
.
IsCas
(
tokens
[
0
])
{
n
,
_
:=
strconv
.
ParseUint
(
tokens
[
3
],
10
,
64
)
nr
=
n
flag
=
true
}
else
if
kvstore
.
IsSet
(
tokens
[
0
])
{
n
,
_
:=
strconv
.
ParseUint
(
tokens
[
2
],
10
,
64
)
nr
=
n
flag
=
true
}
if
flag
{
if
v
,
err
:=
readValue
(
ch
,
nr
);
err
{
Write
(
conn
,
kvstore
.
ERR_CMD_ERR
)
}
else
{
command
.
Val
=
v
//command.isVal = true
}
}
buffer
:=
new
(
bytes
.
Buffer
)
// writing
enc
:=
gob
.
NewEncoder
(
buffer
)
err
:=
enc
.
Encode
(
command
)
if
err
!=
nil
{
//log.Fatal("encode error:", err)
}
rft
.
Append
(
buffer
.
Bytes
())
}
}
assignment2/src/kvstore.go
→
assignment2/src/kvstore
/kvstore
.go
View file @
5e03357b
package
kvstore
import
(
"bufio"
"bytes"
"fmt"
"io/ioutil"
"log"
"net"
...
...
@@ -107,16 +105,16 @@ var table *KeyValueStore
// }
//}
/
//
*Simple write function to send information to the client
//
*arguments: client connection, msg to send to the client
//
*return: none
//
*/
//
func write(conn net.Conn, msg string) {
//
buf := []byte(msg)
//
buf = append(buf, []byte(CRLF)...)
//
logger.Println(buf, len(buf))
//
conn.Write(buf)
//
}
/*Simple write function to send information to the client
*arguments: client connection, msg to send to the client
*return: none
*/
func
write
(
conn
net
.
Conn
,
msg
string
)
{
buf
:=
[]
byte
(
msg
)
buf
=
append
(
buf
,
[]
byte
(
CRLF
)
...
)
//
logger.Println(buf, len(buf))
conn
.
Write
(
buf
)
}
/*After initial establishment of the connection with the client, this go routine handles further interaction
*arguments: client connection
...
...
@@ -268,7 +266,7 @@ func ParseInput(conn net.Conn, msg string, ch chan []byte) {
if
isValid
(
SET
,
tokens
,
conn
)
!=
0
{
return
}
if
ver
,
ok
,
r
:=
performSet
(
conn
,
tokens
[
1
:
len
(
tokens
)],
table
,
ch
);
ok
{
if
ver
,
ok
,
r
:=
performSet
(
conn
,
tokens
[
1
:
len
(
tokens
)],
ch
);
ok
{
//debug(table)
logger
.
Println
(
ver
)
if
r
{
...
...
@@ -284,7 +282,7 @@ func ParseInput(conn net.Conn, msg string, ch chan []byte) {
if
isValid
(
GET
,
tokens
,
conn
)
!=
0
{
return
}
if
data
,
ok
:=
performGet
(
conn
,
tokens
[
1
:
len
(
tokens
)]
,
table
);
ok
{
if
data
,
ok
:=
performGet
(
conn
,
tokens
[
1
:
len
(
tokens
)]);
ok
{
logger
.
Println
(
"sending"
,
tokens
[
1
],
"data"
)
buffer
.
Reset
()
buffer
.
WriteString
(
VALUE
)
...
...
@@ -305,7 +303,7 @@ func ParseInput(conn net.Conn, msg string, ch chan []byte) {
if
isValid
(
GETM
,
tokens
,
conn
)
!=
0
{
return
}
if
data
,
ok
:=
performGetm
(
conn
,
tokens
[
1
:
len
(
tokens
)]
,
table
);
ok
{
if
data
,
ok
:=
performGetm
(
conn
,
tokens
[
1
:
len
(
tokens
)]);
ok
{
logger
.
Println
(
"sending"
,
tokens
[
1
],
"metadata"
)
buffer
.
Reset
()
buffer
.
WriteString
(
VALUE
)
...
...
@@ -334,7 +332,7 @@ func ParseInput(conn net.Conn, msg string, ch chan []byte) {
if
isValid
(
CAS
,
tokens
,
conn
)
!=
0
{
return
}
if
ver
,
ok
,
r
:=
performCas
(
conn
,
tokens
[
1
:
len
(
tokens
)],
table
,
ch
);
r
{
if
ver
,
ok
,
r
:=
performCas
(
conn
,
tokens
[
1
:
len
(
tokens
)],
ch
);
r
{
if
r
{
switch
ok
{
case
0
:
...
...
@@ -365,7 +363,7 @@ func ParseInput(conn net.Conn, msg string, ch chan []byte) {
if
isValid
(
DELETE
,
tokens
,
conn
)
!=
0
{
return
}
if
ok
:=
performDelete
(
conn
,
tokens
[
1
:
len
(
tokens
)]
,
table
);
ok
==
0
{
if
ok
:=
performDelete
(
conn
,
tokens
[
1
:
len
(
tokens
)]);
ok
==
0
{
write
(
conn
,
DELETED
)
}
else
{
write
(
conn
,
ERR_NOT_FOUND
)
...
...
@@ -384,11 +382,11 @@ func ParseInput(conn net.Conn, msg string, ch chan []byte) {
*return: version of inserted key (if successful, 0 otherwise), success or failure, whether to send reply to client
*/
func
performSet
(
conn
net
.
Conn
,
tokens
[]
string
,
ch
chan
[]
byte
)
(
uint64
,
bool
,
bool
)
{
k
:=
tokens
[
0
]
//-
k := tokens[0]
//expiry time offset
e
,
_
:=
strconv
.
ParseUint
(
tokens
[
1
],
10
,
64
)
//-
e, _ := strconv.ParseUint(tokens[1], 10, 64)
//numbytes
n
,
_
:=
strconv
.
ParseUint
(
tokens
[
2
],
10
,
64
)
//-
n, _ := strconv.ParseUint(tokens[2], 10, 64)
r
:=
true
if
len
(
tokens
)
==
4
&&
tokens
[
3
]
==
NOREPLY
{
...
...
@@ -397,32 +395,33 @@ func performSet(conn net.Conn, tokens []string, ch chan []byte) (uint64, bool, b
logger
.
Println
(
r
)
if
v
,
err
:=
readValue
(
ch
,
n
);
err
{
write
(
conn
,
ERR_CMD_ERR
)
return
0
,
false
,
r
}
else
{
defer
table
.
Unlock
()
table
.
Lock
()
//critical section start
var
val
*
Data
if
_
,
ok
:=
table
.
dictionary
[
k
];
ok
{
val
=
table
.
dictionary
[
k
]
}
else
{
val
=
new
(
Data
)
table
.
dictionary
[
k
]
=
val
}
val
.
numBytes
=
n
val
.
version
++
if
e
==
0
{
val
.
isPerpetual
=
true
val
.
expTime
=
0
}
else
{
val
.
isPerpetual
=
false
val
.
expTime
=
e
+
uint64
(
time
.
Now
()
.
Unix
())
}
val
.
value
=
v
return
val
.
version
,
true
,
r
}
//if v, err := readValue(ch, n); err {
// write(conn, ERR_CMD_ERR)
// return 0, false, r
//} else {
// defer table.Unlock()
// table.Lock()
// //critical section start
// var val *Data
// if _, ok := table.dictionary[k]; ok {
// val = table.dictionary[k]
// } else {
// val = new(Data)
// table.dictionary[k] = val
// }
// val.numBytes = n
// val.version++
// if e == 0 {
// val.isPerpetual = true
// val.expTime = 0
// } else {
// val.isPerpetual = false
// val.expTime = e + uint64(time.Now().Unix())
// }
// val.value = v
// return val.version, true, r
//}
return
2
,
true
,
true
}
/*Delegate function reponsible for activities related to the GET command sent by the client.
...
...
@@ -496,40 +495,41 @@ func performCas(conn net.Conn, tokens []string, ch chan []byte) (uint64, int, bo
}
//read value
if
v
,
err
:=
readValue
(
ch
,
n
);
err
{
return
0
,
1
,
r
}
else
{
defer
table
.
Unlock
()
table
.
Lock
()
if
val
,
ok
:=
table
.
dictionary
[
k
];
ok
{
if
val
.
version
==
ve
{
if
val
.
isPerpetual
||
val
.
expTime
>=
uint64
(
time
.
Now
()
.
Unix
())
{
//if expiry time is zero, key should not be deleted
if
e
==
0
{
val
.
isPerpetual
=
true
val
.
expTime
=
0
}
else
{
val
.
isPerpetual
=
false
val
.
expTime
=
e
+
uint64
(
time
.
Now
()
.
Unix
())
}
val
.
numBytes
=
n
val
.
version
++
val
.
value
=
v
//key found and changed
return
val
.
version
,
0
,
r
}
else
{
logger
.
Println
(
"expired key found!"
)
//version found but key expired, can delete key safely and tell client that it does not exist
delete
(
table
.
dictionary
,
k
)
return
0
,
3
,
r
}
}
//version mismatch
return
0
,
2
,
r
}
//key not found
return
0
,
3
,
r
}
//if v, err := readValue(ch, n); err {
// return 0, 1, r
//} else {
// defer table.Unlock()
// table.Lock()
// if val, ok := table.dictionary[k]; ok {
// if val.version == ve {
// if val.isPerpetual || val.expTime >= uint64(time.Now().Unix()) {
// //if expiry time is zero, key should not be deleted
// if e == 0 {
// val.isPerpetual = true
// val.expTime = 0
// } else {
// val.isPerpetual = false
// val.expTime = e + uint64(time.Now().Unix())
// }
// val.numBytes = n
// val.version++
// val.value = v
// //key found and changed
// return val.version, 0, r
// } else {
// logger.Println("expired key found!")
// //version found but key expired, can delete key safely and tell client that it does not exist
// delete(table.dictionary, k)
// return 0, 3, r
// }
// }
// //version mismatch
// return 0, 2, r
// }
// //key not found
// return 0, 3, r
//}
return
1
,
1
,
true
}
/*Delegate function reponsible for activities related to the DELETE command sent by the client.
...
...
@@ -613,11 +613,12 @@ func InitKVStore() {
table
=
&
KeyValueStore
{
dictionary
:
make
(
map
[
string
]
*
Data
)}
}
func
IsCasOrSet
(
msg
string
)
bool
{
tokens
:=
strings
.
Fields
(
msg
)
if
len
(
tokens
)
>=
1
{
return
tokens
[
0
]
==
SET
||
tokens
[
0
]
==
CAS
}
func
IsCas
(
msg
string
)
bool
{
return
msg
==
CAS
}
func
IsSet
(
msg
string
)
bool
{
return
msg
==
SET
}
//server will not call this, we'll call it from test cases to clear the map
...
...
assignment2/src/raft.go
→
assignment2/src/raft
/raft
.go
View file @
5e03357b
package
raft
import
(
"fmt"
"io/ioutil"
"log"
"net"
"net/rpc"
"os"
"reflect"
"strconv"
"time"
)
...
...
@@ -201,81 +196,3 @@ func NewClusterConfig(num_servers int) (*ClusterConfig, error) {
func
(
e
ErrRedirect
)
Error
()
string
{
return
"Redirect to server "
+
strconv
.
Itoa
(
0
)
}
//func start_rpc(this_server *ServerConfig) {
// //rpc.Register()
//}
func
(
t
*
AppendEntries
)
AppendEntriesRPC
(
args
*
Args
,
reply
*
Reply
)
error
{
reply
.
X
=
args
.
X
return
nil
}
func
initInterServerCommunication
(
this_server
*
ServerConfig
)
{
appendRpc
:=
new
(
AppendEntries
)
rpc
.
Register
(
appendRpc
)
listener
,
e
:=
net
.
Listen
(
"tcp"
,
":"
+
strconv
.
Itoa
(
this_server
.
LogPort
))
if
e
!=
nil
{
Info
.
Fatal
(
"listen error:"
,
e
)
}
for
{
if
conn
,
err
:=
listener
.
Accept
();
err
!=
nil
{
Info
.
Fatal
(
"accept error: "
+
err
.
Error
())
}
else
{
Info
.
Printf
(
"new connection established
\n
"
)
go
rpc
.
ServeConn
(
conn
)
}
}
}
// Initialize Logger
func
initLogger
(
serverId
int
)
{
// Logger Initializaion
if
!
DEBUG
{
Info
=
log
.
New
(
ioutil
.
Discard
,
"INFO: "
,
log
.
Ldate
|
log
.
Ltime
|
log
.
Lshortfile
)
}
else
{
Info
=
log
.
New
(
os
.
Stdout
,
"INFO: "
,
log
.
Ldate
|
log
.
Ltime
|
log
.
Lshortfile
)
}
Info
.
Println
(
"Initialized server"
)
}
func
initClientCommunication
(
server
)
{
listener
,
e
:=
net
.
Listen
(
"tcp"
,
":"
+
strconv
.
Itoa
(
server
.
ClientPort
))
if
e
!=
nil
{
Info
.
Fatal
(
"client listen error:"
,
e
)
}
for
{
if
conn
,
err
:=
listener
.
Accept
();
err
!=
nil
{
Info
.
Fatal
(
"client accept error: "
+
err
.
Error
())
}
else
{
Info
.
Printf
(
"client new connection established
\n
"
)
go
handleClient
(
conn
)
}
}
}
func
main
()
{
sid
,
err
:=
strconv
.
Atoi
(
os
.
Args
[
1
])
if
err
!=
nil
{
Info
.
Println
(
"argument "
,
os
.
Args
[
1
],
"is not string"
)
}
initLogger
(
sid
)
Info
.
Println
(
"Start"
)
server
,
_
:=
NewServerConfig
(
sid
)
serverCount
,
err2
:=
strconv
.
Atoi
((
os
.
Args
[
2
]))
if
err2
!=
nil
{
Info
.
Println
(
"argument "
,
os
.
Args
[
2
],
"is not string"
)
}
cluster_config
,
_
:=
NewClusterConfig
(
serverCount
)
initClientCommunication
(
server
)
initInterServerCommunication
(
server
)
var
dummy
string
fmt
.
Scanln
(
&
dummy
)
}
assignment2/src/runner.go
View file @
5e03357b
...
...
@@ -3,10 +3,8 @@ package main
import
(
"fmt"
"os"
//"log"
"os/exec"
"strconv"
//"syscall"
)
//constant values used
...
...
@@ -15,7 +13,7 @@ const (
)
func
TestServersCommunic
(
i
int
)
{
cmd
:=
exec
.
Command
(
"go"
,
"run"
,
"
replic_kvstore
.go"
,
strconv
.
Itoa
(
i
+
1
),
strconv
.
Itoa
(
NUM_SERVERS
))
cmd
:=
exec
.
Command
(
"go"
,
"run"
,
"
server
.go"
,
strconv
.
Itoa
(
i
+
1
),
strconv
.
Itoa
(
NUM_SERVERS
))
f
,
err
:=
os
.
OpenFile
(
strconv
.
Itoa
(
i
),
os
.
O_RDWR
|
os
.
O_CREATE
|
os
.
O_TRUNC
,
0666
)
if
err
!=
nil
{
fmt
.
Println
(
"error opening file: %v"
,
err
)
...
...
@@ -25,11 +23,6 @@ func TestServersCommunic(i int) {
cmd
.
Stdout
=
f
cmd
.
Stderr
=
f
cmd
.
Run
()
/*if err != nil {
fmt.Println(err)
}
fmt.Println(string(out))*/
}
func
main
()
{
...
...
assignment2/src/server.go
View file @
5e03357b
...
...
@@ -2,18 +2,15 @@
package
main
import
(
"cs733/assignment2/handler"
"cs733/assignment2/kvstore"
"cs733/assignment2/raft"
"connhandler"
"fmt"
"io/ioutil"
"log"
"net"
"net/rpc"
"os"
"r
eflec
t"
"r
af
t"
"strconv"
"time"
)
// Logger
...
...
@@ -22,6 +19,8 @@ var Info *log.Logger
// Flag for enabling/disabling logging functionality
var
DEBUG
=
true
type
AppendEntries
struct
{}
type
Args
struct
{
X
int
}
...
...
@@ -30,17 +29,15 @@ type Reply struct {
X
int
}
type
AppendEntries
struct
{}
func
(
t
*
AppendEntries
)
AppendEntriesRPC
(
args
*
Args
,
reply
*
Reply
)
error
{
reply
.
X
=
args
.
X
return
nil
}
func
initInterServerCommunication
(
server
*
raft
.
ServerConfig
,
rft
*
raft
.
SharedLog
)
{
func
initInterServerCommunication
(
server
*
raft
.
ServerConfig
,
rft
*
raft
.
Raft
)
{
appendRpc
:=
new
(
AppendEntries
)
rpc
.
Register
(
appendRpc
)
listener
,
e
:=
net
.
Listen
(
"tcp"
,
":"
+
strconv
.
Itoa
(
this_
server
.
LogPort
))
listener
,
e
:=
net
.
Listen
(
"tcp"
,
":"
+
strconv
.
Itoa
(
server
.
LogPort
))
if
e
!=
nil
{
Info
.
Fatal
(
"listen error:"
,
e
)
}
...
...
@@ -67,7 +64,7 @@ func initLogger(serverId int) {
Info
.
Println
(
"Initialized server"
)
}
func
initClientCommunication
(
server
*
raft
.
ServerConfig
,
rft
*
raft
.
SharedLog
)
{
func
initClientCommunication
(
server
*
raft
.
ServerConfig
,
rft
*
raft
.
Raft
)
{
listener
,
e
:=
net
.
Listen
(
"tcp"
,
":"
+
strconv
.
Itoa
(
server
.
ClientPort
))
if
e
!=
nil
{
Info
.
Fatal
(
"client listen error:"
,
e
)
...
...
@@ -77,7 +74,7 @@ func initClientCommunication(server *raft.ServerConfig, rft *raft.SharedLog) {
Info
.
Fatal
(
"client accept error: "
+
err
.
Error
())
}
else
{
Info
.
Printf
(
"client new connection established
\n
"
)
go
handler
.
HandleClient
(
conn
,
rft
)
go
conn
handler
.
HandleClient
(
conn
,
rft
)
}
}
}
...
...
@@ -100,7 +97,7 @@ func main() {
clusterConfig
,
_
:=
raft
.
NewClusterConfig
(
serverCount
)
commitCh
:=
make
(
chan
raft
.
LogEntry
)
rft
:=
raft
.
NewRaft
(
clusterConfig
,
sid
,
commitCh
)
rft
,
_
:=
raft
.
NewRaft
(
clusterConfig
,
sid
,
commitCh
)
initClientCommunication
(
server
,
rft
)
initInterServerCommunication
(
server
,
rft
)
...
...
assignment2/src/utils.go
→
assignment2/src/utils
/utils
.go
View file @
5e03357b
...
...
@@ -2,23 +2,23 @@
package
utils
import
(
"bytes"
"encoding/gob"
"fmt"
)
type
Command
struct
{
c
md
[]
byte
v
al
[]
byte
C
md
[]
byte
V
al
[]
byte
}
func
(
d
*
Command
)
GobEncode
()
([]
byte
,
error
)
{
w
:=
new
(
bytes
.
Buffer
)
encoder
:=
gob
.
NewEncoder
(
w
)
err
:=
encoder
.
Encode
(
d
.
c
md
)
err
:=
encoder
.
Encode
(
d
.
C
md
)
if
err
!=
nil
{
return
nil
,
err
}
err
=
encoder
.
Encode
(
d
.
v
al
)
err
=
encoder
.
Encode
(
d
.
V
al
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -28,9 +28,9 @@ func (d *Command) GobEncode() ([]byte, error) {
func
(
d
*
Command
)
GobDecode
(
buf
[]
byte
)
error
{
r
:=
bytes
.
NewBuffer
(
buf
)
decoder
:=
gob
.
NewDecoder
(
r
)
err
:=
decoder
.
Decode
(
&
d
.
c
md
)
err
:=
decoder
.
Decode
(
&
d
.
C
md
)
if
err
!=
nil
{
return
err
}
return
decoder
.
Decode
(
&
d
.
v
al
)
return
decoder
.
Decode
(
&
d
.
V
al
)
}
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