def download(self, filename, path): # step1: Client contacts tracker with the filename it wants to obtain, tracker returns hashed_value_of_file, # as well as a node in Chord (as the entrance of Chord) with grpc.insecure_channel(self.tracker_addr) as channel: stub = p2p_service_pb2_grpc.P2PStub(channel) request = p2p_service_pb2.LookUpFileRequest(filename=filename) try: response = stub.rpc_look_up_file(request, timeout=20) except Exception: print("RPC failed from download() position 1") return if response.result == -1: print('Failed while looking up file on tracker') return elif response.result == -2: print('File not found') return hashed_value_of_file = response.hashed_value_of_file self.entrance_addr = response.entrance_addr # step2: Client contacts the entrance, get a list of fileholder_addr result, addr_list = self.get(hashed_value_of_file=hashed_value_of_file) # response: {int32 result: -1 for failed, 0 for succeeded; repeated Address addr_list} if result == -1: print('Failed while getting fileholder\'s addresses from Chord') return print(addr_list) # Client picks one addr randomly and contacts it to download. # This client can also register in Chord as a fileholder download_addr = random.choice(addr_list) print('Chosen address of peer node: {}'.format(download_addr)) with grpc.insecure_channel(download_addr) as channel: stub = p2p_service_pb2_grpc.P2PStub(channel) request = p2p_service_pb2.DownloadRequest( hashed_value_of_file=hashed_value_of_file) try: response = stub.rpc_download(request, timeout=20) # response: {int32 result: -1 for file not found, 0 for succeeded; string file} except Exception as e: print("RPC failed from download() position 2") print(e) return if response.result == -1: print('File not found') return file = response.file # write the file into local file try: with open(path + filename, 'wb') as f: f.write(file) except Exception as e: print('Failed while storing the downloaded file to local') return print('Download succeeded!')
def remove_chord_node_from_tracker(self, remove_addr): with grpc.insecure_channel(self.tracker_addr) as channel: stub = p2p_service_pb2_grpc.P2PStub(channel) request = p2p_service_pb2.RemoveChordNodeRequest(addr=remove_addr) # current successor is the leaved node try: response = stub.rpc_remove_chord_node(request) if response.result == -1: print('[notify tracker remove node failed] nodeId{} remove_chord_node_from_tracker removed nodeId{} failed'.format(self.id, self.successor[0])) except Exception: self.logger.error("Node#{} rpc error when remove node{} from tracker".format(self.id, self.successor[0]))
def add_chord_node_to_tracker(self, add_addr): with grpc.insecure_channel(self.tracker_addr) as channel: stub = p2p_service_pb2_grpc.P2PStub(channel) request = p2p_service_pb2.AddChordNodeRequest(addr=add_addr) try: response = stub.rpc_add_chord_node(request) if response.result == -1: print('[notify tracker add node failed] nodeId{} add_chord_node_to_tracker new nodeId{} failed'.format(self.id, self.successor[0])) except Exception: self.logger.error("Node#{} rpc error when add node{} to tracker".format(self.id, self.successor[0]))
def show_debug_info(self): with grpc.insecure_channel(self.tracker_addr) as channel: stub = p2p_service_pb2_grpc.P2PStub(channel) request = p2p_service_pb2.GetDebugRequest() try: response = stub.rpc_get_debug(request, timeout=20) except Exception: print("RPC failed from show_debug_info()") return print(response.debug_info)
def check_and_fill_entrance(self): if self.entrance_addr: return with grpc.insecure_channel(self.tracker_addr) as channel: stub = p2p_service_pb2_grpc.P2PStub(channel) request = p2p_service_pb2.GetEntranceRequest() try: response = stub.rpc_get_entrance(request, timeout=20) except Exception: print("RPC failed from check_and_fill_entrance()") return -1, list() self.entrance_addr = response.entrance_addr
def upload(self, filename): try: with open(filename, 'rb') as f: lines = f.readlines() except Exception as e: print('Cannot open file') return file = b'' for line in lines: file += line hashed_value_of_file = utils.sha1(file) # step 1: Register (filename, hashed_value_of_file) at tracker with grpc.insecure_channel(self.tracker_addr) as channel: stub = p2p_service_pb2_grpc.P2PStub(channel) request = p2p_service_pb2.RegisterFileRequest( filename=filename, hashed_value_of_file=hashed_value_of_file) try: response = stub.rpc_register_file(request, timeout=20) except Exception: print("RPC failed") return if response.result == -1: print('Failed while registering to tracker') return # step2: Tracker gives fileholder the addr of a node in Chord (as the entrance of Chord) # this is piggybacked in the return of RPC register_file self.entrance_addr = response.entrance_addr # step3: Fileholder put(hashed_value_of_file, fileholder_addr) to Chord result = self.put(hashed_value_of_file=hashed_value_of_file, fileholder_addr=self.addr) # response: {int32 result: -1 for failed, 0 for succeeded;} if result == -1: print('Failed while putting local address to Chord') return # store this file into local memory storage global local_files local_files[hashed_value_of_file] = file if not self.file_server: # start file server server = threading.Thread(target=start_file_server, args=(self.addr, )) server.start() print('Upload succeeded!')