def shuffle_partial_view(self): logger.debug("Shuffling", partialView=self.partialView) # 1) Increase by one the age of all neighbors logger.debug("Increase by one the age of all neighbors.") self.partialView.increment() logger.debug("Increment", partialView=self.partialView) # 2) Select neighbor Q with the highest age among all neighbors. logger.debug( "Select neighbor Q with the highest age among all neighbors.") oldest_peer = self.partialView.get_oldest_peer() logger.debug("SelectOldest", oldest_peer=oldest_peer) # 3) Select l - 1 other random neighbors (meaning avoid oldest). logger.debug( "Select l - 1 other random neighbors (meaning avoid oldest).") neighbors = self.partialView.select_neighbors_for_request(oldest_peer) logger.debug("SelectNeighbors", neighbors=neighbors) # 4) Replace Q's entry with a new entry of age 0 and with P's address. logger.debug( "Replace Q's entry with a new entry of age 0 and with P's address." ) neighbors.add_peer_ip(self.ip, allow_self_ip=True) logger.debug("AddMyself", neighbors=neighbors) try: # 5) Send the updated subset to peer Q. logger.debug("Send the updated subset to peer Q (oldest_peer).", oldest_peer=oldest_peer.ip) response = json.loads( self.send_message(oldest_peer.ip, 'exchange-view', neighbors)) received_partial_view = PartialView.from_dict(response.get('data')) logger.debug("Received", received_partial_view=received_partial_view) # 6) I remove the oldest peer from my view logger.debug("I remove the oldest peer from my view.", oldest_peer=oldest_peer.ip) self.partialView.remove_peer(oldest_peer) logger.debug("RemovedOldest", partialView=self.partialView) # 7) I merge my view with the one just received logger.debug("I merge my view with the one just received.") self.partialView.merge(neighbors, received_partial_view) logger.debug("Merged", partialView=self.partialView) except Timeout: logger.error("TimeoutException: Request to " + str(oldest_peer.ip) + " timed out.")
def test_unmarshal_partial_view(self): for ip in self.ips: self.partialView.add_peer_ip(ip) jsonized = self.partialView.to_json() partial_view = PartialView.from_dict(jsonized) self.assertIsInstance(partial_view, PartialView) for peer in partial_view.peer_list: self.assertIsInstance(peer, PodDescriptor) self.assertEqual(partial_view.ip, self.partialView.ip) self.assertEqual(partial_view.size, 3) self.assertEqual(partial_view.limit, 3) for i in range(self.partialView.limit): self.assertEqual(partial_view.peer_list[i].ip, self.descriptors[i].ip) self.assertEqual(partial_view.peer_list[i].age, self.descriptors[i].age)
def exchange_view(request): if request.method == 'POST': logger.info("ExchangeView") logger.debug("ExchangeView", request=request, partialView=cyclon.partialView) # 1) I cast the received json into a PartialView logger.debug( "ExchangeView: I cast the received json into a PartialView.") message = json.loads(request.body) received_partial_view = PartialView.from_dict(message.get('data')) # 2) I send a subset of my partial view no matter if the source ip is contained in it logger.debug( "ExchangeView: I send a subset of my partial view no matter if the source ip is contained in it." ) to_send = cyclon.partialView.select_neighbors_for_reply() # 3) I merge current partial view with the one just received logger.debug( "ExchangeView: I merge current partial view with the one just received." ) cyclon.partialView.merge(to_send, received_partial_view) logger.debug("ExchangeView", partialView=cyclon.partialView) m = Message(format_address(my_ip(), 5000), message.get('source'), to_send) logger.debug("ExchangeView", response=m.to_json(), to=message.get('source')) return JsonResponse(m.to_json()) else: return JsonResponse( {"error": { "message": "Only the POST method is allowed." }}, status=403)