Repository navigation
Expand file tree
/
Copy pathserver.go
More file actions
122 lines (89 loc) · 2.05 KB
/
Copy pathserver.go
File metadata and controls
122 lines (89 loc) · 2.05 KB
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
package main
import (
"bufio"
"context"
"fmt"
"log"
"net"
"strings"
"time"
)
type Server struct{
listeningAddress string
cache *cacheShardMap
}
func NewServer(listenAddr string , c *cacheShardMap ) *Server{
return &Server{
listeningAddress: listenAddr,
cache: c,
}
}
func (s *Server) handleClient(conn net.Conn){
defer conn.Close()
scanner:= bufio.NewScanner(conn)
for scanner.Scan(){
line:= strings.TrimSpace(scanner.Text())
if line == ""{
continue
}
parts:= strings.Fields(line)
command:= strings.ToUpper(parts[0])
switch command{
case "SET":
if len(parts) < 3{
fmt.Println(conn,"ERR wrong number of arguments for SET command.. ")
continue
}
key:= parts[1]
value:= []byte(parts[2])
var ttl time.Duration
if len(parts) >= 4{
d,err:= time.ParseDuration(parts[3])
if err != nil{
fmt.Printf("Wrong ttl duration / format ")
return
}
ttl = d;
}
s.cache.Set(key,value,ttl)
fmt.Fprintln(conn,"OK")
case "GET":
if len(parts) < 2{
fmt.Println(conn,"ERR .. Least number of arguments for GET command is 2 , Try again..")
continue
}
value,ok:=s.cache.Get(parts[1])
if !ok || value == nil{
fmt.Println(conn,"(nill)")
}
fmt.Fprintf(conn, "%s\n", string(value))
case "DELETE":
if len(parts) < 2{
fmt.Println(conn,"ERR .. Least number of arguments for DELETE command is 2 , Try again..")
continue
}
s.cache.Delete(parts[1])
fmt.Fprintln(conn, "OK")
default:
fmt.Fprintf(conn, "ERR unknown command '%s'\n", command)
}
}
}
func (s *Server) Start() error {
clientConn,err:= net.Listen("tcp",s.listeningAddress)
if err != nil{
log.Fatalf("Couldn't listen on the port [%s] : %v",s.listeningAddress,err)
}
ctx,cancel:= context.WithCancel(context.Background());
defer cancel()
defer clientConn.Close()
for{
conn,err:=clientConn.Accept();
if err != nil{
log.Printf("Error accepting the connection : %v",err)
return err
}
go s.cache.StartEvictionWorker(ctx,1*time.Second)
go s.handleClient(conn)
}
}