Ejemplo n.º 1
0
    def sorted_nodes(self):
        '''The nodes sorted by distance.

        The first node is the closest.

        :rtype: ``list``
        '''

        node_list = NodeList(self._nodes)
        node_list.sort_distance(self._key_obj)

        return node_list
Ejemplo n.º 2
0
    def run(self, controller, key, index):
        kvpid = KVPID(key, index)
        kvp_record = controller._kvp_table.record(kvpid)

        task = controller.find_value_shortlist(key, index)

        self.hook_task(task)

        shortlist = task.result()

        node_list = NodeList(list(shortlist.nodes - shortlist.useful_nodes))
        node_list.sort_distance(controller.key)

        nodes = collections.deque(node_list)
        kvp_record.last_update = time.time()

        _logger.debug('Uploading value %s', kvpid)

        store_count = 0

        if not nodes and not shortlist.useful_nodes:
            _logger.warning('No destination nodes for publication')
            _logger.debug('%s', controller._routing_table)

        while len(nodes):
            tasks = []
            for dummy in range(DHTNetwork.NETWORK_PARALLELISM):
                try:
                    node = nodes.popleft()
                except IndexError:
                    break

                value = controller._kvp_table[kvpid]

                task = controller.store_to_node(node, key, index, value,
                    kvp_record.timestamp)

                self.hook_task(task)
                self._store_to_node_task_observer(True, task)

                tasks.append(task)

            for task in tasks:
                bytes_sent = task.result()
                self._store_to_node_task_observer(False, task)

                if bytes_sent:
                    store_count += 1

        return store_count
Ejemplo n.º 3
0
class GetValueTask(Task):
    '''Returns the ``bytes``'''

    def run(self, controller, key, index):
        _logger.info('Downloading %s:%s', key.base16, index.base16)
        self._controller = controller
        self._key = key
        self._index = index
        find_value_task = controller.find_value_shortlist(key, index)

        self.hook_task(find_value_task)

        self._shortlist = find_value_task.result()
        self._useful_node_list = NodeList(self._shortlist.useful_nodes)

        if not self._useful_node_list:
            return None

        self._useful_node_list.sort_distance(key)
        self._kvp_exchange_info = self._shortlist.get_common_kvp_exchange_info(
            key, index)

        for dummy in range(3):
            self._file = io.BytesIO()

            if self._download_round():
                break
            else:
                self._file = None

            if self.is_running:
                return

        if self.file:
            self._replicate_value()

            return self._file.value()

    def _download_round(self):
        _logger.debug('Download round')

        for node in self._useful_node_list:
            download_task = self._controller.get_value_from_node(node,
                self._key, self._index, offset=self._file.tell())

            self.hook_task(download_task)

            transfered_file = download_task.result()
            data = transfered_file.read()

            self._file.write(data)

            if self._file.tell() >= self._data_size:
                break

        return self._index.validate_value(data)

    def _replicate_value(self):
        node_list = self._shortlist.sorted_nodes

        if node_list:
            node = node_list[0]

            if node not in self._shortlist.useful_nodes:
                _logger.debug('Replicating value')

                self._controller.store_to_node(node, self._key, self._index,
                    self._file.value(), self._kvp_exchange_info.timestamp)