6

I am writing a REST API using aiohttp.

Some of the coroutines need to call the database using the aiomysql library. The documentation for aiomysql has the following example:

import asyncio
import aiomysql

loop = asyncio.get_event_loop()


async def test_example():
    conn = await aiomysql.connect(host='127.0.0.1', port=3306,
                                       user='root', password='', db='mysql',
                                       loop=loop)

    cur = await conn.cursor()
    await cur.execute("SELECT Host,User FROM user")
    print(cur.description)
    r = await cur.fetchall()
    print(r)
    await cur.close()
    conn.close()

loop.run_until_complete(test_example())

My question is concerning the definition of the global variable loop:

loop = asyncio.get_event_loop()

Do I really need to keep loop as a global variable somewhere, or can I just call asyncio.get_event_loop() when I need it?

For example, it the code example above, I could get the event loop when I am connecting to the database:

    conn = await aiomysql.connect(host='127.0.0.1', port=3306,
                                       user='root', password='', db='mysql',
                                       loop=asyncio.get_event_loop())

Is there a non-trivial runtime cost to calling asyncio.get_event_loop() or something else that I am missing?

ostrokach
  • 17,993
  • 11
  • 78
  • 90
  • 1
    `get_event_loop` is thread-dependent. If you call it from a thread that does not have an event loop previously created, it has the potential to _create another_ event loop depending on your event loop policy. You can set this policy with `asyncio.set_event_loop_policy`. Also of note, you can set the event loop for an arbitrary thread using `asyncio.set_event_loop` inside the thread you want to set it for. There is a cost for the first call of `get_event_loop` but other calls in the same thread _should_ (given default policy) be more or less free. – Stephen Nov 10 '20 at 22:43
  • @Stephen thank you for the comment! Could you give an example of when two coroutines would be running in different threads? It was my understanding that, unless I do strange things, every coroutine would be executed by the same thread. – ostrokach Nov 10 '20 at 22:53
  • 1
    your understanding is correct, I was trying to warn you about the possibility of accidentally creating additional event loops. Ideally, you would only ever have one thread and one event loop in your application, but there are (rare) cases where a developer might need more. – Stephen Nov 10 '20 at 23:00

1 Answers1

2

loop argument should go.

aiomysql should be updated to don't accept the loop.

You can just skip loop=... in your code right now because aiomysql.connect() has the default loop=None value for the argument.

In general, asyncio.get_event_loop() will be deprecated; asyncio.get_running_loop() is recommended for the usage from an async code when needed. Passing an explicit loop to asyncio API is deprecated starting from Python 3.8.

Andrew Svetlov
  • 16,730
  • 8
  • 66
  • 69