示例#1
0
    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
示例#2
0
  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
示例#3
0
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))
示例#4
0
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))