def Quit(self, request, context): idk = int(request.idkey) for i in range(4): for entry in self.k_buckets[i]: if int(entry.id) == idk: self.k_buckets[i].remove(entry) print("Evicting quitting node " + str(idk) + " from bucket " + str(i)) return csci4220_hw3_pb2.IDKey(node=self.node, idkey=self.id) print("No record of quitting node " + str(idk) + " in k-buckets.") return csci4220_hw3_pb2.IDKey(node=self.node, idkey=self.id)
def Find_Node(nodeID): if nodeID == local_node.id: print("Found destination id %d" % nodeID) else: closest = [] asked = [] for i in k_buckets: closest += i closest = sorted(closest, key=lambda x: nodeID ^ x.id) while len([i for i in closest if i not in asked][:k]): s = [i for i in closest if i not in asked][:k] for node in s: with grpc.insecure_channel( "%s:%d" % (node.address, node.port)) as channel: stub = csci4220_hw3_pb2_grpc.KadImplStub(channel) ret = stub.FindNode( csci4220_hw3_pb2.IDKey(node=local_node, idkey=nodeID)) asked.append(node) AddorUpdateNode(node) for i in ret.nodes: if i == local_node or i in k_buckets[DetermineBucket( i)]: continue AddorUpdateNode(i) for i in k_buckets: for j in i: if nodeID == j.id: print("Found destination id %d" % nodeID) return closest.clear() for i in k_buckets: closest += i closest = sorted(closest, key=lambda x: nodeID ^ x.id) print("Could not find destination id %d" % nodeID)
def find_value(args): print("Before FIND_VALUE command, k-buckets are:\n{}".format( print_buckets())) key = int(args.split()[1]) # Getting value from the input if hash_table.contains_key( key): # the hash table is where we keep the key value pairs print("Found data \"{}\" for key {}".format(hash_table.get(key), key)) print("After FIND_VALUE command, k-buckets are:\n" + print_buckets()) return else: unvisited = find_k_closest( key) # if we dont have the value in out hash ... visited = list() visited.append( csci4220_hw3_pb2. Node( # we need to loop over the k closest nodes, similar to findnode id=local_id, port=int(my_port), address=my_address)) value_found = False value = None while len( unvisited ) > 0 and not value_found: # Now, we loop over all of the unvisited nodes for node in unvisited: channel = grpc.insecure_channel("{}:{}".format( node.address, node.port)) kad = csci4220_hw3_pb2_grpc.KadImplStub(channel) response = kad.FindValue( # Create a connection to that node csci4220_hw3_pb2.IDKey(node=csci4220_hw3_pb2.Node( id=local_id, port=int(my_port), address=my_address), idkey=key)) save_node( node) # Save it, as it needs to be updated based on LRU visited.append( node) # And we add it to the visited nodes array if response.mode_kv: value = response.kv.value value_found = True break for resp_node in response.nodes: # If we havent found the value in our direct k_buckets.... if not node_is_stored( resp_node ) and resp_node.id != local_id: # We look in each node's k_buckets save_node(resp_node) # Look for any unvisited nodes and add them for next iteration unvisited = [] for node in find_k_closest(key): if node not in visited: unvisited.append(node) if value_found: # Handling the output statements for the found value, if it is found/not print("Found value \"{}\" for key {}".format(value, key)) else: print("Could not find key {}".format(key)) print("After FIND_VALUE command, k-buckets are:\n" + print_buckets())
def handle_find_node(self, node_id): # if the finding node is this node finded_node = None if self.id == node_id: return True else: flag = False visited = {self.id} k_nodes = deque(self.find_nearest_k(node_id, self.k)) while k_nodes: node = k_nodes.popleft() if not node.id in visited: self.update_k_bucket(node) if node.id == node_id: flag = True break with grpc.insecure_channel(node.address + ":" + str(node.port)) as channel: stub = csci4220_hw3_pb2_grpc.KadImplStub(channel) cur_node = csci4220_hw3_pb2.Node(id=self.id, port=int(self.port), address=self.address) IDKey = csci4220_hw3_pb2.IDKey(node=cur_node, idkey=node_id) res = stub.FindNode(IDKey) visited.add(node.id) for n in res.nodes: if not n.id in visited: k_nodes.append(n) while k_nodes: node = k_nodes.popleft() self.update_k_bucket(node) return flag
def Store(self, request, context): global bucket global local_key global local_value # store nodes directly at server node local_key = request.key local_value = request.value print('Storing key {} value "{}"'.format(request.key,request.value)) sys.stdout.flush() if request.node.id==1000: request.node.id = 0 index = locateBucket(local_node,request.node.id) if index!=-1: if index not in bucket: tmp = [] tmp.append(nodeObj(request.node.id,request.node.port,request.node.address)) bucket[index] = tmp else: n = len(bucket[index]) if n==bucket_max: tmp = bucket[index] tmp.pop() tmp.insert(0,nodeObj(request.node.id,request.node.port,request.node.address)) bucket[index] = tmp tmp = csci4220_hw3_pb2.Node(id=local_node,port=local_port,address=local_address) return csci4220_hw3_pb2.IDKey(node=tmp,idkey=request.key)
def handle_find_value(self, key): #reserve the visited node id if key in self.library: print("Found data \"%s\" for key %d" % (self.library[key], key)) return visited = set() visited.add(self.id) k_nodes = deque(self.find_nearest_k(key, self.k)) # change to while with pop while k_nodes: node = k_nodes.popleft() if not node.id in visited: with grpc.insecure_channel(node.address + ":" + str(node.port)) as channel: stub = csci4220_hw3_pb2_grpc.KadImplStub(channel) cur_node = csci4220_hw3_pb2.Node(id=self.id, port=int(self.port), address=self.address) IDKey = csci4220_hw3_pb2.IDKey(node=cur_node, idkey=key) res = stub.FindValue(IDKey) visited.add(node.id) # contain key value or nodes if res.mode_kv: print("Found value \"%s\" for key %d" % (res.kv.value, key)) if res.responding_node != self.id: self.update_k_bucket(node) return else: for n in res.nodes: if not n.id in visited: k_nodes.append(n) print("Could not find key %d" % (key))
def find_node(args): print("Before FIND_NODE command, k-buckets are:\n{}".format( print_buckets())) node_id = int(args.split()[1]) unvisited = find_k_closest( node_id) # Accesses the k closest nodes in the buckets visited = [] # returned in a dictionary next_visit = [] node_found = False while len(unvisited) > 0 and not node_found: for node in unvisited: # looping over all of the unvisted nodes channel = grpc.insecure_channel("{}:{}".format( node.address, node.port)) kad = csci4220_hw3_pb2_grpc.KadImplStub(channel) # creates a connection to each node response = kad.FindNode( # attempts to find the node in search by searching this csci4220_hw3_pb2.IDKey( # node's k_buckets node=csci4220_hw3_pb2. Node( # to other nodes, so they can update id=local_id, # their k_buckets port=int(my_port), address=my_address), idkey=node_id)) save_node( node ) # As we just accessed this node, we need to update the buckets visited.append( node) # Add it to the visited node, do not want to backtrack if node.id == node_id: # If this node is the one we are searching for we can break node_found = True break for resp_node in response.nodes: # Otherwise we also need to check to see the node's k_buckets if not node_is_stored(resp_node): save_node( resp_node ) # If we come across a node not in our network.... we add it if resp_node not in visited: next_visit.append( resp_node ) # Also add this one to the visited nodes list if resp_node.id == node_id: node_found = True if node_found: break # Look for any unvisited nodes and add them for next iteration unvisited = [] for node in find_k_closest(node_id): if node not in visited: unvisited.append(node) if node_found: # Handling the computed node / no node found messages print("Found destination id {}".format(node_id)) else: print("Could not find destination id ".format(node_id)) print("After FIND_NODE command, k-buckets are:\n" + print_buckets())
def Store(self, request, context): print("Storing key %d value \"%s\"" % (request.key, request.value)) self.library[request.key] = request.value cur_node = csci4220_hw3_pb2.Node(id=self.id, port=int(self.port), address=self.address) IDKey = csci4220_hw3_pb2.IDKey(node=cur_node, idkey=request.key) return IDKey
def Store(self, request, context): """Store the value at the given node. Need to return *something*, but client does not use this return value. """ print(f'Storing key {request.key} value "{request.value}"', flush=True) self.values[request.key] = request.value self.DHT.updateNodeLoc(request.node) return csci4220_hw3_pb2.IDKey( node = self.DHT.ourNode, idkey = 0 )
def Quit(): for i in k_buckets: for j in i: print("Letting %d know I'm quitting." % j.id) with grpc.insecure_channel("%s:%d" % (j.address, j.port)) as channel: stub = csci4220_hw3_pb2_grpc.KadImplStub(channel) try: stub.Quit( csci4220_hw3_pb2.IDKey(node=local_node, idkey=local_node.id)) except: continue
def Quit(self, request, context): quit_id = request.idkey i = self.compute_dist(self.id, quit_id) - 1 flag = True if quit_id in self.k_bucket[i]: del self.k_bucket[i][quit_id] print("Evicting quitting node %d from bucket %i" % (quit_id, i)) else: print("No record of quitting node %d in k-buckets." % quit_id) cur_node = csci4220_hw3_pb2.Node(id=self.id, port=int(self.port), address=self.address) IDKey = csci4220_hw3_pb2.IDKey(node=cur_node, idkey=quit_id) return IDKey
def Store(self, request, context): # Use the request input to store key and value inside our node self.key_value.insert(0, (request.key, request.value)) k_closest_nodes = self.find_k_closest_nodes(request.idkey) if len(k_closest_nodes) == 0 or k_closest_nodes.id == self.id: a = 1 #do nothing else: print("Storing key {} value \"{}\"".format(request.key, request.value)) self.update_k_buckets(request.node, 1) # Return ID key for other peer's usage return csci4220_hw3_pb2.IDKey(node=self.node, idkey=self.id)
def Bootstrap(hostname, port): remote_addr = socket.gethostbyname(hostname) remote_port = port with grpc.insecure_channel("%s:%s" % (remote_addr, remote_port)) as channel: stub = csci4220_hw3_pb2_grpc.KadImplStub(channel) ret = stub.FindNode( csci4220_hw3_pb2.IDKey(node=local_node, idkey=local_node.id)) AddorUpdateNode(ret.responding_node) for i in ret.nodes: AddorUpdateNode(i) print("After BOOTSTRAP(%d), k_buckets now look like:" % ret.responding_node.id) print_k_buckets()
def broadcast(self, remote_hostname, remote_port): with grpc.insecure_channel(remote_hostname + ":" + str(remote_port)) as channel: stub = csci4220_hw3_pb2_grpc.KadImplStub(channel) cur_node = csci4220_hw3_pb2.Node(id=self.id, port=int(self.port), address=self.address) IDKey = csci4220_hw3_pb2.IDKey(node=cur_node, idkey=self.id) # run the remote FindNode res = stub.FindNode(IDKey) #update the k_bucket self.update_k_bucket(res.responding_node) for new_node in res.nodes: self.update_k_bucket(new_node) #print k_bucket print("After BOOTSTRAP(%d), k_buckets now look like:" % res.responding_node.id) self.print_k_bucket()
def handle_quit(self): for i in range(4): for k in self.k_bucket[i]: v = self.k_bucket[i][k] print("Letting %d know I'm quitting." % (v.id)) try: with grpc.insecure_channel(v.address + ":" + str(v.port)) as channel: stub = csci4220_hw3_pb2_grpc.KadImplStub(channel) cur_node = csci4220_hw3_pb2.Node(id=self.id, port=int(self.port), address=self.address) IDKey = csci4220_hw3_pb2.IDKey(node=cur_node, idkey=self.id) stub.Quit(IDKey) except Exception as e: pass print("Shut down node %d" % self.id)
def execute_quit(): for node_list in k_buckets: for node in node_list: print("Letting {} know I'm quitting.".format( node.id)) # notifies each node in the k_buckets channel = grpc.insecure_channel("{}:{}".format( node.address, node.port)) kad = csci4220_hw3_pb2_grpc.KadImplStub( channel) # creates a connection to each node try: kad.Quit( csci4220_hw3_pb2.IDKey( # and calls a quit on THIS node node=csci4220_hw3_pb2. Node( # to other nodes, so they can update id=local_id, # their k_buckets port=int(my_port), address=my_address), idkey=local_id)) except grpc.RpcError: pass server.stop(0) print("Shut down node {}".format(local_id)) # Outputs to the console
def Find_Value(key): if key in hash_table.keys(): print("Found data \"%s\" for key %d" % (hash_table[key], key)) else: #TODO # This chunk of code still needs work closest = [] asked = [] for i in k_buckets: closest += i closest = sorted(closest, key=lambda x: key ^ x.id) while len([i for i in closest if i not in asked][:k]): s = [i for i in closest if i not in asked][:k] for node in s: with grpc.insecure_channel( "%s:%d" % (node.address, node.port)) as channel: stub = csci4220_hw3_pb2_grpc.KadImplStub(channel) ret = stub.FindValue( csci4220_hw3_pb2.IDKey(node=local_node, idkey=key)) AddorUpdateNode(node) asked.append(node) if not ret.mode_kv: for i in ret.nodes: if i == local_node or i in k_buckets[ DetermineBucket(i)]: continue AddorUpdateNode(i) closest.clear() for i in k_buckets: closest += i closest = sorted(closest, key=lambda x: key ^ x.id) else: if ret.kv.key == key: print("Found value \"{}\" for key {}".format( ret.kv.value, ret.kv.key)) return print("Could not find key {}".format(key))
def Quit(self, request, context): global bucket Found = False if request.node.id==1000: request.node.id = 0 # loop over to find client node and delete it from bucket for k,v in list(bucket.items()): mark = -1 for i in range(0,len(v)): if v[i].id==request.idkey: mark = i if len(v)>1: Found = True print("Evicting quitting node {} from bucket {}".format(request.idkey,k)) sys.stdout.flush() if mark!=-1 and Found==True: v.remove(mark) for k,v in list(bucket.items()): for i in range(0,len(v)): if v[i].id==request.idkey: if len(v)==1: Found = True del bucket[k] print("Evicting quitting node {} from bucket {}".format(request.idkey,k)) sys.stdout.flush() if Found==False: print("No record of quitting node {} in k-buckets.".format(request.node.id)) sys.stdout.flush() r_node = csci4220_hw3_pb2.Node(id=local_node,port=local_port,address=local_address) return csci4220_hw3_pb2.IDKey(node=r_node,idkey=local_node)
def bootstrap(args): hostname = args.split()[1] # Gettting the hostname from input port = args.split()[2] # Getting the port from input address = socket.gethostbyname(hostname) # Getting the hostname channel = grpc.insecure_channel("{}:{}".format(address, port)) kad = csci4220_hw3_pb2_grpc.KadImplStub(channel) # Get NodeList from remote node to update k_buckets response = kad.FindNode( csci4220_hw3_pb2.IDKey(node=csci4220_hw3_pb2.Node(id=local_id, port=int(my_port), address=my_address), idkey=local_id)) # Save bootstrap node save_node(response.responding_node) # Save nodes learned from bootstrap node for node in response.nodes: save_node(node) print("After BOOTSTRAP({}), k_buckets now look like:\n{}".format( response.responding_node.id, print_buckets()))
def findingValue(find_key): visited = [] Found = False print("Before FIND_VALUE command, k-buckets are:") sys.stdout.flush() for i in range(0,N): tmp = str(i)+":" for k,v in bucket.items(): if k==i and len(v)!=0: for m in v: tmp += " " tmp += str(m.id) tmp += ":" tmp += str(m.port) print(tmp) sys.stdout.flush() all_nodes = [] for k,v in bucket.items(): for j in range(len(v)): if v[j].id!=local_node: all_nodes.append(v[j]) ordered_nodes = sorted(all_nodes, key=lambda x : XOR(x.id,local_node)) S = [] S_prime = [] if len(ordered_nodes)<bucket_max: S = ordered_nodes else: for i in range(0,bucket_max): S.append(ordered_nodes[i]) for x in S: add = True for v_node in visited: if x==v_node: add = False if add==True: S_prime.append(x) for search_node in S_prime: visited.append(search_node.id) remote_host = search_node.id remote_port = int(search_node.port) remote_addr = search_node.address with grpc.insecure_channel(remote_addr + ':' + str(remote_port)) as channel: stub = csci4220_hw3_pb2_grpc.KadImplStub(channel) node_tmp = csci4220_hw3_pb2.Node(id=local_node,port=local_port,address=local_address) idKey = csci4220_hw3_pb2.IDKey(node=node_tmp,idkey=find_key) ret = stub.FindValue(idKey) if ret.mode_kv==True: Found = True tmp_p = '"'+ret.kv.value+'"' print("Found value ""{}"" for key {}".format(tmp_p,find_key)) mr_used = ret.responding_node mr_index = locateBucket(local_node,mr_used.id) if mr_index not in bucket: tmp = [] tmp.append(mr_used) bucket[mr_index] = tmp else: adding = True for y in bucket[mr_index]: if y.id==mr_used.id and len(bucket[mr_index])==1: adding = False elif y.id==mr_used.id and len(bucket[mr_index])==bucket_max and bucket[mr_index][-1].id==mr_used.id: adding = False if adding==True: tmp = bucket[mr_index] tmp.pop(0) tmp.append(mr_used) bucket[mr_index] = tmp break elif ret.mode_kv==False: R = [] for node in ret.nodes: R.append(node) mr_used = search_node mr_index = locateBucket(local_node,mr_used.id) for x in R: if x.id==1000: x.id = 0 if x.id==find_key: Found = True remote_host = x.id remote_port = int(x.port) remote_addr = x.address with grpc.insecure_channel(remote_addr + ':' + str(remote_port)) as channel: stub = csci4220_hw3_pb2_grpc.KadImplStub(channel) node_tmp = csci4220_hw3_pb2.Node(id=local_node,port=local_port,address=local_address) idKey = csci4220_hw3_pb2.IDKey(node=node_tmp,idkey=find_key) result = stub.FindValue(idKey) tmp_p = '"'+result.kv.value+'"' print("Found value ""{}"" for key {}".format(tmp_p,find_key)) index = locateBucket(local_node,x.id) update = True for k,v in bucket.items(): if k==index: for i in range(0,len(v)): if v[i].id==mr_used.id or v[i].id==local_node: update==False if update==True: if index not in bucket: tmp = [] tmp.append(x) bucket[index] = tmp else: adding = True for y in bucket[index]: if y.id==mr_used.id: adding = False if adding==True: tmp = bucket[index] n = len(tmp) if n<bucket_max: tmp.insert(0,x) else: tmp.insert(0,x) tmp.pop() # print(tmp) bucket[index] = tmp if mr_index in bucket.values(): bucket[mr_index].remove(mr_used) bucket[mr_index].insert(0,mr_used) channel.close() if Found==False: print("Could not find key " + str(find_key)) sys.stdout.flush() print("After FIND_VALUE command, k-buckets are:") sys.stdout.flush() for i in range(0,N): tmp = str(i)+":" for k,v in bucket.items(): if k==i and len(v)!=0: for m in v: tmp += " " tmp += str(m.id) tmp += ":" tmp += str(m.port) print(tmp) sys.stdout.flush()
def findingNode(find_node_id): visited = [] Found = False print("Before FIND_NODE command, k-buckets are:") sys.stdout.flush() for i in range(0,N): tmp = str(i)+":" for k,v in bucket.items(): if k==i and len(v)!=0: for m in v: tmp += " " tmp += str(m.id) tmp += ":" tmp += str(m.port) print(tmp) sys.stdout.flush() all_nodes = [] for k,v in bucket.items(): for j in range(len(v)): if v[j].id==find_node_id: Found = True index = locateBucket(find_node_id,local_node) tmp = bucket[index] x = v[j] tmp.remove(x) tmp.insert(0, x) print("Found destination id " + str(find_node_id)) sys.stdout.flush() print("After FIND_NODE command, k-buckets are:") sys.stdout.flush() for i in range(0,N): tmp = str(i)+":" for k,v in bucket.items(): if k==i and len(v)!=0: for m in v: tmp += " " tmp += str(m.id) tmp += ":" tmp += str(m.port) print(tmp) sys.stdout.flush() return else: all_nodes.append(v[j]) ordered_nodes = sorted(all_nodes, key=lambda x : XOR(x.id,find_node_id)) S = [] S_prime = [] if len(ordered_nodes)<bucket_max: S = ordered_nodes else: for i in range(0,bucket_max): S.append(ordered_nodes[i]) for x in S: add = True for v_node in visited: if x==v_node: add = False if add==True: S_prime.append(x) for search_node in S_prime: if search_node.id==find_node_id: Found = True print("Found destination id " + str(find_node_id)) break visited.append(search_node.id) remote_host = search_node.id remote_port = int(search_node.port) remote_addr = search_node.address with grpc.insecure_channel(remote_addr + ':' + str(remote_port)) as channel: stub = csci4220_hw3_pb2_grpc.KadImplStub(channel) node_tmp = csci4220_hw3_pb2.Node(id=find_node_id,port=0,address="") idKey = csci4220_hw3_pb2.IDKey(node=node_tmp,idkey=local_node) nodeList = stub.FindNode(idKey) R = [] for node in nodeList.nodes: R.append(node) mr_used = search_node mr_index = locateBucket(local_node,mr_used.id) for x in R: if x.id==1000: x.id = 0 if x.id==find_node_id: Found = True print("Found destination id " + str(find_node_id)) index = locateBucket(local_node,x.id) update = True for k,v in bucket.items(): if k==index: for i in range(0,len(v)): if v[i].id==mr_used.id or v[i].id==local_node: update==False for j in range(0,len(v)): if v[i].id==v[j].id: update==False if update==True: mr_used = x if index not in bucket: tmp = [] tmp.append(x) bucket[index] = tmp else: tmp = bucket[index] tmp.append(x) n = len(tmp) if n>bucket_max: tmp.pop(0) bucket[index] = tmp if mr_index in bucket.values(): bucket[mr_index].remove(mr_used) bucket[mr_index].insert(0,mr_used) channel.close() print("After FIND_NODE command, k-buckets are:") sys.stdout.flush() for i in range(0,N): tmp = str(i)+":" for k,v in bucket.items(): if k==i and len(v)!=0: for m in v: tmp += " " tmp += str(m.id) tmp += ":" tmp += str(m.port) print(tmp) sys.stdout.flush() if Found==False: print("Could not find destination id " + str(find_node_id)) sys.stdout.flush()
def bootStrap(stub,remote_host,remote_port): global bucket_max # locate other side send connection node_tmp = csci4220_hw3_pb2.Node(id=local_node,port=local_port,address=local_address) idKey = csci4220_hw3_pb2.IDKey(node=node_tmp,idkey=local_node) nodeList = stub.FindNode(idKey) to_bucket = [] to_bucket.append(nodeList.responding_node) for node in nodeList.nodes: to_bucket.append(node) # update bucket for x in to_bucket: if x.id==1000: x.id = 0 add = True for item in bucket.items(): for node in item[1]: if x.id==node.id: add = False if add==True: index = locateBucket(local_node,x.id) if index!=-1: if index not in bucket: tmp = [] obj = nodeObj(x.id,x.port,x.address) tmp.append(obj) bucket[index] = tmp else: n = len(bucket[index]) tmp = bucket[index] if n==bucket_max: l = tmp[-1] tmp[-1] = tmp[0] tmp[0] = l tmp.pop() obj = nodeObj(x.id,x.port,x.address) tmp.append(obj) bucket[index] = tmp # outprint print("After BOOTSTRAP(" + str(remote_host) + "), k_buckets now look like:") sys.stdout.flush() for i in range(0,N): tmp = str(i)+":" for k,v in bucket.items(): if k==i and len(v)!=0: for m in v: tmp += " " tmp += str(m.id) tmp += ":" tmp += str(m.port) print(tmp) sys.stdout.flush()
channel.close() elif msg.split(" ")[0]=='QUIT': if already_quit==False: for k,v in list(bucket.items()): for i in range(0,len(v)): if v[i].id!=local_node: re_id = v[i].id if v[i].id==0: re_id = 1000 print("Letting " + str(v[i].id) + " know I'm quitting.") sys.stdout.flush() node = csci4220_hw3_pb2.Node(id=re_id,port=v[i].port,address=v[i].address) id_key = csci4220_hw3_pb2.IDKey(node=node,idkey=local_node) with grpc.insecure_channel(v[i].address + ':' + str(v[i].port)) as channel: stub = csci4220_hw3_pb2_grpc.KadImplStub(channel) stub.Quit(id_key) channel.close() for k,v in list(bucket.items()): del bucket[k] print("Shut down node " + str(local_node)) sys.stdout.flush() already_quit = True else: print("ERROR! Not valid command!", file=sys.stderr) sys.stdout.flush()
def Store(self, KeyValue, context): AddorUpdateNode(KeyValue.node) print("Storing key %d value \"%s\"" % (KeyValue.key, KeyValue.value)) hash_table[KeyValue.key] = KeyValue.value return csci4220_hw3_pb2.IDKey(node=local_node, idkey=KeyValue.key)
def run(): if len(sys.argv) != 4: print("Error, correct usage is {} [my id] [my port] [k]".format(sys.argv[0])) sys.exit(-1) local_id = int(sys.argv[1]) my_port = str(int(sys.argv[2])) # add_insecure_port() will want a string k = int(sys.argv[3]) my_hostname = socket.gethostname() # Gets my host name my_address = socket.gethostbyname(my_hostname) # Gets my IP address from my hostname ''' Use the following code to convert a hostname to an IP and start a channel Note that every stub needs a channel attached to it When you are done with a channel you should call .close() on the channel. Submitty may kill your program if you have too many file descriptors open at the same time. ''' #remote_addr = socket.gethostbyname(remote_addr_string) #remote_port = int(remote_port_string) #channel = grpc.insecure_channel(remote_addr + ':' + str(remote_port)) ourNode = csci4220_hw3_pb2.Node(id = local_id, port = int(my_port), address = my_address) ourServicer = KadImplServicer(k, ourNode) # Code to start the servicer for our node server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) csci4220_hw3_pb2_grpc.add_KadImplServicer_to_server(ourServicer, server) server.add_insecure_port(f'[::]:{my_port}') server.start() # Let servicer start listening w/t blocking while True: userInput = input() # Perhaps change this to select, but that's a discussion for later :P userInput = userInput.strip().split() if ((userInput[0]).lower().strip() == "bootstrap"): remoteHost = (userInput[1]).strip() remotePort = (userInput[2]).strip() remote_addr = socket.gethostbyname(remoteHost) remote_port = int(remotePort) with grpc.insecure_channel(remote_addr + ':' + str(remote_port)) as channel: stub = csci4220_hw3_pb2_grpc.KadImplStub(channel) result = stub.FindNode(csci4220_hw3_pb2.IDKey(node = ourNode, idkey = ourNode.id)) remoteID = result.responding_node.id] ourServicer.DHT.updateNodeLoc(result.responding_node) for node_ in result.nodes: ourServicer.DHT.updateNodeLoc(node_) print(f'After BOOTSTRAP({remoteID}), k_buckets now look like:') ourServicer.DHT.print() elif ((userInput[0]).lower().strip() == "find_node" or (userInput[0]).lower().strip() == "find_value"): nodeID = int((userInput[1]).strip()) findNode = (userInput[0]).lower().strip() == "find_node" print(f"Before FIND_{'NODE' if findNode else 'VALUE'} command, k-buckets are:") ourServicer.DHT.print() found = nodeID == local_id if findNode else ourServicer.values.get(nodeID) is not None value = (found, ourServicer.values.get(nodeID)) if (not found): # Do the search Visited = set() # Stores id of visited nodes nodeOfInterest = csci4220_hw3_pb2.IDKey(node = ourNode, idkey = nodeID) # Condition for us to use FindNode or FindValue # S = ourServicer.DHT.kClosest(nodeOfInterest.idkey) # get k closest to idkey S = ourServicer.DHT.kClosest(nodeOfInterest.idkey) # get k closest nodes to idkey # print(f"Closest nodes to {nodeOfInterest.idkey} are {[n.id for n in S]}") notVisited = [n for n in S if n.id not in Visited] while not found and len(notVisited) > 0: for node in notVisited: with grpc.insecure_channel(node.address + ':' + str(node.port)) as channel: stub = csci4220_hw3_pb2_grpc.KadImplStub(channel) # Condition for us to use FindNode or FindValue R = stub.FindNode(nodeOfInterest) if findNode else stub.FindValue(nodeOfInterest) # Update our k-buckets with node ourServicer.DHT.updateNodeLoc(R.responding_node) if not findNode and R.mode_kv: # If we're for FindValue found = True value = (R.responding_node.id == ourNode.id, R.kv.value) # If a node in R was already in a k-bucket, its position does not change. # If it was not in the bucket yet, then it is added as the most recently used in that bucket. # This _may_ kick out the node from above. for n in R.nodes: if findNode and (n.id ^ nodeOfInterest.idkey) == 0: found = True ourServicer.DHT.updateNodeLoc(n) Visited.add(node.id) if found: break S = ourServicer.DHT.kClosest(nodeOfInterest.idkey) # get k closest nodes to idkey notVisited = [n for n in S if n.id not in Visited] # Do the printing if (found): if findNode: print(f'Found destination id {nodeID}', flush=True) else: if value[0]: print(f'Found data "{value[1]}" for key {nodeID}') else: print(f'Found value "{value[1]}" for key {nodeID}') else: if findNode: print(f'Could not find destination id {nodeID}', flush=True) else: print(f'Could not find key {nodeID}') print(f"After FIND_{'NODE' if findNode else 'VALUE'} command, k-buckets are:") ourServicer.DHT.print() elif ((userInput[0]).lower().strip() == "store"): key = int(userInput[1].strip()) val = userInput[2].strip() # Find the node it knows that's closest to the key closestNodes = ourServicer.DHT.kClosest(key) if len(closestNodes) == 0 or (ourNode.id ^ key <= closestNodes[0].id ^ key): print(f'Storing key {key} at node {ourNode.id}', flush=True) ourServicer.values[key] = val else: print(f'Storing key {key} at node {closestNodes[0].id}', flush=True) with grpc.insecure_channel(closestNodes[0].address + ':' + str(closestNodes[0].port)) as channel: stub = csci4220_hw3_pb2_grpc.KadImplStub(channel) stub.Store(csci4220_hw3_pb2.KeyValue(node = ourNode, key = key, value = val)) elif ((userInput[0]).lower().strip() == "quit"): for node in ourServicer.DHT.getAllNodes(): with grpc.insecure_channel(node.address + ':' + str(node.port)) as channel: stub = csci4220_hw3_pb2_grpc.KadImplStub(channel) print(f'Letting {node.id} know I\'m quitting.', flush=True) try: stub.Quit(csci4220_hw3_pb2.IDKey(node = ourNode, idkey = ourNode.id)) except: pass # The stub already closed print(f'Shut down node {ourNode.id}', flush=True) server.stop(None) break else: print("Invalid Command", flush=True)
def Store(self, request, context): print("Storing key {} value \"{}\"".format(request.key, request.value)) hash_table.put(request.key, request.value) save_node(request.node) # Need to return something, but this isn't used return csci4220_hw3_pb2.IDKey(node=request.node, idkey=request.key)
def run(): ''' Check the # of command-line arguments, which should have hw3.py <nodeID> <port> <k> ''' if len(sys.argv) != 4: print("Error, correct usage is {} [my id] [my port] [k]".format( sys.argv[0])) sys.exit(-1) local_id = int(sys.argv[1]) my_port = str(int(sys.argv[2])) # add_insecure_port() will want a string k = int(sys.argv[3]) my_hostname = socket.gethostname() # Gets my host name my_address = socket.gethostbyname( my_hostname) # Gets my IP address from my hostname # print("[myself] Running as {0} @ {1}".format(my_hostname,my_address)) # Setting up the server server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) servicer = KadImplServicer(local_id, int(my_port), my_address, k) csci4220_hw3_pb2_grpc.add_KadImplServicer_to_server(servicer, server) server.add_insecure_port("[::]:" + my_port) server.start() # Run the client while True: inputs = input() arguments = inputs.split() if arguments[0] == "BOOTSTRAP": remote_hostname = arguments[1] my_port = int(arguments[2]) remote_addr = socket.gethostbyname(remote_hostname) # Connect to other peer channel = grpc.insecure_channel( str(remote_addr) + ':' + str(my_port)) stub = csci4220_hw3_pb2_grpc.KadImplStub(channel) # Find peer node using servicer node nodee = stub.FindNode( csci4220_hw3_pb2.IDKey(node=servicer.node, idkey=local_id)) # Add node that was responding res_node = nodee.responding_node bit_len = ((res_node.id) ^ local_id).bit_length() bit_len -= 1 if len(servicer.k_buckets[bit_len]) == k: servicer.k_buckets[bit_len].popleft() servicer.k_buckets[bit_len].append(res_node) # Print bucket contents print('After BOOTSTRAP({}), k_buckets now look like:'.format( str(res_node.id))) servicer.print_k_buckets() channel.close() elif arguments[0] == "FIND_NODE": # Load the inputs argument node_id = int(arguments[1]) print("Before FIND_NODE command, k-buckets are:") servicer.print_k_buckets() S = servicer.find_k_closest_nodes(node_id) S_no = S # Nodes in S that have not been contacted yet S_yes = [] # Nodes that have been contacted found = False while S_no and (not found): for no in S_no: # Start a channel channel = grpc.insecure_channel(no.address + ':' + str(no.port)) stub = csci4220_hw3_pb2_grpc.KadImplStub(channel) # Send a FindNode RPC R = stub.FindNode( csci4220_hw3_pb2.IDKey(node=servicer.node, idkey=node_id)) # Update the k-buckets servicer.update_k_buckets(no, True) for node in R.nodes: servicer.update_k_buckets(node, False) # Update S_yes S_yes.append(no) # Close the channel channel.close() # Check if the node has been found for bucket in servicer.k_buckets: if any(node.id == node_id for node in bucket): found = True print("Found destination id {}".format(node_id)) break if not found: # Update S and S_no S = servicer.find_k_closest_nodes(node_id) S_no.clear() for node in S: if not any(yes.id == node.id for yes in S_yes): S_no.append(node) if not found: print("Could not find destination id {}".format(node_id)) print("After FIND_NODE command, k-buckets are:") servicer.print_k_buckets() elif arguments[0] == "FIND_VALUE": # Load the inputs argument key = int(arguments[1]) print("Before FIND_VALUE command, k-buckets are:") servicer.print_k_buckets() found = False # See if the key/value pair has already been stored for pair in servicer.key_value: if pair[0] == key: found = True print("Found data \"{}\" for key {}".format(pair[1], key)) break if not found: S = servicer.find_k_closest_nodes(key) S_no = S # Nodes in S that have not been contacted yet S_yes = [] # Nodes that have been contacted while S_no and (not found): for no in S_no: # Start a channel channel = grpc.insecure_channel(no.address + ':' + str(no.port)) stub = csci4220_hw3_pb2_grpc.KadImplStub(channel) # Send a FindNode RPC R = stub.FindValue( csci4220_hw3_pb2.IDKey(node=servicer.node, idkey=key)) # Update the k-buckets servicer.update_k_buckets(no, True) # Update S_yes S_yes.append(no) # Close the channel channel.close() # Check if the value is found if R.mode_kv: found = True print("Found value \"{}\" for key {}".format( R.kv.value, key)) break else: # Update the k-buckets for node in R.nodes: servicer.update_k_buckets(node, False) if not found: # Update S and S_no S = servicer.find_k_closest_nodes(key) S_no.clear() for node in S: if not any(yes.id == node.id for yes in S_yes): S_no.append(node) if not found: print("Could not find key {}".format(key)) print("After FIND_VALUE command, k-buckets are:") servicer.print_k_buckets() elif arguments[0] == "STORE": this_key = int(arguments[1]) this_value = arguments[2] closest_node = csci4220_hw3_pb2.Node(id=local_id, port=int(my_port), address=str(my_address)) distance = abs(local_id - this_key) for bucket in servicer.k_buckets: for entry in bucket: if abs(int(entry.id) - this_key) < distance: closest_node = entry distance = abs(int(entry.id) - this_key) closest_port = int(closest_node.port) #Connect to server & stub this_addr = closest_node.address + ':' + str(closest_port) channel = grpc.insecure_channel(this_addr) stub = csci4220_hw3_pb2_grpc.KadImplStub(channel) some_idkey = stub.Store( csci4220_hw3_pb2.KeyValue(node=servicer.node, key=this_key, value=this_value)) print("Storing key {} at node {}".format(this_key, some_idkey.idkey)) channel.close() elif arguments[0] == "QUIT": # Tell everyone we are quitting, goodbye :( for bucket in servicer.k_buckets: for entry in bucket: remote_host = str(entry.id) remote_port = int(entry.port) my_addr = entry.address + ':' + str(remote_port) # Create channel and tell other peer we are quitting channel = grpc.insecure_channel(my_addr) stub = csci4220_hw3_pb2_grpc.KadImplStub(channel) print("Letting " + remote_host + " know I'm quitting.") some_idkey = stub.Quit( csci4220_hw3_pb2.IDKey(node=servicer.node, idkey=local_id)) channel.close() print("Shut down node " + str(local_id)) break else: # Unknown command print("Unknown command. Use BOOTSTRAP , FIND_VALUE , STORE , QUIT")