def _received_store_rpc(self, data_packet): '''Received store RPC''' _logger.debug('Store value %s←%s', self.address, data_packet.address) dict_obj = data_packet.dict_obj # FIXME: validation key = KeyBytes(dict_obj[JSONKeys.KEY]) index = KeyBytes(dict_obj[JSONKeys.INDEX]) size = int(dict_obj[JSONKeys.SIZE]) timestamp = int(dict_obj[JSONKeys.TIMESTAMP]) d = self._template_dict() kvpid = KVPID(key, index) if self._kvp_table.is_acceptable(kvpid, size, timestamp): transfer_id = self._network.new_sequence_id() download_task = self._download_slot.add( self._network.expect_incoming_transfer, transfer_id, max_size=DHTNetwork.MAX_VALUE_SIZE, download_task_class=ReadStoreFromNodeTask) download_task.key = kvpid.key download_task.index = kvpid.index download_task.total_size = size d[JSONKeys.TRANSFER_ID] = transfer_id self._network.send_answer_reply(data_packet, d) _logger.debug('Store value %s←%s begin read', self.address, data_packet.address) file = download_task.result() _logger.debug('Store value %s←%s received data', self.address, data_packet.address) data = file.read() if index.validate_value(data): self._kvp_table[kvpid] = data kvp_record = self._kvp_table.record(kvpid) kvp_record.timestamp = timestamp kvp_record.last_update = time.time() kvp_record.time_to_live = self._calculate_expiration_time(key) else: self._network.send_answer_reply(data_packet, d)
def __setitem__(self, kvpid, value): assert isinstance(kvpid, KVPID) assert isinstance(value, bytes) assert KeyBytes.validate_hash_value(kvpid.index, value) result = self._setitem(kvpid, value) self._value_changed_observer(kvpid) return result
def _received_find_value_rpc(self, data_packet): '''Find value rpc callback''' _logger.debug('Find value %s←%s', self.address, data_packet.address) key = KeyBytes.new_silent(data_packet.dict_obj.get(JSONKeys.KEY, 'fake')) index = KeyBytes.new_silent(data_packet.dict_obj.get(JSONKeys.INDEX)) if not key: _logger.debug('Find value %s←%s bad key', self.address, data_packet.address) return _logger.debug('Find value %s←%s k=%s i=%s', self.address, data_packet.address, key, index) kvpid = KVPID(key, index) if index and kvpid in self._kvp_table: kvp_record = self._kvp_table.record(kvpid) d = self._template_dict() d[JSONKeys.VALUES] = KVPExchangeInfoList([ KVPExchangeInfo.from_kvp_record(kvp_record) ]).to_json_dumpable() self._network.send_answer_reply(data_packet, d) elif self._kvp_table.indices(key): kvp_record_list = self._kvp_table.records_by_key(key) d = self._template_dict() d[JSONKeys.VALUES] = KVPExchangeInfoList.from_kvp_record_list( kvp_record_list).to_json_dumpable() self._network.send_answer_reply(data_packet, d) else: self._reply_find_node(data_packet, key)
def _received_find_node_rpc(self, data_packet): '''Find node RPC callback''' _logger.debug('Find node %s←%s', self.address, data_packet.address) key_obj = KeyBytes.new_silent(data_packet.dict_obj.get(JSONKeys.KEY)) if not key_obj: _logger.debug('Find node %s←%s bad key', self.address, data_packet.address) return self._reply_find_node(data_packet, key_obj)
def _received_get_value_rpc(self, data_packet): '''Get value rpc calllback''' _logger.debug('Get value %s←%s', self.address, data_packet.address) self._update_routing_table_from_data_packet(data_packet) key = KeyBytes.new_silent(data_packet.dict_obj[JSONKeys.KEY]) index = KeyBytes.new_silent(data_packet.dict_obj[JSONKeys.INDEX]) transfer_id = data_packet.dict_obj.get(JSONKeys.TRANSFER_ID) if not transfer_id: _logger.debug('Missing transfer id') return try: offset = data_packet.dict_obj.get(JSONKeys.VALUE_OFFSET, 0) except TypeError as e: _logger.debug('Offset parse error %s', e) return kvpid = KVPID(key, index) if not kvpid in self._kvp_table: _logger.debug('KeyBytes not in cache') return data = self._kvp_table[kvpid] task = self._network.send_bytes(data_packet.address, transfer_id, data[offset:]) bytes_sent = task.result() _logger.debug('Sent %d bytes', bytes_sent)
def table_store_get(self, data, kvp_table): kvpid = KVPID(KeyBytes(), KeyBytes.new_hash(data)) self.assertFalse(kvpid in kvp_table) kvp_table[kvpid] = data self.assertTrue(kvpid in kvp_table) self.assertTrue(kvp_table.indices(kvpid.key)) record = kvp_table.record(kvpid) self.assertEqual(len(data), record.size) del kvp_table[kvpid] self.assertFalse(kvpid in kvp_table)