InfoLearner
InfoLearner

Reputation: 15598

When to use asyncio.get_running_loop() vs asyncio.get_event_loop()?

I have seen running a blocking code using

loop = asyncio.get_running_loop()
await loop.run_in_executor(None, blockingfunc)

And

loop = asyncio.get_event_loop()
await loop.run_in_executor(None, blockingfunc)

When should we use asyncio.get_running_loop() vs asyncio.get_event_loop()?

Upvotes: 21

Views: 25403

Answers (3)

AmericanJael
AmericanJael

Reputation: 141

According to the asyncio documentation, get_event_loop is deprecated since 3.12. The get_running_loop function is recommended because it has a more predictable output. However, get_running_loop only works if there is a running loop, and must be called from a coroutine or a callback.

Upvotes: 1

asyncio.get_event_loop() has the caracteristics of asyncio.get_running_loop(), asyncio.new_event_loop() and asyncio.set_event_loop().

asyncio.get_event_loop() deprecated since version 3.10:

Get the current event loop.

If there is no current event loop set in the current OS thread, the OS thread is main, and set_event_loop() has not yet been called, asyncio will create a new event loop and set it as the current one.

asyncio.get_running_loop():

Return the running event loop in the current OS thread.

asyncio.new_event_loop():

Create and return a new event loop object.

asyncio.set_event_loop():

Set loop as a current event loop for the current OS thread

For example, if running this code below:

import asyncio

async def test():
    while True:
        print("Test")
        await asyncio.sleep(1)

async def call_test():
    loop = asyncio.get_running_loop()
    loop.create_task(test())

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)

loop.create_task(call_test())
loop.run_forever()

Test is printed every second:

Test
Test
Test
...

So now, we can replace asyncio.get_running_loop() with asyncio.get_event_loop() in call_test() and replace loop = asyncio.new_event_loop() and asyncio.set_event_loop(loop) with asyncio.get_event_loop() as shown below:

import asyncio

async def test():
    while True:
        print("Test")
        await asyncio.sleep(1)

async def call_test():
    loop = asyncio.get_event_loop() # Here
    # loop = asyncio.get_running_loop()
    loop.create_task(test())

loop = asyncio.get_event_loop() # Here
# loop = asyncio.new_event_loop()
# asyncio.set_event_loop(loop)

loop.create_task(call_test())
loop.run_forever()

Then, Test is still printed every second:

Test
Test
Test
...

So, about when to use asyncio.get_event_loop() or asyncio.get_running_loop(), you shouldn't use asyncio.get_event_loop() anytime because it is deprecated since version 3.10. So instead, you should use asyncio.get_running_loop() everytime and also asyncio.new_event_loop() and asyncio.set_event_loop(). But if you really want to use asyncio.get_event_loop(), use it to decrease code.

Upvotes: 5

Foxy Fox
Foxy Fox

Reputation: 491

In accordance with the official documentation, both the get_running_loop and get_event_loop are used to actually get an active loop, with the difference that the latter get_event_loop has more complex behaviour, thus get_running_loop can be used widely in the applications, where the existance of the loop is not questionable.

Moreover, in the documentation it is suggested to used run method to obtain an event loop (available starting from the Python 3.7 version), e.g.

async def main():
    await asyncio.sleep(1)
    print('hello')

asyncio.run(main())   

instead of:

async def main():
    await asyncio.sleep(1)
    print('hello')
        
loop = asyncio.get_event_loop()
task = loop.create_task(main)
loop.run_forever()

Please note, that the run method solution can work weirdly in Jupyter Notebook.

Upvotes: 13

Related Questions