Commit 57bd661b authored by Sushant Mahajan's avatar Sushant Mahajan

added crlf support and logging to server

parent 8925a076
...@@ -30,7 +30,10 @@ func main() { ...@@ -30,7 +30,10 @@ func main() {
fmt.Println("Err: ", err) fmt.Println("Err: ", err)
} }
fmt.Println(msg) fmt.Println(msg)
conn.Write([]byte(msg)) buf := []byte(msg)[0:len(msg)-1]
buf = append(buf, []byte("\r\n")...)
fmt.Println(len(buf))
conn.Write(buf)
} }
conn.Close() conn.Close()
......
...@@ -9,6 +9,9 @@ import ( ...@@ -9,6 +9,9 @@ import (
"sync" "sync"
"strconv" "strconv"
"time" "time"
"log"
"os"
"io/ioutil"
) )
const ( const (
...@@ -18,15 +21,19 @@ const ( ...@@ -18,15 +21,19 @@ const (
GETM = "getm" GETM = "getm"
CAS = "cas" CAS = "cas"
DELETE = "delete" DELETE = "delete"
NOREPLY = "[noreply]" NOREPLY = "noreply"
// //
// //response // //response
// OK = "OK" OK = "OK"
CRLF = "\r\n"
// VALUE = "VALUE" // VALUE = "VALUE"
// DELETED = "DELETED" // DELETED = "DELETED"
//errors //errors
ERR_CMD_ERR = "ERR_CMD_ERR" ERR_CMD_ERR = "ERR_CMD_ERR"
//logging
LOG = true
) )
type Data struct { type Data struct {
...@@ -42,12 +49,13 @@ type KeyValueStore struct { ...@@ -42,12 +49,13 @@ type KeyValueStore struct {
} }
var ver uint64 var ver uint64
var logger *log.Logger
func startServer() { func startServer() {
fmt.Println("Server started") logger.Println("Server started")
listener, err := net.Listen("tcp", ":5000") listener, err := net.Listen("tcp", ":5000")
if err != nil { if err != nil {
fmt.Println("Could not start server!") logger.Println("Could not start server!")
} }
//initialize key value store //initialize key value store
...@@ -57,44 +65,52 @@ func startServer() { ...@@ -57,44 +65,52 @@ func startServer() {
for { for {
conn, err := listener.Accept() conn, err := listener.Accept()
if err != nil { if err != nil {
fmt.Println(err) logger.Println(err)
continue continue
} }
go handleClient(&conn, table) go handleClient(conn, table)
} }
} }
func read(conn *net.Conn, toRead uint64) ([]byte, bool){ func read(conn net.Conn, toRead uint64) ([]byte, bool){
buf := make([]byte, toRead) buf := make([]byte, toRead)
_, err := (*conn).Read(buf) _, err := conn.Read(buf)
if err != nil { if err != nil {
if err == io.EOF { if err == io.EOF {
fmt.Println("Client disconnected!") logger.Println("Client disconnected!")
return []byte{0}, false return []byte{0}, false
} }
} }
n := bytes.Index(buf, []byte{0}) n := bytes.Index(buf, []byte{0})
if n != 0 { if n != 0 {
fmt.Println("Received: ", string(buf[:n-1])) logger.Println("Received: ", buf[:n], string(buf[:n]))
return buf[:n-1], true return buf[:n-2], true
} }
return []byte{0}, false return []byte{0}, false
} }
func handleClient(conn *net.Conn, table *KeyValueStore) { func write(conn net.Conn, msg string) {
defer (*conn).Close() buf := []byte(msg)[0:len(msg)-1]
buf = append(buf, []byte(CRLF))
conn.Write(buf)
}
func handleClient(conn net.Conn, table *KeyValueStore) {
defer conn.Close()
for { for {
if msg, ok := read(conn, 1024); ok{ if msg, ok := read(conn, 1024); ok{
parseInput(conn, string(msg), table) parseInput(conn, string(msg), table)
} else {
break
} }
} }
} }
func isValid(cmd string, tokens []string, conn *net.Conn) int{ func isValid(cmd string, tokens []string, conn net.Conn) int{
var flag int var flag int
switch cmd { switch cmd {
case SET: case SET:
...@@ -127,30 +143,33 @@ func isValid(cmd string, tokens []string, conn *net.Conn) int{ ...@@ -127,30 +143,33 @@ func isValid(cmd string, tokens []string, conn *net.Conn) int{
} }
switch flag { switch flag {
case 1: (*conn).Write([]byte(ERR_CMD_ERR)) case 1: write(conn, ERR_CMD_ERR)
} }
return flag return flag
} }
func parseInput(conn *net.Conn, msg string, table *KeyValueStore) { func parseInput(conn net.Conn, msg string, table *KeyValueStore) {
tokens := strings.Fields(msg) tokens := strings.Fields(msg)
//fmt.Println(tokens) var buffer bytes.Buffer
//logger.Println(tokens)
switch tokens[0] { switch tokens[0] {
case SET: case SET:
if isValid(SET, tokens, conn) != 0 { if isValid(SET, tokens, conn) != 0 {
return return
} }
performSet(conn, tokens[1:len(tokens)], table) if ver, ok := performSet(conn, tokens[1:len(tokens)], table); ok {
}
//case GET: performGet(tokens[1:len(tokens)]) //case GET: performGet(tokens[1:len(tokens)])
//case GETM: performGetm(tokens[1:len(tokens)]) //case GETM: performGetm(tokens[1:len(tokens)])
//case CAS: performCas(tokens[1:len(tokens)]) //case CAS: performCas(tokens[1:len(tokens)])
//case DELETE: performDelete(tokens[1:len(tokens)]) //case DELETE: performDelete(tokens[1:len(tokens)])
default: fmt.Println("Command not found") default: logger.Println("Command not found")
} }
} }
func performSet(conn *net.Conn, tokens []string, table *KeyValueStore){ func performSet(conn net.Conn, tokens []string, table *KeyValueStore) (uint64, bool){
k := tokens[0] k := tokens[0]
e, _ := strconv.ParseUint(tokens[1], 10, 64) e, _ := strconv.ParseUint(tokens[1], 10, 64)
n, _ := strconv.ParseUint(tokens[2], 10, 64) n, _ := strconv.ParseUint(tokens[2], 10, 64)
...@@ -160,7 +179,7 @@ func performSet(conn *net.Conn, tokens []string, table *KeyValueStore){ ...@@ -160,7 +179,7 @@ func performSet(conn *net.Conn, tokens []string, table *KeyValueStore){
r = false r = false
} }
fmt.Println(r) logger.Println(r)
//read value //read value
v, ok := read(conn, n+2) v, ok := read(conn, n+2)
...@@ -169,35 +188,47 @@ func performSet(conn *net.Conn, tokens []string, table *KeyValueStore){ ...@@ -169,35 +188,47 @@ func performSet(conn *net.Conn, tokens []string, table *KeyValueStore){
return return
} }
(*table).Lock() table.Lock()
logger.Println("Table locked")
//critical section start //critical section start
var val *Data var val *Data
if _, ok := (*table).dictionary[k]; ok { if _, ok := table.dictionary[k]; ok {
val = (*table).dictionary[k] val = table.dictionary[k]
} else{ } else{
val = new(Data) val = new(Data)
(*table).dictionary[k] = val table.dictionary[k] = val
} }
ver++ ver++
(*val).numBytes = n val.numBytes = n
(*val).version = ver val.version = ver
(*val).expTime = e + uint64(time.Now().Unix()) val.expTime = e + uint64(time.Now().Unix())
(*val).value = v val.value = v
(*table).Unlock() table.Unlock()
logger.Println("Table unlocked")
debug(table) debug(table)
return val.version, true
} }
func debug(table *KeyValueStore){ func debug(table *KeyValueStore){
fmt.Println("----start debug----") logger.Println("----start debug----")
for key,val := range (*table).dictionary { for key,val := range (*table).dictionary {
fmt.Println(key, val) logger.Println(key, val)
} }
fmt.Println("----end debug----") logger.Println("----end debug----")
} }
func main() { func main() {
ver = 1 ver = 1
if LOG {
logf, _ := os.OpenFile("serverlog.log", os.O_RDWR | os.O_CREATE | os.O_TRUNC, 0666)
defer logf.Close()
logger = log.New(logf, "SERVER: ", log.Ltime|log.Lshortfile)
} else{
logger = log.New(ioutil.Discard, "SERVER: ", log.Ldate)
}
go startServer() go startServer()
var input string var input string
fmt.Scanln(&input) fmt.Scanln(&input)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment