I'm using uvloop
with websockets
as
import uvloop
coro = websockets.serve(handler, host, port) # creates new server
loop = uvloop.new_event_loop()
loop.create_task(coro)
loop.run_forever()
It works fine, I'm just wondering whether I could run to some unexpected problems without setting the global asyncio
policy to uvloop
. As far as I understand, not setting the global policy should work as long as nothing down there doesn't use the global asyncio
methods, but works with the passed-down event loop directly. Is that correct?
There are three main global objects in asyncio:
All the attempts to get the current context in asyncio go through a single function, asyncio.get_event_loop.
One thing to remember is that since Python 3.6 (and Python 3.5.3+),
get_event_loop
has a specific behavior:Example 1:
Here the policy is the uvloop policy. The loop returned by
get_event_loop
is a uvloop, and it is set as the default loop for this thread. When this loop is running, it is registered as the running loop.In this example, calling
get_event_loop()
anywhere in this thread returns the right loop.Example 2:
Here the policy is still the default policy. The loop returned by
new_event_loop
is a uvloop, and it is set as the default loop for this thread explicitly usingasyncio.set_event_loop
. When this loop is running, it is registered as the running loop.In this example, calling
get_event_loop()
anywhere in this thread returns the right loop.Example 3:
Here the policy is still the default policy. The loop returned by
new_event_loop
is a uvloop, but it is not set as the default loop for this thread. When this loop is running, it is registered as the running loop.In this example, calling
get_event_loop()
within a coroutine returns the right loop (the running uvloop). But callingget_event_loop()
outside a coroutine will result in a new standard asyncio loop, set as the default loop for this thread.So the first two approaches are fine, but the third one is discouraged.