Python trio.TooSlowError() Examples

The following are 16 code examples of trio.TooSlowError(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module trio , or try the search function .
Example #1
Source File: trio-server.py    From h11 with MIT License 6 votes vote down vote up
def maybe_send_error_response(wrapper, exc):
    # If we can't send an error, oh well, nothing to be done
    wrapper.info("trying to send error response...")
    if wrapper.conn.our_state not in {h11.IDLE, h11.SEND_RESPONSE}:
        wrapper.info("...but I can't, because our state is",
                     wrapper.conn.our_state)
        return
    try:
        if isinstance(exc, h11.RemoteProtocolError):
            status_code = exc.error_status_hint
        elif isinstance(exc, trio.TooSlowError):
            status_code = 408  # Request Timeout
        else:
            status_code = 500
        body = str(exc).encode("utf-8")
        await send_simple_response(wrapper,
                                   status_code,
                                   "text/plain; charset=utf-8",
                                   body)
    except Exception as exc:
        wrapper.info("error while sending error response:", exc) 
Example #2
Source File: util.py    From douyin_downloader with GNU Lesser General Public License v3.0 6 votes vote down vote up
def download_file(self, url, headers=IPHONE_HEADER, timeout=DOWNLOAD_TIMEOUT, res_time=RETRIES_TIMES):
        if res_time <= 0: # 重试超过了次数
            return None
        try:
            _url = random.choice(url) if isinstance(url, list) else url
            res = await asks.get(_url, headers=headers, timeout=timeout, retries=3)
        except (socket.gaierror, trio.BrokenResourceError, trio.TooSlowError, asks.errors.RequestTimeout) as e:
            logging.error("download from %s fail]err=%s!" % (url, e))
            await trio.sleep(random.randint(1, 5)) # for scheduler
            return await self.download_file(url, res_time=res_time-1)

        if res.status_code not in [200, 202]:
            logging.warn(f"download from {url} fail]response={res}")
            await trio.sleep(random.randint(3, 10))
            return await self.download_file(url, res_time=res_time-1)
        return res.content 
Example #3
Source File: server.py    From linehaul with Apache License 2.0 5 votes vote down vote up
def send_batch(
    bq,
    table,
    template_suffix,
    batch,
    *args,
    retry_max_attempts=None,
    retry_max_wait=None,
    retry_multiplier=None,
    **kwargs
):
    if retry_max_attempts is None:
        retry_max_attempts = 10
    if retry_max_wait is None:
        retry_max_wait = 60
    if retry_multiplier is None:
        retry_multiplier = 0.5

    # We split up send_batch and actually_send_batch so that we can use tenacity to
    # handle retries for us, while still getting to use the Nurser.start_soon interface.
    # This also makes it easier to deal with the error handling aspects of sending a
    # batch, from the work of actually sending. The general rule here is that errors
    # shoudl not escape from this function.

    send = actually_send_batch.retry_with(
        wait=tenacity.wait_exponential(multiplier=retry_multiplier, max=retry_max_wait),
        stop=tenacity.stop_after_attempt(retry_max_attempts),
    )

    try:
        await send(bq, table, template_suffix, batch, *args, **kwargs)
    # We've tried to send this batch to BigQuery, however for one reason or another
    # we were unable to do so. We should log this error, but otherwise we're going
    # to just drop this on the floor because there's not much else we can do here
    # except buffer it forever (which is not a great idea).
    except trio.TooSlowError:
        logger.error("Timed out sending %d items; Dropping them.", len(batch))
    except Exception:
        logger.exception("Error sending %d items; Dropping them.", len(batch)) 
Example #4
Source File: test_aio.py    From pynng with MIT License 5 votes vote down vote up
def test_arecv_trio_cancel():
    with pynng.Pair0(listen=addr, recv_timeout=5000) as p0:
        with pytest.raises(trio.TooSlowError):
            with trio.fail_after(0.001):
                await p0.arecv() 
Example #5
Source File: tcp_server.py    From hypercorn with MIT License 5 votes vote down vote up
def run(self) -> None:
        try:
            try:
                with trio.fail_after(self.config.ssl_handshake_timeout):
                    await self.stream.do_handshake()
            except (trio.BrokenResourceError, trio.TooSlowError):
                return  # Handshake failed
            alpn_protocol = self.stream.selected_alpn_protocol()
            socket = self.stream.transport_stream.socket
            ssl = True
        except AttributeError:  # Not SSL
            alpn_protocol = "http/1.1"
            socket = self.stream.socket
            ssl = False

        try:
            client = parse_socket_addr(socket.family, socket.getpeername())
            server = parse_socket_addr(socket.family, socket.getsockname())

            async with trio.open_nursery() as nursery:
                self.nursery = nursery
                context = Context(nursery)
                self.protocol = ProtocolWrapper(
                    self.app,
                    self.config,
                    context,
                    ssl,
                    client,
                    server,
                    self.protocol_send,
                    alpn_protocol,
                )
                await self.protocol.initiate()
                await self._update_keep_alive_timeout()
                await self._read_data()
        except (trio.MultiError, OSError):
            pass
        finally:
            await self._close() 
Example #6
Source File: lifespan.py    From hypercorn with MIT License 5 votes vote down vote up
def wait_for_startup(self) -> None:
        if not self.supported:
            return

        await self.app_send_channel.send({"type": "lifespan.startup"})
        try:
            with trio.fail_after(self.config.startup_timeout):
                await self.startup.wait()
        except trio.TooSlowError as error:
            raise LifespanTimeout("startup") from error 
Example #7
Source File: lifespan.py    From hypercorn with MIT License 5 votes vote down vote up
def wait_for_shutdown(self) -> None:
        if not self.supported:
            return

        await self.app_send_channel.send({"type": "lifespan.shutdown"})
        try:
            with trio.fail_after(self.config.shutdown_timeout):
                await self.shutdown.wait()
        except trio.TooSlowError as error:
            raise LifespanTimeout("startup") from error 
Example #8
Source File: __init__.py    From starbelly with MIT License 5 votes vote down vote up
def assert_max_elapsed(seconds):
    '''
    Fail the test if the execution of a block takes longer than ``seconds``.
    '''
    try:
        with trio.fail_after(seconds):
            yield
    except trio.TooSlowError:
        pytest.fail('Failed to complete within {} seconds'.format(seconds)) 
Example #9
Source File: engine.py    From lahja with MIT License 5 votes vote down vote up
def run_with_timeout(
        self, coro: Callable[..., Awaitable[Any]], *args: Any, timeout: int
    ) -> None:
        try:
            with trio.fail_after(timeout):
                await coro(*args)
        except trio.TooSlowError as err:
            raise TimeoutError from err 
Example #10
Source File: trio_utils.py    From trinity with MIT License 5 votes vote down vote up
def maybe_send_error_response(wrapper: TrioHTTPWrapper, exc: Exception) -> None:
    # If we can't send an error, oh well, nothing to be done
    if wrapper.conn.our_state not in {h11.IDLE, h11.SEND_RESPONSE}:
        return
    try:
        if isinstance(exc, h11.RemoteProtocolError):
            status_code = exc.error_status_hint
        elif isinstance(exc, trio.TooSlowError):
            status_code = 408  # Request Timeout
        elif isinstance(exc, ResourceNotFoundException):
            await send_simple_response(
                wrapper,
                exc.error_status_hint,
                "text/html; charset=UTF-8",
                b"Resource not found",
            )
            return
        elif isinstance(exc, MethodNotAllowedException):
            await send_simple_response(
                wrapper,
                exc.error_status_hint,
                "text/html; charset=UTF-8",
                b"",
                (("Allow", "GET, POST"),),
            )
            return
        else:
            status_code = 500
        body = str(exc).encode("utf-8")
        await send_simple_response(
            wrapper, status_code, "text/plain; charset=utf-8", body
        )
    except Exception as exc:
        wrapper.info("error while sending error response:", exc) 
Example #11
Source File: discovery.py    From trinity with MIT License 5 votes vote down vote up
def request_enr(self, remote: NodeAPI) -> ENR:
        """Get the most recent ENR for the given node and update our local DB and routing table.

        The updating of the DB and RT happens in the handler called when we receive an ENR
        response, so that the new ENR is stored even if we give up waiting.

        Raises CouldNotRetrieveENR if we can't get a ENR from the remote node.
        """
        # No need to use a timeout because bond() takes care of that internally.
        await self.bond(remote.id)
        token = self.send_enr_request(remote)
        send_chan, recv_chan = trio.open_memory_channel[Tuple[ENR, Hash32]](1)
        try:
            with trio.fail_after(constants.KADEMLIA_REQUEST_TIMEOUT):
                enr, received_token = await self.enr_response_channels.receive_one(
                    remote, send_chan, recv_chan)
        except trio.TooSlowError:
            raise CouldNotRetrieveENR(f"Timed out waiting for ENR from {remote}")
        except AlreadyWaitingDiscoveryResponse:
            raise CouldNotRetrieveENR(f"Already waiting for ENR from {remote}")

        if received_token != token:
            raise CouldNotRetrieveENR(
                f"Got ENR from {remote} with token {received_token!r} but expected {token!r}")

        return enr 
Example #12
Source File: packer.py    From trinity with MIT License 5 votes vote down vote up
def check_handshake_timeout(self, handshake_successful_event: trio.Event) -> None:
        try:
            with trio.fail_after(HANDSHAKE_TIMEOUT):
                # Only the timeout for successful handshakes has to be checked as a failure during
                # handshake will make the service as a whole fail.
                await handshake_successful_event.wait()
        except trio.TooSlowError as too_slow_error:
            self.logger.warning("Handshake with %s has timed out", encode_hex(self.remote_node_id))
            raise HandshakeFailure("Handshake has timed out") from too_slow_error

    #
    # Handshake states
    # 
Example #13
Source File: _impl.py    From trio-websocket with MIT License 4 votes vote down vote up
def open_websocket(host, port, resource, *, use_ssl, subprotocols=None,
    extra_headers=None,
    message_queue_size=MESSAGE_QUEUE_SIZE, max_message_size=MAX_MESSAGE_SIZE,
    connect_timeout=CONN_TIMEOUT, disconnect_timeout=CONN_TIMEOUT):
    '''
    Open a WebSocket client connection to a host.

    This async context manager connects when entering the context manager and
    disconnects when exiting. It yields a
    :class:`WebSocketConnection` instance.

    :param str host: The host to connect to.
    :param int port: The port to connect to.
    :param str resource: The resource, i.e. URL path.
    :param use_ssl: If this is an SSL context, then use that context. If this is
        ``True`` then use default SSL context. If this is ``False`` then disable
        SSL.
    :type use_ssl: bool or ssl.SSLContext
    :param subprotocols: An iterable of strings representing preferred
        subprotocols.
    :param list[tuple[bytes,bytes]] extra_headers: A list of 2-tuples containing
        HTTP header key/value pairs to send with the connection request. Note
        that headers used by the WebSocket protocol (e.g.
        ``Sec-WebSocket-Accept``) will be overwritten.
    :param int message_queue_size: The maximum number of messages that will be
        buffered in the library's internal message queue.
    :param int max_message_size: The maximum message size as measured by
        ``len()``. If a message is received that is larger than this size,
        then the connection is closed with code 1009 (Message Too Big).
    :param float connect_timeout: The number of seconds to wait for the
        connection before timing out.
    :param float disconnect_timeout: The number of seconds to wait when closing
        the connection before timing out.
    :raises HandshakeError: for any networking error,
        client-side timeout (:exc:`ConnectionTimeout`, :exc:`DisconnectionTimeout`),
        or server rejection (:exc:`ConnectionRejected`) during handshakes.
    '''
    async with trio.open_nursery() as new_nursery:
        try:
            with trio.fail_after(connect_timeout):
                connection = await connect_websocket(new_nursery, host, port,
                    resource, use_ssl=use_ssl, subprotocols=subprotocols,
                    extra_headers=extra_headers,
                    message_queue_size=message_queue_size,
                    max_message_size=max_message_size)
        except trio.TooSlowError:
            raise ConnectionTimeout from None
        except OSError as e:
            raise HandshakeError from e
        try:
            await yield_(connection)
        finally:
            try:
                with trio.fail_after(disconnect_timeout):
                    await connection.aclose()
            except trio.TooSlowError:
                raise DisconnectionTimeout from None 
Example #14
Source File: discovery.py    From trinity with MIT License 4 votes vote down vote up
def bond(self, node_id: NodeID) -> bool:
        """Bond with the given node.

        Bonding consists of pinging the node, waiting for a pong and maybe a ping as well.

        It is necessary to do this at least once before we send find_node requests to a node.

        If we already have a valid bond with the given node we return immediately.
        """
        if node_id == self.this_node.id:
            # FIXME: We should be able to get rid of this check, but for now issue a warning.
            self.logger.warning("Attempted to bond with self; this shouldn't happen")
            return False

        try:
            node = Node(self.node_db.get_enr(node_id))
        except KeyError:
            self.logger.exception("Attempted to bond with node that doesn't exist in our DB")
            return False

        self.logger.debug2("Starting bond process with %s", node)
        if self.is_bond_valid_with(node_id):
            self.logger.debug("Bond with %s is still valid, not doing it again", node)
            return True

        token = await self.send_ping_v4(node)
        send_chan, recv_chan = trio.open_memory_channel[Tuple[Hash32, int]](1)
        try:
            with trio.fail_after(constants.KADEMLIA_REQUEST_TIMEOUT):
                received_token, enr_seq = await self.pong_channels.receive_one(
                    node, send_chan, recv_chan)
        except AlreadyWaitingDiscoveryResponse:
            self.logger.debug("Bonding failed, already waiting pong from %s", node)
            return False
        except trio.TooSlowError:
            self.logger.debug("Bonding with %s timed out", node)
            return False

        if received_token != token:
            self.logger.info(
                "Bonding with %s failed, expected pong with token %s, but got %s",
                node, token, received_token)
            self.routing.remove(node.id)
            return False

        ping_send_chan, ping_recv_chan = trio.open_memory_channel[None](1)
        try:
            # Give the remote node a chance to ping us before we move on and
            # start sending find_node requests. It is ok for us to timeout
            # here as that just means the remote remembers us -- that's why we use
            # move_on_after() instead of fail_after().
            with trio.move_on_after(constants.KADEMLIA_REQUEST_TIMEOUT):
                await self.ping_channels.receive_one(node, ping_send_chan, ping_recv_chan)
        except AlreadyWaitingDiscoveryResponse:
            self.logger.debug("bonding failed, already waiting for ping")
            return False

        self.logger.debug("bonding completed successfully with %s", node)
        if enr_seq is not None:
            self.schedule_enr_retrieval(node.id, enr_seq)
        return True 
Example #15
Source File: routing_table_manager.py    From trinity with MIT License 4 votes vote down vote up
def request_remote_enr(self, incoming_message: IncomingMessage) -> None:
        """Request the ENR of the sender of an incoming message and store it in the ENR db."""
        self.logger.debug("Requesting ENR from %s", encode_hex(incoming_message.sender_node_id))

        find_nodes_message = FindNodeMessage(
            request_id=self.message_dispatcher.get_free_request_id(incoming_message.sender_node_id),
            distance=0,  # request enr of the peer directly
        )
        try:
            with trio.fail_after(REQUEST_RESPONSE_TIMEOUT):
                response = await self.message_dispatcher.request(
                    incoming_message.sender_node_id,
                    find_nodes_message,
                    endpoint=incoming_message.sender_endpoint,
                )
        except trio.TooSlowError:
            self.logger.warning(
                "FindNode request to %s has timed out",
                encode_hex(incoming_message.sender_node_id),
            )
            return

        sender_node_id = response.sender_node_id
        self.update_routing_table(sender_node_id)

        if not isinstance(response.message, NodesMessage):
            self.logger.warning(
                "Peer %s responded to FindNode with %s instead of Nodes message",
                encode_hex(sender_node_id),
                response.message.__class__.__name__,
            )
            return
        self.logger.debug("Received Nodes message from %s", encode_hex(sender_node_id))

        if len(response.message.enrs) == 0:
            self.logger.warning(
                "Peer %s responded to FindNode with an empty Nodes message",
                encode_hex(sender_node_id),
            )
        elif len(response.message.enrs) > 1:
            self.logger.warning(
                "Peer %s responded to FindNode with more than one ENR",
                encode_hex(incoming_message.sender_node_id),
            )

        for enr in response.message.enrs:
            if enr.node_id != sender_node_id:
                self.logger.warning(
                    "Peer %s responded to FindNode with ENR from %s",
                    encode_hex(sender_node_id),
                    encode_hex(response.message.enrs[0].node_id),
                )
            self.node_db.set_enr(enr) 
Example #16
Source File: routing_table_manager.py    From trinity with MIT License 4 votes vote down vote up
def request_nodes(self,
                            peer: NodeID,
                            target: NodeID,
                            distance: int,
                            ) -> Optional[Tuple[ENR, ...]]:
        """Send a FindNode request to the given peer and return the ENRs in the response.

        If the peer does not respond or fails to respond properly, `None` is returned
        indicating that retrying with a larger distance is futile.
        """
        request = FindNodeMessage(
            request_id=self.message_dispatcher.get_free_request_id(peer),
            distance=distance,
        )
        try:
            with trio.fail_after(FIND_NODE_RESPONSE_TIMEOUT):
                incoming_messages = await self.message_dispatcher.request_nodes(peer, request)
        except ValueError as value_error:
            self.logger.warning(
                f"Failed to send FindNode to %s: %s",
                encode_hex(peer),
                value_error,
            )
            return None
        except UnexpectedMessage as unexpected_message_error:
            self.logger.warning(
                f"Peer %s sent unexpected message to FindNode request: %s",
                encode_hex(peer),
                unexpected_message_error,
            )
            return None
        except trio.TooSlowError:
            self.logger.warning(
                "Peer %s did not respond in time to FindNode request",
                encode_hex(peer),
            )
            return None
        else:
            self.update_routing_table(peer)
            enrs = tuple(
                enr
                for incoming_message in incoming_messages
                for enr in incoming_message.message.enrs
            )
            return enrs