classification
Title: asyncio: Windows Proactor Event Loop UDP Support
Type: enhancement Stage: resolved
Components: asyncio Versions: Python 3.8
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: Alex Chandel, asvetlov, giampaolo.rodola, meilyadam, miss-islington, vstinner, willingc, yselivanov
Priority: normal Keywords: patch

Created on 2017-03-22 19:28 by meilyadam, last changed 2019-05-28 10:46 by asvetlov. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 1067 closed meilyadam, 2017-04-09 21:35
PR 13440 merged asvetlov, 2019-05-20 12:08
Messages (9)
msg290010 - (view) Author: Adam Meily (meilyadam) * Date: 2017-03-22 19:28
I am working on a Python 3.5 project that uses asyncio on a Windows system to poll both UDP and TCP connections. Multiple sources online say that the Windows Proactor event loop, which uses I/O Completion Ports, is considerably faster and more efficient than the default Selector event loop. I'm using both UDP and TCP connections so I am stuck with the Selector event loop for the time being. I've seen the overhead of 128 open UDP/TCP connections on the Selector event loop to be near 85%, which I understand is entirely spent in Windows proprietary code and not the Python implementation.

I'd like to take a shot at implementing UDP support in the IOCP event loop. It looks like there will be a considerable amount of code shared between TCP and UDP IOCP so I plan on implementing UDP support directly in _ProactorReadPipeTransport and _ProactorBaseWritePipeTransport. I should be able to do this by wrapping any TCP/UDP specific function calls in a check of:


if sock.type == socket.SOCK_DGRAM:
    # Do UDP stuff
elif sock.type == socket.SOCK_STREAM:
    # Do TCP stuff


My initial implementation plan is to:

 - Call datagram_received() instead of data_received() when UDP data is available in _ProactorReadPipeTransport._loop_reading().
 - Implement BaseProactorEventLoop._make_datagram_transport().
 - Implement wrappers for WSAConnect, WSARecvFrom, and WSASendTo in _overlapped.
 - Implement sendto() and recvfrom() in IocpProactor, which will use the new functions in _overlapped.
 - Implement handling for UDP "connections" in IocpProactor.connect() to call WSAConnect(). WSAConnect() appears to always return immediately so the function not supporting IOCP shouldn't be an issue. We can't use ConnectEx() for UDP because ConnectEx() is for connection-oriented sockets only.

My project is unfortunately tied to Python 3.5. So, if possible, I'd like to have UDP support merged into a v3.5 release. I can fork off of master instead of v3.5.3 if Python 3.5 support isn't an option.
msg325388 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2018-09-14 19:31
I just marked my old issue bpo-23295 as duplicate of this one. Copy of my messages:

"""
ProactorEventLoop lacks UDP support: create_datagram_endpoint() is not supported.

New functions should be added to the _overlapped modul. Example: add maybe WSARecvFrom()?

See also https://code.google.com/p/tulip/issues/detail?id=187
"""
msg325389 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2018-09-14 19:32
Copy of my messages in July 2014:
https://github.com/python/asyncio/issues/187

"""
ProcatorEventLoop doesn't support UDP right now.

I'm working on a patch. I need to implement WSARecvFrom in the _overlapped module for example.

ConnectEx() fails with an error 10022 when create_datagram_endpoint() is called with remote_address. A workaround is to replace "yield from sock_connect(sock, remote_address)" with "sock.connect(remote_address)".
"""
msg325390 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2018-09-14 19:33
Adam Meily: Thanks for the proposed pull request. Would you mind to try to rebase it on the current master branch, please?
msg325453 - (view) Author: Adam Meily (meilyadam) * Date: 2018-09-15 18:12
I've rebased onto upstream master and I fixed the CI build.
msg339446 - (view) Author: Alex Chandel (Alex Chandel) Date: 2019-04-04 14:44
Could this be merged? UDP and pipes are critical for non-trivial asyncio programs on Windows, and this should be merged before the 3.8 feature window closes.
msg343754 - (view) Author: miss-islington (miss-islington) Date: 2019-05-28 09:52
New changeset bafd4b5ac83b6cc0b7455290a04c4bfad34bdc90 by Miss Islington (bot) (Andrew Svetlov) in branch 'master':
bpo-29883: Asyncio proactor udp (GH-13440)
https://github.com/python/cpython/commit/bafd4b5ac83b6cc0b7455290a04c4bfad34bdc90
msg343762 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2019-05-28 10:38
I planned to ask you (Adam and Andrew) to merge the PR even if it's not finished, just to make sure that UDP support will land into Python 3.8. But Andrew finished the PR, yahoo!

Thanks you very much Adam Meily and Andrew Svetlov! Sorry, I planned to do what Andrew did: "finish" the PR, but I was just too busy on other things :-(

Well done, I see that you fixed max_size, pause/resume protocol, etc.

asyncio on Windows will be much better experience with IOCP by default, CTRL+c support, UDP support, etc.
msg343763 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2019-05-28 10:46
You are welcome, Victor!

Thank you very much, Adam!
History
Date User Action Args
2019-05-28 10:46:30asvetlovsetmessages: + msg343763
2019-05-28 10:38:38vstinnersetmessages: + msg343762
2019-05-28 09:54:22asvetlovsetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2019-05-28 09:52:19miss-islingtonsetnosy: + miss-islington
messages: + msg343754
2019-05-20 12:08:28asvetlovsetkeywords: + patch
pull_requests: + pull_request13349
2019-04-04 14:44:58Alex Chandelsetnosy: + Alex Chandel
messages: + msg339446
2018-09-16 14:36:26willingcsetnosy: + willingc

stage: test needed -> patch review
2018-09-15 18:12:39meilyadamsetmessages: + msg325453
2018-09-14 19:33:01vstinnersetmessages: + msg325390
2018-09-14 19:32:20vstinnersetmessages: + msg325389
2018-09-14 19:31:26vstinnersetmessages: + msg325388
versions: + Python 3.8, - Python 3.7
2018-09-14 19:30:38vstinnerlinkissue23295 superseder
2017-12-08 22:14:22yselivanovsetnosy: + asvetlov
2017-04-09 21:35:47meilyadamsetpull_requests: + pull_request1213
2017-03-24 22:03:38terry.reedysetstage: test needed
versions: + Python 3.7, - Python 3.5
2017-03-23 17:10:14brett.cannonsetnosy: + vstinner, giampaolo.rodola
2017-03-22 19:28:01meilyadamcreate