def replicaRequest(self, request, context): document = twoLevelDict.find_one({"topic":request.topic,"subscriber":"NULL"}) allotedServer = document["publisher"] if twoLevelDict.find({"topic":request.topic,"publisher":request.client_ip}).count() > 0 : return pr_pb2.acknowledge(ack="Requesting front end server already a replica for "+request.topic) if twoLevelDict.find({"topic":request.topic,"subscriber":request.client_ip}).count() > 0 : if IS_MASTER: response = two_phase_init(pr_pb2.commit_req_data(action="remove",level="3",data_1 = request.topic,data_2="", data_3 = request.client_ip, filename = "twoLevelDict",function_name="replicaRequest")) if response == "ERROR" : twoLevelDict.delete_one({"topic":request.topic,"subscriber":request.client_ip}) else : twoLevelDict.delete_one({"topic":request.topic,"subscriber":request.client_ip}) # twoLevelDict.delete_one({"topic":request.topic,"subscriber":request.client_ip}) if IS_MASTER: response = two_phase_init(pr_pb2.commit_req_data(action="insert",level="3",data_1 = request.topic,data_2=request.client_ip, data_3 = "NULL", filename = "twoLevelDict",function_name="replicaRequest")) if response == "ERROR" : twoLevelDict.insert_one({"topic":request.topic,"publisher":request.client_ip,"subscriber":"NULL"}) else : twoLevelDict.insert_one({"topic":request.topic,"publisher":request.client_ip,"subscriber":"NULL"}) # twoLevelDict.insert_one({"topic":request.topic,"publisher":request.client_ip,"subscriber":"NULL"}) if IS_MASTER: response = two_phase_init(pr_pb2.commit_req_data(action="insert",level="3",data_1 = request.topic,data_2=request.client_ip, data_3 = request.client_ip, filename = "twoLevelDict",function_name="replicaRequest")) if response == "ERROR" : twoLevelDict.insert_one({"topic":request.topic,"publisher":request.client_ip,"subscriber":request.client_ip}) else : twoLevelDict.insert_one({"topic":request.topic,"publisher":request.client_ip,"subscriber":request.client_ip}) # twoLevelDict.insert_one({"topic":request.topic,"publisher":request.client_ip,"subscriber":request.client_ip}) channel = grpc.insecure_channel(allotedServer) stub = pr_pb2_grpc.PublishTopicStub(channel) response = stub.sendBackupRequestReplica(pr_pb2.topicSubscribe(topic=request.topic, client_ip=request.client_ip)) print "Replication for topic server : "+request.client_ip+" started..." return pr_pb2.acknowledge(ack="Requesting front end server "+request.client_ip+" made a replica of topic(backup sent) "+request.topic)
def subscribeRequest(self, request, context): print "\nFRONTEND : new client subscriber ", request.client_ip, " for topic", request.topic subType = "" if subscribers.find({"topic": request.topic}).count() > 0: print "FRONTEND : Not the first client for topic ", request.topic subType = "old" else: print "FRONTEND : First client for topic ", request.topic subType = "new" newSubscribers.insert_one({ "topic": request.topic, "ip": request.client_ip }) subscribers.insert_one({ "topic": request.topic, "ip": request.client_ip }) if subscribers.find({"topic": request.topic}).count() > THRESHOLD: channel = grpc.insecure_channel(CENTRAL_SERVER_IP) stub = pr_pb2_grpc.PublishTopicStub(channel) response = stub.replicaRequest( pr_pb2.topicSubscribe(topic=request.topic, client_ip=str(SELF_IP) + ":" + port)) channel = grpc.insecure_channel(CENTRAL_SERVER_IP) stub = pr_pb2_grpc.PublishTopicStub(channel) response = stub.subscribeRequestCentral( pr_pb2.topicDataType(topic=request.topic, client_ip=str(SELF_IP) + ":" + str(port), type=subType)) return pr_pb2.acknowledge(ack="temporary acknowledge")
def subscribeRequestCentral(self, request, context): print "Subscribe request from access point",request.client_ip," for topic",request.topic," of type :",request.type allotedServer = "" if request.type == "new" : if twoLevelDict.find({"topic":request.topic,"publisher":request.client_ip}).count() > 0: allotedServer = request.client_ip else : l = sys.maxsize tempIp = "" cursor = twoLevelDict.find({"topic":request.topic,"subscriber":"NULL"}) for document in cursor : ip = document["publisher"] if twoLevelDict.find({"topic":request.topic,"publisher":ip}).count() < l : l=twoLevelDict.find({"topic":request.topic,"publisher":ip}).count() tempIp = ip allotedServer = tempIp if IS_MASTER: response = two_phase_init(pr_pb2.commit_req_data(action="insert",level="3",data_1 = request.topic,data_2=allotedServer, data_3 = request.client_ip, filename = "twoLevelDict",function_name="subscribeRequestCentral")) if response == "ERROR" : twoLevelDict.insert_one({"topic":request.topic,"publisher":allotedServer,"subscriber":request.client_ip}) else : twoLevelDict.insert_one({"topic":request.topic,"publisher":allotedServer,"subscriber":request.client_ip}) # twoLevelDict.insert_one({"topic":request.topic,"publisher":allotedServer,"subscriber":request.client_ip}) else : document = twoLevelDict.find_one({"topic":request.topic,"subscriber":request.client_ip}) allotedServer = document["publisher"] channel = grpc.insecure_channel(allotedServer) stub = pr_pb2_grpc.PublishTopicStub(channel) response = stub.sendBackupRequest(pr_pb2.topicSubscribe(topic=request.topic, client_ip=request.client_ip)) print response.ack return pr_pb2.acknowledge(ack="temporary acknowledge from central server")
def unsubscribeRequest(self, request_iterator, context): topicList = [] client_ip = "" for request in request_iterator: print "FRONTEND : Unsubscribe request from client", request.client_ip, " for topic", request.topic client_ip = request.client_ip topicList.append(request.topic) for topic in topicList: subscribers.delete_one({"topic": topic, "ip": client_ip}) count = subscribers.find({"topic": topic}).count() if count <= THRESHOLD and count > 0: channel = grpc.insecure_channel(CENTRAL_SERVER_IP) stub = pr_pb2_grpc.PublishTopicStub(channel) response = stub.deReplicaRequest( pr_pb2.topicSubscribe(topic=topic, client_ip=str(SELF_IP) + ":" + port)) if response.ack == "DONE": dataDump.delete_many({"topic": topic}) print "TOPIC_SERVER : Dereplicated for topic :", topic else: channel = grpc.insecure_channel(CENTRAL_SERVER_IP) stub = pr_pb2_grpc.PublishTopicStub(channel) response = stub.unsubscribeRequestCentral( pr_pb2.topicSubscribe(topic=topic, client_ip=str(SELF_IP) + ":" + port)) return pr_pb2.acknowledge(ack="done")
def upgradeBackup(self, request, context): global IS_MASTER global centralServer global backupCentralServer IS_MASTER=True print_status() centralServer, backupCentralServer = backupCentralServer, centralServer return pr_pb2.acknowledge(ack="backup successfully upgraded to master")
def sendData(self, request, context): cursor = subscribers.find({"topic": request.topic}) pool = ThreadPool(cursor.count()) lst = [] for document in cursor: lst.append([[request], document["ip"]]) results = pool.map(forwardBackupToClient, lst) return pr_pb2.acknowledge(ack="data sent to subscribed clients")
def unsubscribeRequestCentral(self, request, context): print "unsubscribe request from access point",request.client_ip," for topic",request.topic if IS_MASTER: response = two_phase_init(pr_pb2.commit_req_data(action="remove",level="3",data_1 = request.topic,data_2="", data_3 = request.client_ip, filename = "twoLevelDict",function_name="unsubscribeRequestCentral")) if response == "ERROR" : twoLevelDict.delete_one({"topic":request.topic,"subscriber":request.client_ip}) else : twoLevelDict.delete_one({"topic":request.topic,"subscriber":request.client_ip}) return pr_pb2.acknowledge(ack="temporary acknowledge from central server")
def registerIp(self, request, context) : if IS_MASTER: response = two_phase_init(pr_pb2.commit_req_data(action="insert",level="2",data_1 = "ip",data_2=request.ip, data_3 = "", filename = "frontends",function_name="getFrontIp")) if response == "ERROR" : frontends.insert_one({"type":"ip","ip":request.ip}) else : frontends.insert_one({"type":"ip","ip":request.ip}) # frontends.insert_one({"type":"ip","ip":request.ip}) return pr_pb2.acknowledge(ack="Ip added...")
def sendBackupRequest(self, request, context): cursor = dataDump.find({"topic": request.topic}) lst = [] for document in cursor: lst.append(document["data"]) channel = grpc.insecure_channel(request.client_ip) stub = pr_pb2_grpc.PublishTopicStub(channel) response = stub.sendBackup(generateBackup(request.topic, lst)) return pr_pb2.acknowledge(ack="data send to : " + request.client_ip + " complete...")
def sendBackupReplica(self, request_iterator, context): requestList = [] for request in request_iterator: requestList.append(request) topic = "" for request in requestList: dataDump.insert_one({"topic": request.topic, "data": request.data}) topic = request.topic print "Replication complete for topic : " + topic return pr_pb2.acknowledge( ack="complete data backup received by the replica...")
def sendBackupRequestReplica(self, request, context): print "TOPIC_SERVER : Sending data backup for topic : " + request.topic + " to the new replica : " + request.client_ip cursor = dataDump.find({"topic": request.topic}) lst = [] for document in cursor: lst.append(document["data"]) channel = grpc.insecure_channel(request.client_ip) stub = pr_pb2_grpc.PublishTopicStub(channel) response = stub.sendBackupReplica(generateBackup(request.topic, lst)) return pr_pb2.acknowledge(ack="data send to : " + request.client_ip + " replica complete...")
def publish(self, request, context): print "TOPIC_SERVER : Data received for topic : " + request.topic dataDump.insert_one({"topic": request.topic, "data": request.data}) channel = grpc.insecure_channel(CENTRAL_SERVER_IP) stub = pr_pb2_grpc.PublishTopicStub(channel) responses = stub.giveSubscriberIps( pr_pb2.topicSubscribe(topic=request.topic, client_ip=str(SELF_IP) + ":" + port)) ipList = [] for response in responses: ipList.append(response.ip) print("TOPIC_SERVER : frontend subscriber IP received: " + response.ip + " for topic: " + request.topic) if ipList[0] == "none": return pr_pb2.acknowledge(ack="No subscribers for this replica") pool = ThreadPool(len(ipList)) lst = [] for client_ip in ipList: lst.append([request, client_ip]) results = pool.map(sendToFrontend, lst) return pr_pb2.acknowledge(ack="Data send to clients complete")
def deReplicaRequest(self, request, context): dct = {} cursor = twoLevelDict.find({"topic":request.topic}) for document in cursor: if dct.has_key(document["publisher"]): pass else : dct[document["publisher"]] = [] if document["subscriber"]!="NULL" : dct[document["publisher"]].append(document["subscriber"]) if len(dct.keys()) == 1: return pr_pb2.acknowledge(ack="ERROR") extraSubscribers = dct[request.client_ip] if IS_MASTER: response = two_phase_init(pr_pb2.commit_req_data(action="remove",level="2",data_1 = request.topic,data_2=request.client_ip, data_3 = "", filename = "twoLevelDict",function_name="deReplicaRequest")) if response == "ERROR" : twoLevelDict.delete_many({"topic":request.topic,"publisher":request.client_ip}) else : twoLevelDict.delete_many({"topic":request.topic,"publisher":request.client_ip}) # twoLevelDict.delete_many({"topic":request.topic,"publisher":request.client_ip}) del dct[request.client_ip] for subscriber in extraSubscribers : l = sys.maxsize tempIp = "" for ip in dct.keys(): tempCursor = twoLevelDict.find({"topic":request.topic,"publisher":ip}) if tempCursor.count() < l: l = tempCursor.count() tempIp = ip if IS_MASTER: response = two_phase_init(pr_pb2.commit_req_data(action="insert",level="3",data_1 = request.topic,data_2=tempIp, data_3 = subscriber, filename = "twoLevelDict",function_name="deReplicaRequest")) if response == "ERROR" : twoLevelDict.insert_one({"topic":request.topic,"publisher":tempIp,"subscriber":subscriber}) else : twoLevelDict.insert_one({"topic":request.topic,"publisher":tempIp,"subscriber":subscriber}) # twoLevelDict.insert_one({"topic":request.topic,"publisher":tempIp,"subscriber":subscriber}) print "Dereplication for topic server : "+request.client_ip+" started..." return pr_pb2.acknowledge(ack="DONE")
def sendBackup(self, request_iterator, context): requestList = [] topic = "" for request in request_iterator: requestList.append(request) topic = request.topic cursor = newSubscribers.find({"topic": topic}) pool = ThreadPool(cursor.count()) lst = [] for document in cursor: lst.append([requestList, document["ip"]]) results = pool.map(forwardBackupToClient, lst) newSubscribers.delete_many({"topic": topic}) return pr_pb2.acknowledge( ack= "complete data backup received and forwarded to resepective clients..." )
def publishRequest(self, request, context): print "FRONTEND : Data received for topic : " + request.topic channel = grpc.insecure_channel(CENTRAL_SERVER_IP) stub = pr_pb2_grpc.PublishTopicStub(channel) responses = stub.giveIps(pr_pb2.topic(topic=request.topic)) returned_ips = [] for response in responses: print("FRONTEND : Data to be sent to topic server IP: " + response.ip + " for topic: " + request.topic) returned_ips.append(response.ip) lst = [] pool = ThreadPool(len(returned_ips)) for returned_ip in returned_ips: lst.append([request, returned_ip]) results = pool.map(publishData, lst) return pr_pb2.acknowledge(ack="Published in " + str(len(results)) + " topic servers")
def commit_phase_two(self,request,context): if request.filename == "twoLevelDict": if request.action == "remove" : if request.level == "3" : twoLevelDict.delete_one({"topic":request.data_1,"subscriber":request.data_3}) logging.info("%s:%s:REMOVE 3 %s %s %s",str(datetime.now()),request.filename,request.data_1,"NIL",request.data_3) elif request.level == "2" : twoLevelDict.delete_many({"topic":request.data_1,"publisher":request.data_2}) logging.info("%s:%s:REMOVE 2 %s %s %s",str(datetime.now()),request.filename,request.data_1,request.data_2,"NIL") elif request.action == "insert": if request.level == "3" : twoLevelDict.insert_one({"topic":request.data_1,"publisher":request.data_2,"subscriber":request.data_3}) logging.info("%s:%s:INSERT 3 %s %s %s",str(datetime.now()),request.filename,request.data_1,request.data_2,request.data_3) elif request.filename == "frontends" : if request.action == "remove" : if request.level == "2" : if request.data_1 == "ip" : frontends.delete_one({"type":request.data_1,request.data_1:request.data_2}) logging.info("%s:%s:REMOVE 2 %s %s %s",str(datetime.now()),request.filename,request.data_1,request.data_2,request.data_3) else : frontends.delete_one({"type":request.data_1,request.data_1:int(request.data_2)}) logging.info("%s:%s:REMOVE 2 %s %s %s",str(datetime.now()),request.filename,request.data_1,request.data_2,request.data_3) elif request.action == "insert" : if request.level == "2" : if request.data_1 == "ip" : frontends.insert_one({"type":request.data_1,request.data_1:request.data_2}) logging.info("%s:%s:INSERT 2 %s %s %s",str(datetime.now()),request.filename,request.data_1,request.data_2,request.data_3) else : frontends.insert_one({"type":request.data_1,request.data_1:int(request.data_2)}) logging.info("%s:%s:INSERT 2 %s %s %s",str(datetime.now()),request.filename,request.data_1,request.data_2,request.data_3) logging.info("%s:%s:COMMIT",str(datetime.now()),request.filename) return pr_pb2.acknowledge(ack="COMMIT")
def commit_request(self,request,context): if request.filename == "twoLevelDict": if request.action == "remove" : if request.level == "3" : documents = twoLevelDict.find({"topic":request.data_1,"subscriber":request.data_3}) for document in documents: pending_twoLevelDict.insert_one({"topic":document["topic"],"publisher":document["publisher"],"subscriber":document["subscriber"],"action":"remove"}) twoLevelDict.delete_one({"topic":request.data_1,"subscriber":request.data_3}) logging.info("%s:%s:REMOVE 3 %s %s %s",str(datetime.now()),request.filename,request.data_1,"NIL",request.data_3) elif request.level == "2" : documents = twoLevelDict.find({"topic":request.data_1,"publisher":request.data_2}) for document in documents: pending_twoLevelDict.insert_one({"topic":document["topic"],"publisher":document["publisher"],"subscriber":document["subscriber"],"action":"remove"}) twoLevelDict.delete_many({"topic":request.data_1,"publisher":request.data_2}) logging.info("%s:%s:REMOVE 2 %s %s %s",str(datetime.now()),request.filename,request.data_1,request.data_2,"NIL") elif request.action == "insert": if request.level == "3" : twoLevelDict.insert_one({"topic":request.data_1,"publisher":request.data_2,"subscriber":request.data_3}) documents = twoLevelDict.find({"topic":request.data_1,"publisher":request.data_2,"subscriber":request.data_3}) for document in documents: pending_twoLevelDict.insert_one({"topic":document["topic"],"publisher":document["publisher"],"subscriber":document["subscriber"],"action":"insert"}) logging.info("%s:%s:INSERT 3 %s %s %s",str(datetime.now()),request.filename,request.data_1,request.data_2,request.data_3) elif request.filename == "frontends" : if request.action == "remove" : if request.level == "2" : if request.data_1 == "ip" : pending_frontends.insert_one({"type":request.data_1,request.data_1:request.data_2,"action":"remove"}) frontends.delete_one({"type":request.data_1,request.data_1:request.data_2}) logging.info("%s:%s:REMOVE 2 %s %s %s",str(datetime.now()),request.filename,request.data_1,request.data_2,request.data_3) else : pending_frontends.insert_one({"type":request.data_1,request.data_1:int(request.data_2),"action":"remove"}) frontends.delete_one({"type":request.data_1,request.data_1:int(request.data_2)}) logging.info("%s:%s:REMOVE 2 %s %s %s",str(datetime.now()),request.filename,request.data_1,request.data_2,request.data_3) elif request.action == "insert" : if request.level == "2" : if request.data_1 == "ip" : pending_frontends.insert_one({"type":request.data_1,request.data_1:request.data_2,"action":"insert"}) frontends.insert_one({"type":request.data_1,request.data_1:request.data_2}) logging.info("%s:%s:INSERT 2 %s %s %s",str(datetime.now()),request.filename,request.data_1,request.data_2,request.data_3) else : pending_frontends.insert_one({"type":request.data_1,request.data_1:int(request.data_2),"action":"insert"}) frontends.insert_one({"type":request.data_1,request.data_1:int(request.data_2)}) logging.info("%s:%s:INSERT 2 %s %s %s",str(datetime.now()),request.filename,request.data_1,request.data_2,request.data_3) channel = grpc.insecure_channel(centralServer) stub = pr_pb2_grpc.PublishTopicStub(channel) TIMEOUT = 3 print str(TIMEOUT),"seconds to kill central server..." time.sleep(TIMEOUT) retries = 0 while(True) : try : response = stub.commit_phase_two(request) if response.ack == "COMMIT": pending_frontends.drop() pending_twoLevelDict.drop() logging.info("%s:%s:COMMIT",str(datetime.now()),request.filename) return pr_pb2.acknowledge(ack="OK") else : return pr_pb2.acknowledge(ack="ERROR") except : retries += 1 if retries > MAX_RETRIES : print "Central down..." roll_back(request) logging.info("%s:%s:ROLLBACK",str(datetime.now()),request.filename) return pr_pb2.acknowledge(ack="ERROR")
def forwardBackup(self, request_iterator, context): for request in request_iterator: print "\nReceived new data..." print request dataDump.insert_one({"topic": request.topic, "data": request.data}) return pr_pb2.acknowledge(ack="Data received by the client...")
def giveDataPhaseTwo(self,response,context): IS_LOCKED = False print "Master is unlocked... Phase two completed" return pr_pb2.acknowledge(ack = "phase two completed")