# Can Have Socket, Select, Os, Sys
# Can Have Socket, Select, Os, Sys
import select
import socket
import sys
import random
import os
import json
import datetime
bootstrapID = 2**16 - 1
myID = random.randint(0, 2**16 - 2) # random int from 0 and 2^16-2
TIMEOUT = 2 # seconds
def isRequestValid(recvData):
isValid = True
return isValid
def constructRequest(cmd):
# works for cases PRED_REQUEST and SET_PRED. Also works for QUERY
message = { "cmd": cmd, "port": myAddr[1], "ID": myID, "hostname":
socket.gethostname()}
if(cmd == COMMANDS["MY_PRED"]):
message = { "cmd": cmd, "me": { "ID": myID, "hostname":
socket.gethostname(), "port": myAddr[1]}, "thePred": myPred}
# elif(cmd == COMMANDS["OWNER"]):
# message = ''
message = json.dumps(message).encode('utf-8')
return message
def handleRequest(data):
if(not isRequestValid(data)):
print(str(datetime.datetime.now()) + "\t" + "Invalid request: " + str(data)
+ "\n")
else:
if(data["cmd"] == COMMANDS["PRED_REQUEST"]):
print(str(datetime.datetime.now()) + "\t" + "Responding to
PRED_REQUEST: " + str(constructRequest(COMMANDS["MY_PRED"])) + "\n")
serverSocket.sendto(constructRequest(COMMANDS["MY_PRED"]),
data["hostname"], data["port"])
elif data["cmd"] == COMMANDS["SET_PRED"]:
# only set Pred if its less than me, otherwise ignore as its invalid
if(int(data["ID"]) <= myID):
setPred(data["ID"], data["hostname"], data["port"])
elif data["cmd"] == COMMANDS["find"]:
# case 1: successor is valid, so just resolve the query (respond if i
own it, pass on if i dont)
def handleQuery(queryID):
# first send them the find query
# ask for successor's pred
# case 1: successor is valid, so just resolve the query (respond if i own it,
pass on if i dont)
def handleJoin():
return 0
localLog = ''
try:
serverSocket.bind(myAddr)
requestAddress = bootstrapAddr
data = ''
while(True):
# send join request
try:
requestMessage = constructRequest(COMMANDS["PRED_REQUEST"])
serverSocket.sendto(requestMessage, requestAddress)
serverSocket.settimeout(TIMEOUT)
(recvData, recvAddr) = serverSocket.recvfrom(2048)
serverSocket.settimeout(None)
data = json.loads(recvData.decode('utf-8'))
# if the request is not valid, then log with timestamp and break
if((not isRequestValid(data)) or data["cmd"] != COMMANDS["MY_PRED"]):
print(str(datetime.datetime.now()) + "\t" + "Invalid request: " +
str(data) + "\n")
break
requestMessage = constructRequest(COMMANDS["PRED_REQUEST"])
serverSocket.sendto(requestMessage, (mySucc["hostname"], mySucc["port"]))
serverSocket.settimeout(TIMEOUT)
(recvData, recvAddr) = serverSocket.recvfrom(2048)
serverSocket.settimeout(None)
print("who's your pred?" + recvData.decode('utf-8'))
done = False
while not done:
# TODO: try to implement what the prof said about find() and interrupts.
# only in find we stabilize the local neighbourhood, other operations of
the protocol are simple
except Exception as e:
# TODO: throw some exception. with timestamp or handle the case idk
print(str(datetime.datetime.now()) + "\t" + "Code halted due to exception: " +
str(e) + "\n")
finally:
# TODO: do i really need SOCKET SHUTDOWN for datagram socket?
serverSocket.close()
print(str(datetime.datetime.now()) + "\t" + "Code halted due to completion" +
"\n")