Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Count active tasks in event loop

How can I find out how many active tasks in the event loop? In documentation I find only asyncio.Task.all_tasks() but it's simple incremental counter:

import asyncio


async def coro():
    await asyncio.sleep(1)


async def main():
    tasks = []
    print('Tasks count: ', len(asyncio.Task.all_tasks()))
    for idx in range(3):
        task = asyncio.ensure_future(coro())
        tasks.append(task)
        print('Tasks count: ', len(asyncio.Task.all_tasks()))
    await asyncio.gather(*tasks)
    print('Tasks count: ', len(asyncio.Task.all_tasks()))


loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Output:

Tasks count:  1
Tasks count:  2
Tasks count:  3
Tasks count:  4
Tasks count:  4

Expected output:

Tasks count:  1
Tasks count:  2
Tasks count:  3
Tasks count:  4
Tasks count:  1
like image 566
El Ruso Avatar asked Dec 07 '16 23:12

El Ruso


People also ask

How do event loops work?

In this chapter we first cover theoretical details about how things work, and then see practical applications of that knowledge. The event loop concept is very simple. There’s an endless loop, where the JavaScript engine waits for tasks, executes them and then sleeps, waiting for more tasks.

What happens to the event loop when a macro task is completed?

On completion of one macro-task, the event loop moves on to the micro-task queue. The event loop does not move to the next task outside of the micro-task queue until all the tasks inside the micro-task queue are completed.

What is event loop in asyncio?

Event Loop¶. The event loop is the core of every asyncio application. Event loops run asynchronous tasks and callbacks, perform network IO operations, and run subprocesses. Application developers should typically use the high-level asyncio functions, such as asyncio.run(), and should rarely need to reference the loop object or call its methods.

How do you invoke a callback from an event loop?

The callback will be invoked by loop, along with other queued callbacks and runnable coroutines of that event loop. Unlike signal handlers registered using signal.signal (), a callback registered with this function is allowed to interact with the event loop.


1 Answers

all_tasks returns all the registered tasks, including the finished ones. You can simply filter the tasks by done() to get the active ones:

import asyncio


async def coro():
    await asyncio.sleep(1)


async def main():
    tasks = []
    print('Tasks count: ', len(asyncio.Task.all_tasks()))
    for idx in range(3):
        task = asyncio.ensure_future(coro())
        tasks.append(task)
        print('Tasks count: ', len(asyncio.Task.all_tasks()))
    await asyncio.gather(*tasks)
    print('Tasks count: ', len(asyncio.Task.all_tasks()))
    print('Active tasks count: ', len(
        [task for task in asyncio.Task.all_tasks() if not task.done()])
    )

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Which outputs:

Tasks count:  1
Tasks count:  2
Tasks count:  3
Tasks count:  4
Tasks count:  4
Active tasks count:  1
like image 71
Yeray Diaz Avatar answered Oct 04 '22 15:10

Yeray Diaz