This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: ProactorEventLoop should use implement GetAddrInfo, GetNameInfo
Type: enhancement Stage:
Components: asyncio Versions: Python 3.8
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: asvetlov, ysangkok+launchpad, yselivanov
Priority: normal Keywords:

Created on 2018-08-15 15:56 by ysangkok+launchpad, last changed 2022-04-11 14:59 by admin.

Messages (6)
msg323572 - (view) Author: (ysangkok+launchpad) Date: 2018-08-15 15:56
Since socket.getaddrinfo and socket.getnameinfo take a lock on Windows, it would be nice to have their corresponding methods in asyncio.ProactorEventLoop use IOCP, so that they wouldn't block the whole event loop.

Overlapped I/O flags are available, so I am wondering how hard this would be: https://docs.microsoft.com/en-us/windows/desktop/api/ws2tcpip/nf-ws2tcpip-getaddrinfoexa
msg323573 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2018-08-15 16:19
> so that they wouldn't block the whole event loop.

The aren't blocking it now as they are executed in a thread pool.
msg323574 - (view) Author: (ysangkok+launchpad) Date: 2018-08-15 17:38
As far as our experiments show, the requests are blocking each other irrespective of thread pool size. Which is expected since the lock is global across threads.

Am I correct in assuming that an implementation for the ProactorEventLoop with IOCP would not require a global lock?

Here is our code, this takes 12 sec on Ubuntu and ~12*100 secs on Windows (cause a failed DNS request takes 10 sec):

import asyncio

futs = []
for i in range(100):
  t = asyncio.get_event_loop().getaddrinfo("aa000000aa"+str(i)+".onion.", 80)
  futs.append(t)

print(asyncio.get_event_loop().run_until_complete(asyncio.gather(*futs, return_exceptions=True)))
msg323575 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2018-08-15 17:44
> As far as our experiments show, the requests are blocking each other irrespective of thread pool size. Which is expected since the lock is global across threads.

It looks like you don't understand how GIL works in Python (sorry if I'm mistaken).

The GIL prevents two threads from simultaneously executing *pure Python* code.  Whenever Python code does a system call, the GIL is released for that thread, allowing other Python code in other threads to execute.  Therefore, getaddrname calls in threadpools can't block each other or the event loop thread in any way.

There's a max capacity for the threadpool though, so if you're making 100s of getaddrname calls you'll indeed see some slowdown.  Using IOCP for getaddsname can remove this bottleneck.

> Am I correct in assuming that an implementation for the ProactorEventLoop with IOCP would not require a global lock?

I think so, because we can have as many getaddrcalls as we want all monitored by IOCP for us.  But I'm not an expert in IOCP, so if you want to work on the patch I can't really help you with details.
msg323578 - (view) Author: (ysangkok+launchpad) Date: 2018-08-15 18:01
The lock I was referring to is https://github.com/python/cpython/blob/e0b5b2096ead4cc094a129ce7602ac5c0e998086/Modules/socketmodule.c#L222

Is netdb_lock the GIL?

If the thread pooling was effective, the slowdown wouldn't be linear, but it does indeed appear to be. How can this be?
msg323579 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2018-08-15 18:08
> Is netdb_lock the GIL?

No, it's a lock used by getaddrinfo specifically on *some* platforms. It doesn't look like it's used on Windows.

> If the thread pooling was effective, the slowdown wouldn't be linear, but it does indeed appear to be. How can this be?

I don't know, hard to tell without seeing how you test that :)
History
Date User Action Args
2022-04-11 14:59:04adminsetgithub: 78592
2018-08-15 18:08:23yselivanovsetmessages: + msg323579
2018-08-15 18:01:18ysangkok+launchpadsetmessages: + msg323578
2018-08-15 17:44:37yselivanovsetmessages: + msg323575
2018-08-15 17:38:52ysangkok+launchpadsetmessages: + msg323574
2018-08-15 16:19:07yselivanovsetmessages: + msg323573
2018-08-15 15:56:16ysangkok+launchpadcreate