예제 #1
0
    def SendFindValue(self, target_key):

        if target_key in self.data.keys():
            print("Found data \""+ self.data[target_key]+ "\" for key " + str(target_key))
            return
        
        obj = csci4220_hw4_pb2.IDKey(node=csci4220_hw4_pb2.Node(id=self.my_id, port=int(self.my_port), address=self.my_address), idkey=target_key)

        visited = []
        visited.append(self.my_id)

        # for all peers
        to_sort = []
        for item in self.k_buckets.items():
            for peer in item[1]:
                to_sort.append(peer)
        
        # sort the peers based on distance to target_key
        to_sort.sort(key=lambda node: (target_key ^ node.node_id).bit_length() -1)

        # for all peers in order
        for peer in to_sort:
            with grpc.insecure_channel(peer.address + ":" + str(peer.port)) as channel:

                # send find value command
                stub = csci4220_hw4_pb2_grpc.KadImplStub(channel)
                R = stub.FindValue(obj)
                visited.append(peer.node_id)

                b = peer.node_id ^ self.my_id
                b = b.bit_length() - 1

                # update location of the peer
                self.UpdateBucket(b, peer)
                
                # if found
                if (R.mode_kv == True):
                    print("Found value \"" + R.kv.value + "\" for key " + str(R.kv.key))
                    return
                else:
                    for i in R.nodes:
                        if i.id not in visited:

                            b = self.my_id ^ i.id
                            b = b.bit_length() - 1

                            self.UpdateBucket(b, Node(i.address, i.port, i.id))

                            # search through the returned k nearest peers
                            with grpc.insecure_channel(i.address + ":" + str(i.port)) as to_ask:
                                stub = csci4220_hw4_pb2_grpc.KadImplStub(to_ask)
                                response = stub.FindValue(obj)
                                visited.append(i.id)

                                # if found in peer list
                                if (response.mode_kv == True):
                                    print("Found value \"" + response.kv.value + "\" for key " + str(response.kv.key))
                                    return
        # if haven't found at this point, print that it couldn't be found
        print("Could not find key " + str(target_key))
예제 #2
0
    def SendBootstrap(self, peer_host, peer_port):
        # temporarily connect with them to get 
        with grpc.insecure_channel(peer_host + ":" + peer_port) as channel:
            
            # access the remote server
            stub = csci4220_hw4_pb2_grpc.KadImplStub(channel)
            obj = csci4220_hw4_pb2.IDKey(node=csci4220_hw4_pb2.Node(id=self.my_id, port=int(self.my_port), address=self.my_address), idkey=self.my_id)
            
            # node contains the return from FindNode
            node = stub.FindNode(obj)

            # get the bucket it should be stored in
            bucket = self.my_id ^ node.responding_node.id
            bucket = bucket.bit_length() - 1
            

            # create a new node from the responding node and append it
            n = Node(node.responding_node.address, node.responding_node.port, node.responding_node.id)
            self.UpdateBucket(bucket,n)

            # add all the nodes that were neighbors
            for i in node.nodes:
                b = self.my_id ^ i.id
                b = b.bit_length() - 1

                if (b >= 0):
                    self.UpdateBucket(b, Node(i.address, i.port, i.id))
            print("After BOOTSTRAP(" + str(node.responding_node.id) + "), k_buckets now look like:")
            self.PrintBuckets()
예제 #3
0
def rpcFindNode(recipient, requestedId, meNode):

	remote_addr = recipient.address
	remote_port = recipient.port
	with grpc.insecure_channel(remote_addr + ':' + str(remote_port)) as channel:
		idKey = csci4220_hw4_pb2.IDKey(node = meNode, idkey = requestedId)
		try:
			stub = csci4220_hw4_pb2_grpc.KadImplStub(channel)
			response = stub.FindNode(idKey)
		except:
			print("Try Failed in rpcFindNode")
			return

	return response.nodes
