def __init__(self,ip,port): self.ip = ip self.port = port self.name = "http://"+str(ip)+":"+str(port) self.hashid = getHash(self.name) self.server = RPCThreading(("",port),logRequests=False) #register functions here self.server.register_function(self.checkIn,"checkIn") self.server.register_function(self.report,"report") self.aliveNodes = [] self.deadNodes = [] self.safe = [] self.churnThread = None t = Thread(target=self.server.serve_forever) t.start() self.churn = False self.choosing = False
class InstrumentationNode(object): def __init__(self,ip,port): self.ip = ip self.port = port self.name = "http://"+str(ip)+":"+str(port) self.hashid = getHash(self.name) self.server = RPCThreading(("",port),logRequests=False) #register functions here self.server.register_function(self.checkIn,"checkIn") self.server.register_function(self.report,"report") self.aliveNodes = [] self.deadNodes = [] self.safe = [] self.churnThread = None t = Thread(target=self.server.serve_forever) t.start() self.churn = False self.choosing = False # kill a random node in the network def killRandom(self): self.kill(random.choice(self.aliveNodes)) # rez a random node def rezRandom(self): self.rez(random.choice(self.deadNodes),random.choice(self.aliveNodes)) # tell a node to pretend to diaf def kill(self,victim): newPort = random.choice(PORTS) print "Killing", victim, getHashString(victim) try: oldPort = int(victim[victim.rfind(":")+1:]) newName = victim[:victim.rfind(":")+1]+str(newPort) Peer(victim).kill(newPort) self.aliveNodes.remove(victim) self.deadNodes.append(newName) PORTS.remove(newPort) PORTS.append(oldPort) #do at end except Exception as e: print "He's already dead", e # add node back in def rez(self, nodeName, ringMember): print "Rezzing", nodeName, getHashString(nodeName) try: Peer(nodeName).join(ringMember) self.deadNodes.remove(nodeName) except Exception as e: print "Error rezzing", e # splits up nodes among the dead and living according to ratio def setupExperiment(self): targets = self.aliveNodes[:] for node in targets: self.kill(node) print "Wanton destruction complete." print "alive:", self.aliveNodes print len(targets), len(self.deadNodes) time.sleep(2) print "Creating new network." n = random.choice(self.deadNodes) Peer(n).create() self.deadNodes.remove(n) ## adding the rest while len(self.aliveNodes) < len(self.deadNodes): self.rezRandom() time.sleep(MAINT_INT) print "Done." self.startChurn() print "Storing." self.choosing = True tester = random.choice(self.aliveNodes) self.safe.append(tester) self.choosing = False try: Peer(tester).storeFile(TEST_FILE) except: print "failed." traceback.print_exc(file=sys.stdout) print "terminating." return print "Store done." self.safe.pop() self.choosing = True tester = random.choice(self.aliveNodes) outputAddress = getHashString( Peer(tester).name) print outputAddress self.safe.append(tester) self.choosing = False try: Peer(tester).stage(TEST_FILE, outputAddress) except: print "failed." traceback.print_exc(file=sys.stdout) print "terminating." return print "Stage done." #self.safe.pop() #print "Churning the network before we retrieve." #time.sleep(10) """ for node in self.aliveNodes: try: print Peer(node).myInfo() except Exception as e: print e self.churn = False print "Done." """ # public def checkIn(self,nodeName): self.aliveNodes.append(nodeName) print nodeName, "checked in." return True def startChurn(self): print "Allowing network to establish before Churn." time.sleep(3) self.churnThread = Thread(target=self.simulateChurn) self.churnThread.daemon = True self.churn = True self.churnThread.start() print "Started Churn." time.sleep(5) def simulateChurn(self): while self.churn: if not self.choosing: try: time.sleep(1) for node in self.aliveNodes[:]: if node not in self.safe and len(self.aliveNodes) > 1 and random.random() < CHURN_RATE: self.kill(node) joinTargets = self.aliveNodes[:] for node in self.deadNodes[:]: if len(self.deadNodes) > 1 and random.random() < CHURN_RATE: self.rez(node, random.choice(joinTargets)) except Exception, e: print "Error in Churn", e print "Churning done!"