async def test_client_locate_request_single_response(alice_and_bob_clients): alice, bob = alice_and_bob_clients async with trio.open_nursery() as nursery: single_location = NodeFactory() async with bob.message_dispatcher.subscribe(Locate) as locate_subscription: async def _handle_locate(): with trio.fail_after(1): message = await locate_subscription.receive() assert isinstance(message.payload, Locate) await bob.send_locations( message.node, request_id=message.payload.request_id, locations=(single_location,), ) nursery.start_soon(_handle_locate) with trio.fail_after(1): messages = await alice.locate(bob.local_node, key=b'key') assert len(messages) == 1 message = messages[0] assert isinstance(message.payload, Locations) payload = message.payload assert payload.total == 1 assert len(payload.nodes) == 1 node = Node.from_payload(payload.nodes[0]) assert node == single_location
async def _handle_advertise_requests(self) -> None: async with self.client.message_dispatcher.subscribe( Advertise) as subscription: while self.manager.is_running: request = await subscription.receive() payload = request.payload await self.client.send_ack(request.node, request_id=payload.request_id) node = Node.from_payload(payload.node) # Queue the content to be ingested by the content manager try: self._inbound_content_send_channel.send_nowait( (node, payload.key)) except trio.WouldBlock: self.logger.error( "Content processing channel is full. Discarding " "advertised content: %s@%s", encode_hex(payload.key), request.node, )
async def single_lookup(self, node: Node, *, distance: int) -> Tuple[Node, ...]: found_nodes = await self.client.find_nodes(node, distance=distance) return tuple( Node.from_payload(node_as_payload) for message in found_nodes for node_as_payload in message.payload.nodes)
async def locate(self, node: Node, *, key: bytes) -> Tuple[Node, ...]: locations = await self.client.locate(node, key=key) return tuple( Node.from_payload(node_payload) for message in locations for node_payload in message.payload.nodes)