예제 #4
0
def quit(myId, meNode, k_buckets):

	for lst in k_buckets:
		for node in lst:
			print("Letting {} know I'm quitting.".format(node.id))

			with grpc.insecure_channel(node.address + ':' + str(node.port)) as channel:
				try:
					stub = csci4220_hw4_pb2_grpc.KadImplStub(channel)
					request = csci4220_hw4_pb2.IDKey(node=meNode, idkey=myId)
					response = stub.Quit(request)
				except:
					#print("Try Failed in quit")
					pass

	print("Shut down node {}".format(myId))
예제 #5
0
def bootstrap(remote_addr_string, remote_port_string, myId, meNode, k_buckets, k):
	remote_addr = socket.gethostbyname(remote_addr_string)
	remote_port = int(remote_port_string)

	#set up RPC channel
	with grpc.insecure_channel(remote_addr + ':' + str(remote_port)) as channel:
		#Set up stub, send message, get response
		try:
			stub = csci4220_hw4_pb2_grpc.KadImplStub(channel)
			request = csci4220_hw4_pb2.IDKey(node=meNode, idkey=myId)
			response = stub.FindNode(request)
		except:
			print("Try Failed in bootstrap")
			return

		#add responding node if not in kbuckets
		responding_node = response.responding_node
		found = False
		for lst in k_buckets:
			if responding_node in lst:
				found = True
				break
		if not found:
			addNode(k_buckets, responding_node, myId, k)

		#add new nodes to kbuckets
		nodeList = response.nodes
		for node in nodeList:

			if node.id == myId:
				continue

			found = False
			for lst in k_buckets:
				if node in lst:
					found = True
					break
			if found:
				continue

			addNode(k_buckets, node, myId, k)

		#make the responding node the most recently used
		makeMostRecent(responding_node, k_buckets)
		print("After BOOTSTRAP({}), k_buckets now look like:".format(
			response.responding_node.id))
		printBuckets(k_buckets)
예제 #6
0
    def SendQuit(self):
        obj = csci4220_hw4_pb2.IDKey(node=csci4220_hw4_pb2.Node(id=self.my_id, port=int(self.my_port), address=self.my_address), idkey=self.my_id)

        # for all peers
        for item in self.k_buckets.items():
            for peer in item[1]:
                #send a quit to all pears
                with grpc.insecure_channel(peer.address + ":" + str(peer.port)) as channel:
                    print("Letting "+ str(peer.node_id)+" know I'm quitting.")
                    
                    # send quit to them
                    try:
                        stub = csci4220_hw4_pb2_grpc.KadImplStub(channel)
                        ret = stub.Quit(obj)
                    # if quit does not connect, do nothing
                    # hacky way as of submitty 195
                    except:
                        pass
예제 #7
0
    def SendFindNode(self, target_id):
        obj = csci4220_hw4_pb2.IDKey(node=csci4220_hw4_pb2.Node(id=self.my_id, port=int(self.my_port), address=self.my_address),
        idkey=target_id)

        # keep track of visited
        visited = []
        for item in self.k_buckets.items():
            bucket = item[1]
            for index in range(len(bucket)):

                # if already visited
                if (bucket[index].node_id in visited):
                    print("alerady visited")
                    continue

                # send the peer the find node command
                with grpc.insecure_channel(bucket[index].address + ":" + str(bucket[index].port)) as channel:
                    stub = csci4220_hw4_pb2_grpc.KadImplStub(channel)

                    # make the request
                    R = stub.FindNode(obj)

                    # add this to visited
                    visited.append(bucket[index].node_id)

                    # update the position of this first node
                    self.UpdateBucket(item[0],bucket[index])

                    # update k buckets with node (move it to the front)
                    for i in R.nodes:
                        b = self.my_id ^ i.id
                        b = b.bit_length() - 1

                        # make sure not self
                        if (b >= 0):
                            found = False
                            for match in bucket:
                                if match.node_id == i.id:
                                    found = True

                            # found it
                            if (target_id == i.id):
                                print("Found destination id " + str(target_id))
                            self.UpdateBucket(b, Node(i.address, i.port, i.id))
