Skip to content

Commit

Permalink
Add FAQ section for demonstrating sending data from different tasks t…
Browse files Browse the repository at this point in the history
…hrough the same websocket
  • Loading branch information
asvetlov committed Jul 24, 2016
1 parent 1c50f9b commit 8d9ee8b
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
48 changes: 48 additions & 0 deletions docs/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,51 @@ Just put data inside *request*::
See https://github.com/aio-libs/aiohttp_session code for inspiration,
``aiohttp_session.get_session(request)`` method uses ``SESSION_KEY``
for saving request specific session info.


.. _aiohttp_faq_parallel_event_sources:

How to receive an incoming events from different sources in parallel?
---------------------------------------------------------------------

For example we have two event sources:

1. WebSocket for event from end user

2. Redis PubSub from receiving events from other parts of app for
sending them to user via websocket.

The most native way to perform it is creation of separate task for
pubsub handling.

Parallel :meth:`aiohttp.web.WebSocketResponse.receive` calls are forbidden, only
the single task should perform websocket reading.

But other tasks may use the same websocket object for sending data to
peer::

async def handler(request):

ws = web.WebSocketResponse()
await ws.prepare(request)
task = request.app.loop.create_task(
read_subscription(ws,
request.app['redis']))
try:
async for msg in ws:
# handle incoming messages
# use ws.send_str() to send data back
...

finally:
task.cancel()

async def read_subscriptions(ws, redis):
channel, = await redis.subscribe('channel:1')

try:
async for msg in channel.iter():
answer = process message(msg)
ws.send_str(answer)
finally:
await redis.unsubscribe('channel:1')
10 changes: 10 additions & 0 deletions docs/web.rst
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,16 @@ incoming request.
.. _SockJS: https://github.com/aio-libs/sockjs


.. warning::

Parallel reads from websocket are forbidden, there is no
possibility to call :meth:`aiohttp.web.WebSocketResponse.receive`
from two tasks.

See :ref:`FAQ section <aiohttp_faq_parallel_event_sources>` for
instructions how to solve the problem.


.. _aiohttp-web-exceptions:

Exceptions
Expand Down

0 comments on commit 8d9ee8b

Please sign in to comment.