Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

aiohttp: how to best mitigate "OSError: Too many open files"

I have an aiohttp (3.4.4) server with an HTTP endpoint that takes a file as input (the client issues a multipart form POST). I have a test client that makes 10K POSTs to the endpoint. The server endpoint looks something like this:

async def event_handler(request):
    files = await request.post()
    file_field = files['file_from_client']
    file_contents = file_field.file.read()

Intermittently, when my endpoint tries to look at the file provided in the POST payload, I get the following exception:

"~/venv/python3.7/site-packages/aiohttp/web_protocol.py", line 390, in start
"~/venv/python3.7/site-packages/aiohttp/web_app.py", line 366, in _handle
"~/projects/my_project/controllers.py", line 58, in event_handler
"~/venv/python3.7/site-packages/aiohttp/web_request.py", line 585, in post
"~/venv/python3.7/tempfile.py", line 618, in TemporaryFile
"~/venv/python3.7/tempfile.py", line 258, in _mkstemp_inner
OSError: [Errno 24] Too many open files: '/tmp/tmpjnt4eu_k'

(note: line 58 of event_handler is is the "await request.post()" line)

I know what causes this. My process's file descriptor limit is set to the default of 1024, and my client is throwing enough requests at my server that it is exceeding that limit. My problem is that I'm not certain what the best server mitigation is.

This article mentions this problem, with two possible solutions: increase the number of file descriptors for the server process, or introduce a semaphore on the client to ensure that that many requests are never being sent to the server. The latter is all well and good for test problems, but I don't control the client in production. The former is easily done, and mitigates this specific problem, but it seems to only be raising the ceiling - with enough requests it still seems as if this issue could occur.

Is it possible to impose a limit on the number of requests that an aiohttp server tries to handle at once, and make the others wait in line?

like image 531
krieghan Avatar asked Oct 17 '22 10:10

krieghan


1 Answers

Aiohttp accepts all incoming connections, and it seems that we can't change this, but a reverse proxy in front of aiohttp can deal with it.

e.g. Nginx has a module for it.

like image 72
Artemiy Rodionov Avatar answered Oct 21 '22 04:10

Artemiy Rodionov