def __init__(self, ring_id=1, id=None, ip='127.0.0.1', port=8080, user_id=None): MessageHandlerNode.__init__(self, ip, port) self.set_timeout(0.25) self.id = id if id != None else random_key() sys.stdout.write('me: %s\n' % key_to_int(self.id)) self.ring_id = ring_id self.user_id = user_id self.contacts = MultiRingChordContacts( Contact(ring_id=ring_id, id=self.id, ip=self.ip, port=self.port, network_protocol=self)) self.messages_received = 0 self.message_limit = None # self.data[string_to_key('physical_key')] = { # 'data': value, # 'version': VectorVersion(), # 'requires': VectorVersionList() # } self.data = {} self.callback_manager = CallbackManager() self.next_finger_to_fix = 1
def __init__(self, ring_id=1, id=None, ip='127.0.0.1', port=8080, user_id=None): MessageHandlerNode.__init__(self, ip, port) self.set_timeout(0.25) self.id = id if id != None else random_key() sys.stdout.write('me: %s\n' % key_to_int(self.id)) self.ring_id = ring_id self.user_id = user_id self.contacts = MultiRingChordContacts(Contact(ring_id=ring_id, id=self.id, ip=self.ip, port=self.port, network_protocol=self)) self.messages_received = 0 self.message_limit = None # self.data[string_to_key('physical_key')] = { # 'data': value, # 'version': VectorVersion(), # 'requires': VectorVersionList() # } self.data = {} self.callback_manager = CallbackManager() self.next_finger_to_fix = 1
class DHTNode(MessageHandlerNode): """ Chord node Messages sent recursively Maintains an in-memory dict of node data Shuffles data when nodes join and leave Provides some consistency through vector version numbers """ def __init__(self, ring_id=1, id=None, ip='127.0.0.1', port=8080, user_id=None): MessageHandlerNode.__init__(self, ip, port) self.set_timeout(0.25) self.id = id if id != None else random_key() sys.stdout.write('me: %s\n' % key_to_int(self.id)) self.ring_id = ring_id self.user_id = user_id self.contacts = MultiRingChordContacts(Contact(ring_id=ring_id, id=self.id, ip=self.ip, port=self.port, network_protocol=self)) self.messages_received = 0 self.message_limit = None # self.data[string_to_key('physical_key')] = { # 'data': value, # 'version': VectorVersion(), # 'requires': VectorVersionList() # } self.data = {} self.callback_manager = CallbackManager() self.next_finger_to_fix = 1 def about_to_receive(self): pass def received_obj(self, ip, port, obj): if not isinstance(obj, DHTNodeMessage): return contact = Contact(ring_id=obj.ring_id, id=obj.id, ip=ip, port=port, network_protocol=self) if hasattr(obj, 'join') and obj.join: # this node is trying to join # don't include it in any finger tables for now pass else: self.add_contact(contact) sys.stdout.write('received %s from %s\n' % (message_to_string(obj), contact)) self.received_msg(contact, obj) def received_msg(self, contact, obj): self.messages_received += 1 if self.message_limit and (self.messages_received >= self.message_limit): sys.stdout.write('reached message limit\n') sys.exit(1) # figure out which function handles this message type handler = DHTNode.get_message_handler(obj) if handler: # invoke handler handler(self, contact, obj) def add_contact(self, contact): self.contacts.add(contact) def remove_contact(self, contact_id): del self.contacts[contact_id] def owns_key(self, key): return keyspace_compare(self.id, self.contacts.get_successor().id, key) # JOIN def join(self, ip, port): dummy_contact = Contact(ring_id=None, id=None, ip=ip, port=port, network_protocol=self) request_id = self.callback_manager.register(self.join_response_callback) dummy_contact.send(JoinMessage(request_id=request_id, join=True)) return request_id @handlesrequest(JoinMessage) def got_join_message(self, contact, obj): if not self.owns_key(contact.id): self.forward( key = contact.id, raw_key = True, message = obj, requester = contact ) return old_successor = self.contacts.get_successor() critical_data = {} for key in self.data: if keyspace_compare(contact.id, old_successor.id, string_to_key(key)): critical_data[key] = self.value_to_wire(self.data[key]) # data shuffle: potentially large message contact.send( JoinResponse( request_id = obj.request_id, successor = old_successor.to_tuple(), data = critical_data ) ) self.contacts.set_successor(contact) @handlesrequest(JoinResponse) def got_join_response(self, contact, obj): for key in obj.data: self.data[key] = self.value_from_wire(obj.data[key]) self.callback_manager.call(obj.request_id, (contact, obj)) self.stabilize() def join_response_callback(self, request_id, (contact, obj)): self.contacts.set_successor(Contact.from_tuple(obj.successor, self)) self.contacts.set_predecessor(contact) sys.stdout.write('joined!\n') sys.stdout.write(' predecessor: %s\n' % key_to_int(self.contacts.get_predecessor().id)) sys.stdout.write(' me: %s\n' % key_to_int(self.id)) sys.stdout.write(' successor: %s\n' % key_to_int(self.contacts.get_successor().id))
class DHTNode(MessageHandlerNode): """ Chord node Messages sent recursively Maintains an in-memory dict of node data Shuffles data when nodes join and leave Provides some consistency through vector version numbers """ def __init__(self, ring_id=1, id=None, ip='127.0.0.1', port=8080, user_id=None): MessageHandlerNode.__init__(self, ip, port) self.set_timeout(0.25) self.id = id if id != None else random_key() sys.stdout.write('me: %s\n' % key_to_int(self.id)) self.ring_id = ring_id self.user_id = user_id self.contacts = MultiRingChordContacts( Contact(ring_id=ring_id, id=self.id, ip=self.ip, port=self.port, network_protocol=self)) self.messages_received = 0 self.message_limit = None # self.data[string_to_key('physical_key')] = { # 'data': value, # 'version': VectorVersion(), # 'requires': VectorVersionList() # } self.data = {} self.callback_manager = CallbackManager() self.next_finger_to_fix = 1 def about_to_receive(self): pass def received_obj(self, ip, port, obj): if not isinstance(obj, DHTNodeMessage): return contact = Contact(ring_id=obj.ring_id, id=obj.id, ip=ip, port=port, network_protocol=self) if hasattr(obj, 'join') and obj.join: # this node is trying to join # don't include it in any finger tables for now pass else: self.add_contact(contact) sys.stdout.write('received %s from %s\n' % (message_to_string(obj), contact)) self.received_msg(contact, obj) def received_msg(self, contact, obj): self.messages_received += 1 if self.message_limit and (self.messages_received >= self.message_limit): sys.stdout.write('reached message limit\n') sys.exit(1) # figure out which function handles this message type handler = DHTNode.get_message_handler(obj) if handler: # invoke handler handler(self, contact, obj) def add_contact(self, contact): self.contacts.add(contact) def remove_contact(self, contact_id): del self.contacts[contact_id] def owns_key(self, key): return keyspace_compare(self.id, self.contacts.get_successor().id, key) # JOIN def join(self, ip, port): dummy_contact = Contact(ring_id=None, id=None, ip=ip, port=port, network_protocol=self) request_id = self.callback_manager.register( self.join_response_callback) dummy_contact.send(JoinMessage(request_id=request_id, join=True)) return request_id @handlesrequest(JoinMessage) def got_join_message(self, contact, obj): if not self.owns_key(contact.id): self.forward(key=contact.id, raw_key=True, message=obj, requester=contact) return old_successor = self.contacts.get_successor() critical_data = {} for key in self.data: if keyspace_compare(contact.id, old_successor.id, string_to_key(key)): critical_data[key] = self.value_to_wire(self.data[key]) # data shuffle: potentially large message contact.send( JoinResponse(request_id=obj.request_id, successor=old_successor.to_tuple(), data=critical_data)) self.contacts.set_successor(contact) @handlesrequest(JoinResponse) def got_join_response(self, contact, obj): for key in obj.data: self.data[key] = self.value_from_wire(obj.data[key]) self.callback_manager.call(obj.request_id, (contact, obj)) self.stabilize() def join_response_callback(self, request_id, (contact, obj)): self.contacts.set_successor(Contact.from_tuple(obj.successor, self)) self.contacts.set_predecessor(contact) sys.stdout.write('joined!\n') sys.stdout.write(' predecessor: %s\n' % key_to_int(self.contacts.get_predecessor().id)) sys.stdout.write(' me: %s\n' % key_to_int(self.id)) sys.stdout.write(' successor: %s\n' % key_to_int(self.contacts.get_successor().id))