-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathserver.py
57 lines (44 loc) · 1.69 KB
/
server.py
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
# coding: utf-8
# This is a sample server which acts as a Redis server but uses Bitcask
# instead. It only implements GET and SET operations.
import socketserver
def _pack_value(value):
return b'$' + bytes(str(len(value)), 'ascii') + b'\r\n' + value + b'\r\n'
class MyTCPHandler(socketserver.StreamRequestHandler):
def _read_command(self):
first = self.rfile.readline().rstrip()
assert first.startswith(b'$')
length = int(first[1:])
data = self.rfile.readline()
assert len(data) == length + 2
return data[:-2]
def handle(self):
data = self.rfile.readline().rstrip()
assert data.startswith(b'*')
commands_to_read = int(data[1:])
command = self._read_command()
parameters = [self._read_command() for _ in range(commands_to_read - 1)]
if command == b'SET':
if len(parameters) != 2:
# TODO: send the correct error
self.wfile.write(b'-ERR\r\n')
else:
self.server._db[parameters[0]] = parameters[1]
self.wfile.write(b'+OK\r\n')
elif command == b'GET':
key = parameters[0]
try:
value = self.server._db[parameters[0]]
except KeyError:
self.wfile.write(b'$-1\r\n')
else:
self.wfile.write(_pack_value(value))
else:
# TODO: send the correct error
self.wfile.write(b'-ERR\r\n')
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
import bitcask
server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)
server._db = bitcask.Bitcask('mycask')
server.serve_forever()