Newer
Older
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
import json
from multiprocessing.connection import Client
import pickle
import random
import socket
import sys
from message import * # Can change this after testing done
from timers import ClientTimer, setTimer
class LockClient():
def __init__(self) -> None:
with open("config.json", encoding='utf-8') as f:
json_dict = json.loads(f.read())
server_addresses = json_dict["servers"]
self.server_addresses = [(server_addresses[i], int(server_addresses[i + 1])) for i in range(0, len(server_addresses), 2)]
# create a UDP socket
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock.bind(('', 0))
self.client_addr = self.sock.getsockname()
print(f"Starting client {self.client_addr}", file=sys.stdout)
random.seed(0)
# For client timer to know whether to resend message
self.req_num = 0
def execute(self):
prompt_str = "Enter a command (e.g. lock 1 / unlock 1 / exit): "
input_str = input(prompt_str) # Input would be "lock 2" / "unlock 1", etc or "exit"
try:
while input_str != "exit":
lock, val = input_str.split(" ", 2)
paxos_req = PaxosRequest(self.client_addr, LockCommand(lock, val, self.req_num))
data = pickle.dumps(paxos_req)
server_address = random.choice(self.server_addresses)
print(f"Sending command {paxos_req} to {server_address}", file=sys.stdout)
self.sock.sendto(data, server_address)
setTimer(ClientTimer(paxos_req, self.req_num), ClientTimer.CLIENT_RETRY_MILLIS, self.onClientTimer)
# receive data back from the server
res = pickle.loads(self.sock.recv(1024))
while res.cmd.req_num != self.req_num:
res = pickle.loads(self.sock.recv(1024))
self.req_num += 1
print(f"Received response: {res}", file=sys.stdout)
if res.value == True:
print("Command successfully ran", file=sys.stdout)
else:
print("Command failed to run", file=sys.stdout)
input_str = input(prompt_str)
finally:
# Close socket
self.sock.close()
def onClientTimer(self, client_timer: ClientTimer):
# print(f"{client_timer}: Callback", file=sys.stdout)
if self.req_num <= client_timer.req_num:
server_address = random.choice(self.server_addresses)
print(f"Resending command {client_timer.paxos_req} to {server_address}", file=sys.stdout)
data = pickle.dumps(client_timer.paxos_req)
self.sock.sendto(data, server_address)
setTimer(client_timer, ClientTimer.CLIENT_RETRY_MILLIS, self.onClientTimer)
if __name__ == "__main__":
client = LockClient()
client.execute()