-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient_server.py
73 lines (63 loc) · 2.4 KB
/
client_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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import random
import sys
# thrift stuff
sys.path.append('gen-py')
from replica import Replica
from replica.ttypes import ReadResult
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer
class ClientHandler:
def __init__(self):
self.id = -1
self.last_seen = dict() # key -> version
self.reachable = set()
self.stubs = dict()
self.transports = dict()
self.key_vectorclock_map = dict()
self.time = 0
def setID(self, id):
self.id = id
def addConnection(self, id, port):
transport = TSocket.TSocket('localhost', port)
transport = TTransport.TBufferedTransport(transport)
protocol = TBinaryProtocol.TBinaryProtocol(transport)
replica = Replica.Client(protocol)
transport.open()
self.reachable.add(id)
self.stubs[id] = replica
self.transports[id] = transport
transport.close()
return id in self.reachable
def removeConnection(self, id):
if id not in self.reachable:
return id not in self.reachable
self.reachable.remove(id)
self.transports[id].close()
self.stubs.pop(id, None)
return id not in self.reachable
def requestWrite(self, key, value):
rid = random.sample(self.reachable, 1)[0]
vector_clock = {}
if key in self.key_vectorclock_map:
vector_clock = self.key_vectorclock_map[key]
self.transports[rid].open()
new_vector_clock = self.stubs[rid].write(key, value, self.id, self.time)
self.key_vectorclock_map[key] = new_vector_clock
self.transports[rid].close()
self.time += 1
def requestRead(self, key):
rid = random.sample(self.reachable, 1)[0]
vector_clock = {}
if key in self.key_vectorclock_map:
vector_clock = self.key_vectorclock_map[key]
self.transports[rid].open()
read_result = self.stubs[rid].read(key, self.id, vector_clock)
if read_result.value != 'ERR_DEP' and read_result.value != 'ERR_KEY':
# update client's vector clock for this key if the result was not
# some kind of error
self.key_vectorclock_map[key] = read_result.vector_clock
self.transports[rid].close()
# return value to master
return read_result.value