예제 #8
0
def store(key, value, k_buckets, k, meNode, storedDict):

	minDist = meNode.id ^ key
	minNode = meNode

	# iterate over all known nodes to find node closest to the key
	for bucket in k_buckets:
		for node in bucket:
			dist = node.id ^ key
			if(dist < minDist):
				minDist = dist
				minNode = node

	# if this node is the closest node, store the value locally
	if(minNode.id == meNode.id):
		print("Storing key %d at node %d" % (key, meNode.id))

		storedDict[key] = value
		return


	print("Storing key %d at node %d" % (key, minNode.id))

	#Set up RPC and send Store RPC to proper node
	remote_addr = minNode.address
	remote_port = minNode.port
	with grpc.insecure_channel(remote_addr + ':' + str(remote_port)) as channel:
		keyVal = csci4220_hw4_pb2.KeyValue(node = meNode, key = key, value = value)
		try:
			stub = csci4220_hw4_pb2_grpc.KadImplStub(channel)
			response = stub.Store(keyVal)
			makeMostRecent(minNode, k_buckets)
		except:
			print("Try Failed in store")
			return

	return
예제 #9
0
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.'''


    # start the server in the background
    hash_table = HashTable()
    hash_table.my_port = int(my_port)
    hash_table.my_id = local_id
    hash_table.my_address = my_address

    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    csci4220_hw4_pb2_grpc.add_KadImplServicer_to_server(hash_table, server)
    server.add_insecure_port('[::]:'+my_port)
    server.start()

    # initializing the buckets 2^k
    buckets = pow(2, k)
    for i in range(buckets):
        hash_table.k_buckets[i] = []
    

    # main listening loop
    while (True):
        stdin = str(input())
        arguments = stdin.split(" ")

        # connect to another peer directly
        if (arguments[0] == "BOOTSTRAP"):
            peer_host = arguments[1]
            peer_port = arguments[2]

            hash_table.SendBootstrap(peer_host, peer_port)

        # if the command is to store a value at a key
        if (arguments[0] == "STORE"):
            key = int(arguments[1])
            value = arguments[2]
            min_dist = key ^ hash_table.my_id
            min_key = Node(hash_table.my_address, hash_table.my_port, hash_table.my_id)

            # get the minimum distance peer to the key
            for item in hash_table.k_buckets.items():
                for peer in item[1]:
                    dist = key ^ peer.node_id
                    if dist < min_dist:
                        min_dist = dist
                        min_key = peer
            
            print("Storing key " + str(key) + " at node " + str(min_key.node_id))
            if (min_key.node_id == hash_table.my_id):
                hash_table.data[key] = value
            else:

                # send the store command to that remote
                with grpc.insecure_channel(min_key.address + ":" + str(min_key.port)) as channel:
                    stub = csci4220_hw4_pb2_grpc.KadImplStub(channel)
                    obj = csci4220_hw4_pb2.KeyValue(node=csci4220_hw4_pb2.Node(id=hash_table.my_id, port=int(hash_table.my_port), address=hash_table.my_address), key=key, value=value)
                    
                    id_key = stub.Store(obj)

        # command to find a node
        if (arguments[0] == "FIND_NODE"):
            target_id = int(arguments[1])
            print("Before FIND_NODE command, k-buckets are:")
            hash_table.PrintBuckets()

            # perform searching and updating here
            hash_table.SendFindNode(target_id)

            print("After FIND_NODE command, k-buckets are:")
            hash_table.PrintBuckets()

        # command to find a value
        if (arguments[0] == "FIND_VALUE"):
            find_target = int(arguments[1])
            print("Before FIND_VALUE command, k-buckets are:")
            hash_table.PrintBuckets()

            # perform search and updating here
            hash_table.SendFindValue(find_target)

            print("After FIND_VALUE command, k-buckets are:")
            hash_table.PrintBuckets()

        # command to  quit and unregister self from pers
        if (arguments[0] == "QUIT"):

            # send quit to all peers
            hash_table.SendQuit()
            print("Shut down node " + str(local_id))
            break
예제 #10
0
def run():
    if len(sys.argv) != 4:
        print("Error, correct usage is {} [my id] [my port] [k]".format(sys.argv[0]))
        sys.exit(-1)

    global val
    global val_key
    global buckets
    
    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])
    
    #4 buckets needed
    i = 4
    while i > 0:
        #append 4 empty deques into the bucket, the deques should contain Nodes
        buckets.append(deque([]))
        i -= 1
    
    my_hostname = socket.gethostname() # Gets my host name
    my_address = socket.gethostbyname(my_hostname) # Gets my IP address from my hostname
    
    #don't ask, gRPC tutorial said so
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    csci4220_hw4_pb2_grpc.add_KadImplServicer_to_server(KadImplServicer(), server)
    
    #listen from the port
    server.add_insecure_port("127.0.0.1" + ':' + my_port)
    server.start()
    
	# 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(my_hostname)
    #remote_port = int(my_port)
    
    #channel = grpc.insecure_channel(remote_addr + ':' + str(remote_port))
    
    while True:
        input_str = str(raw_input())
        input_args = input_str.split()
        
        if input_args[0] == "BOOTSTRAP":
            #print("bootstrap")
            remote_hostname = str(input_args[1])
            remote_port = int(input_args[2])
            remote_addr = socket.gethostbyname(remote_hostname)
            
            #connect to server & create stub
            channel = grpc.insecure_channel("127.0.0.1" + ':' + str(remote_port))
            stub = csci4220_hw4_pb2_grpc.KadImplStub(channel)
            
            #create the node object
            this_node = csci4220_hw4_pb2.Node(id = local_id, port = int(my_port), address = str(my_address))
            
            #call FindNode
            node_list = stub.FindNode(csci4220_hw4_pb2.IDKey(node = this_node, idkey = local_id))
            
            #add nodes from the list in node_list
            for node in node_list.nodes:
                bit_len = ((node.id)^local_id).bit_length()
                bit_len -= 1
                #pop an element if the bucket is full
                if len(buckets[bit_len]) == k:
                    buckets[bit_len].popleft()
                buckets[bit_len].append(node)
            
            #add the node that it just sent RPC to
            r_node = node_list.responding_node
            bit_len = ((r_node.id)^local_id).bit_length()
            bit_len -= 1
            if len(buckets[bit_len]) == k:
                buckets[bit_len].popleft()
            buckets[bit_len].append(r_node)
            
            #done (hopefully)
            print('After BOOTSTRAP({}), k_buckets now look like:'.format(str(r_node.id)))
            count = 0
            for bucket in buckets:
                sys.stdout.write('{}:'.format(str(count)))
                for entry in bucket:
                    sys.stdout.write(' {}:{}'.format(str(entry.id), str(entry.port)))
                sys.stdout.write('\n')
                count += 1
            
            channel.close()

        if input_args[0] == "STORE":
            print("store")
            this_key = int(input_args[1])
            this_value = input_args[2]

            closest_node = csci4220_hw4_pb2.Node(id = local_id, port = int(my_port), address = str(my_address))
            distance = abs(local_id - this_key)
            for bucket in buckets:
                for entry in bucket:
                    if abs(int(entry.id) - this_key) < distance:
                	    closest_node = entry
                	    distance = abs(int(entry.id) - this_key)
            remote_hostname = str(closest_node.id)
            remote_port = int(closest_node.port)
            remote_addr = socket.gethostbyname(remote_hostname)
            
            #connect to server & create stub
            this_addr = "127.0.0.1" + ':' + str(remote_port)
            channel = grpc.insecure_channel(this_addr)
            stub = csci4220_hw4_pb2_grpc.KadImplStub(channel)
            print(this_addr)
            some_idkey = stub.Store(csci4220_hw4_pb2.KeyValue(node = None, key = this_key, value = this_value))

            channel.close()
            
        if input_args[0] == "QUIT":
            for bucket in buckets:
                for entry in bucket:
            	    remote_hostname = str(entry.id)
            	    remote_port = int(entry.port)
            	    remote_addr = socket.gethostbyname(remote_hostname)
            	    this_addr = "127.0.0.1" + ':' + str(remote_port)
            	    channel = grpc.insecure_channel(this_addr)
            	    stub = csci4220_hw4_pb2_grpc.KadImplStub(channel)

            	    print("Letting " + remote_hostname + " know I'm quitting.")
            	    some_idkey = stub.Quit(csci4220_hw4_pb2.IDKey(node = None, idkey = local_id))
            	    channel.close()
            print("Shut down node " + str(local_id))
            break
예제 #11
0
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

    # Create server
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=16))
    servicer = KadImplServicer()
    csci4220_hw4_pb2_grpc.add_KadImplServicer_to_server(servicer, server)
    server.add_insecure_port('[::]:' + my_port)
    server.start()

    servicer.k = k
    for i in range(n):
        servicer.k_buckets.append([])

    servicer.this_node = csci4220_hw4_pb2.Node(id=local_id,
                                               port=int(my_port),
                                               address=my_address)

    # Listen for commands from standard input
    while 1:
        for line in sys.stdin:
            command = line.split(" ")
            for i in range(len(command)):
                command[i] = command[i].strip()

            # BOOTSTRAP command
            if (command[0] == "BOOTSTRAP"):
                remote_addr = socket.gethostbyname(command[1])
                remote_port = int(command[2])
                with grpc.insecure_channel(remote_addr + ':' +
                                           str(remote_port)) as channel:
                    stub = csci4220_hw4_pb2_grpc.KadImplStub(channel)

                    nodeList = stub.FindNode(
                        csci4220_hw4_pb2.IDKey(node=servicer.this_node,
                                               idkey=servicer.this_node.id))

                    k_buckets_add(servicer, nodeList.responding_node)

                    # Add nodes in nodeList to k_buckets
                    for node in nodeList.nodes:
                        k_buckets_add(servicer, node)

                    print("After BOOTSTRAP(" +
                          str(nodeList.responding_node.id) +
                          "), k_buckets now look like:")
                    print_k_buckets(servicer.k_buckets)

            # FIND_NODE command
            if (command[0] == "FIND_NODE"):
                print("Before FIND_NODE command, k-buckets are:")
                print_k_buckets(servicer.k_buckets)

                key = int(command[1])
                found = 0

                if local_id == key:
                    print("Found destination id " + str(key))
                else:
                    for i in range(n):
                        for j in range(len(servicer.k_buckets[i])):
                            if found == 0:
                                with grpc.insecure_channel(
                                        servicer.k_buckets[i][j].address +
                                        ':' +
                                        str(servicer.k_buckets[i][j].port)
                                ) as channel:
                                    stub = csci4220_hw4_pb2_grpc.KadImplStub(
                                        channel)

                                    nodelist = stub.FindNode(
                                        csci4220_hw4_pb2.IDKey(
                                            node=servicer.this_node,
                                            idkey=key))

                                    for node in nodelist.nodes:
                                        k_buckets_add(servicer, node)
                                        if node.id == key:
                                            print("Found destination id " +
                                                  str(key))
                                            found = 1

                if found == 0:
                    print("Could not find destination id " + str(key))

                print("After FIND_NODE command, k-buckets are:")
                print_k_buckets(servicer.k_buckets)

            # FIND_VALUE command
            if (command[0] == "FIND_VALUE"):
                print("Before FIND_VALUE command, k-buckets are:")
                print_k_buckets(servicer.k_buckets)

                key = int(command[1])
                found = 0

                # First check if key is stored locally
                if key in servicer.values:
                    print('Found data "' + servicer.values[key] +
                          '" for key ' + str(key))
                    found = 1
                else:
                    # Find node with id closest to key
                    closest = None
                    for i in range(n):
                        for j in range(len(servicer.k_buckets[i])):
                            if closest == None:
                                closest = servicer.k_buckets[i][j]
                            if (servicer.k_buckets[i][j].id
                                    ^ key) < (closest.id ^ key):
                                closest = servicer.k_buckets[i][j]

                    # Check if bucket is empty
                    if closest != None:
                        # Ask closest node for value
                        with grpc.insecure_channel(
                                closest.address + ':' +
                                str(closest.port)) as channel:
                            stub = csci4220_hw4_pb2_grpc.KadImplStub(channel)

                            kv_wrapper = stub.FindValue(
                                csci4220_hw4_pb2.IDKey(node=servicer.this_node,
                                                       idkey=key))

                            k_buckets_add(servicer, kv_wrapper.responding_node)

                            # If value was found for key
                            if kv_wrapper.mode_kv:
                                print('Found value "' + kv_wrapper.kv.value +
                                      '" for key ' + str(key))
                                found = 1
                            else:
                                for node in kv_wrapper.nodes:
                                    k_buckets_add(servicer, node)
                                    # Correct node found, ask for value
                                    if node.id == key:
                                        with grpc.insecure_channel(
                                                node.address + ':' +
                                                str(node.port)) as channel:
                                            stub = csci4220_hw4_pb2_grpc.KadImplStub(
                                                channel)

                                            kv_wrapper1 = stub.FindValue(
                                                csci4220_hw4_pb2.IDKey(
                                                    node=servicer.this_node,
                                                    idkey=key))

                                            if kv_wrapper1.mode_kv:
                                                print('Found value "' +
                                                      kv_wrapper1.kv.value +
                                                      '" for key ' + str(key))
                                                found = 1

                if found == 0:
                    print("Could not find key " + str(key))

                print("After FIND_VALUE command, k-buckets are:")
                print_k_buckets(servicer.k_buckets)

            # STORE command
            if (command[0] == "STORE"):
                key = int(command[1])
                value = command[2]

                # Find node with id closest to key
                closest = servicer.this_node
                for i in range(n):
                    for j in range(len(servicer.k_buckets[i])):
                        if (servicer.k_buckets[i][j].id ^ key) < (closest.id
                                                                  ^ key):
                            closest = servicer.k_buckets[i][j]

                # Check if this is the closest node -> store locally
                if closest.id == servicer.this_node.id:
                    servicer.values[key] = value
                else:
                    # Send value to closest node
                    with grpc.insecure_channel(closest.address + ':' +
                                               str(closest.port)) as channel:
                        stub = csci4220_hw4_pb2_grpc.KadImplStub(channel)

                        stub.Store(
                            csci4220_hw4_pb2.KeyValue(node=servicer.this_node,
                                                      key=key,
                                                      value=value))

                print("Storing key " + str(key) + " at node " +
                      str(closest.id))

            # QUIT command
            if (command[0] == "QUIT"):
                for i in reversed(range(n)):
                    for node in reversed(servicer.k_buckets[i]):
                        with grpc.insecure_channel(node.address + ':' +
                                                   str(node.port)) as channel:
                            stub = csci4220_hw4_pb2_grpc.KadImplStub(channel)

                            print("Letting " + str(node.id) +
                                  " know I'm quitting.")
                            stub.Quit(
                                csci4220_hw4_pb2.IDKey(
                                    node=servicer.this_node,
                                    idkey=servicer.this_node.id))

                print("Shut down node " + str(local_id))
                sys.exit()