stellarbit / aioping

Python asyncio ping library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Send lot of pings at ones (too many file descriptors in select)

xtipacko opened this issue · comments

commented

If I try to do a lot of pings (like in the code below), I get such message:
ValueError: too many file descriptors in select()
What do you suggest to surpass this limitation?

import asyncio
import aioping

AMOUNT_OF_PINGS = 1000

async def do_ping(host, n=0):
    try:
        delay = await aioping.ping(host) * 1000
        print(f"[{n}]Ping response in {delay} ms")

    except TimeoutError:
                   print("Timed out")
#loop = asyncio.new_event_loop()

asyncio.set_event_loop(asyncio.new_event_loop()) #set as global
loop = asyncio.get_event_loop()

tasklist = []
for i in range(AMOUNT_OF_PINGS):
    tasklist.append(loop.create_task(do_ping("google.com",n=i)))
wait_tasks = asyncio.wait(tasklist)

loop.run_until_complete(wait_tasks)
loop.close()

Hello @xtipacko,

In what system are you running this code? I never met this error, but as far as I know, by default asyncio event loop uses "select" selector, which is limited to 512 descriptors in Windows and 1024 in Linux, so you can use some other event loop selector to avoid that.

In Windows instead of asyncio.new_event_loop() you might want to try:

import asyncio

loop = asyncio.ProactorEventLoop()
asyncio.set_event_loop(loop)

In Linux:

import selectors

selector = selectors.PollSelector()
loop = asyncio.SelectorEventLoop(selector)
asyncio.set_event_loop(loop)

I didn't test that, just an idea.

Thanks!

Hi,

one issue is, that my_socket is not closed in receive_one_ping() when a timeout occurs.
Maybe it should be

except asyncio.TimeoutError:
my_socket.close()
raise TimeoutError("Ping timeout")

Opened a PR for it

@hergla thanks! Sorry for being 2 years late, the request is merged :)

@xtipacko closing the issue, hope my previous answer helped you.

Writing here because this thread is pretty high in Google ranking for file descripter limit on python. Thanks for the tip! Just wanted to note here in case anyone needs it that you can tell your OS to increase that limit if you don't want to use the polling selector.