Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docs/_newsfragments/2585.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Documented that exiting the context manager returned by
:meth:`~falcon.testing.ASGIConductor.simulate_ws` awaits completion of the
background task running the simulated ASGI request. If the
``on_websocket`` responder never returns (for example, an infinite loop
that does not break out when the connection is closed), this await will
hang indefinitely, regardless of any ``timeout`` passed to
:meth:`~falcon.testing.ASGIWebSocketSimulator.wait_ready`.
13 changes: 13 additions & 0 deletions falcon/testing/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1219,10 +1219,23 @@ def simulate_ws(self, path: str = '/', **kwargs: Any) -> _WSContextManager:

This method returns an async context manager that can be used to obtain
a managed :class:`falcon.testing.ASGIWebSocketSimulator` instance.

Exiting the context will simulate a close on the WebSocket (if not
already closed) and await the completion of the task that is
running the simulated ASGI request.

.. warning::
If your ``on_websocket`` responder does not return (for example,
it runs an infinite loop without ever breaking out on
disconnect), exiting this context manager will hang
indefinitely while awaiting that task, regardless of any
``timeout`` passed to
:meth:`~falcon.testing.ASGIWebSocketSimulator.wait_ready`.
Ensure your responder returns promptly after the client
disconnects, or explicitly break out of any long-running
loops when :attr:`~falcon.testing.ASGIWebSocketSimulator.closed`
becomes ``True``.

In the following example, a series of WebSocket TEXT events are
received from the ASGI app::

Expand Down
Loading