asyncio: set TCP_NODELAY flag by default #71643
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
assignee = None closed_at = <Date 2017-12-16.02:54:32.507> created_at = <Date 2016-07-05.15:27:48.626> labels = ['expert-asyncio', 'performance'] title = 'asyncio: set TCP_NODELAY flag by default' updated_at = <Date 2017-12-20.07:18:20.545> user = 'https://github.com/jimfulton'
activity = <Date 2017-12-20.07:18:20.545> actor = 'socketpair' assignee = 'none' closed = True closed_date = <Date 2017-12-16.02:54:32.507> closer = 'yselivanov' components = ['asyncio'] creation = <Date 2016-07-05.15:27:48.626> creator = 'j1m' dependencies =  files =  hgrepos =  issue_num = 27456 keywords = ['patch'] message_count = 22.0 messages = ['269826', '269831', '269836', '269837', '269838', '269839', '269840', '269841', '269857', '269933', '274251', '275907', '275908', '305432', '305435', '305437', '305438', '308436', '308441', '308627', '308640', '308706'] nosy_count = 6.0 nosy_names = ['vstinner', 'j1m', 'vmagamedov', 'socketpair', 'python-dev', 'yselivanov'] pr_nums = ['4231', '4233', '4897', '4898', '4922'] priority = 'normal' resolution = 'fixed' stage = 'resolved' status = 'closed' superseder = None type = 'performance' url = 'https://bugs.python.org/issue27456' versions = ['Python 3.4', 'Python 3.5']
The text was updated successfully, but these errors were encountered:
tl;dr TCP_NODELAY should be set by default and/or there should be a
I've ported ZEO, ZODB's client-server networking layer to asyncio.
After some digging, I came across this:
Then led me to try setting TCP_NODELAY, which provided Linux
Issue 311 suggested that this was a kernal-version issue. I think
I originally tried this on Ubuntu 14.04, with kernal
Finally, I tried an Amazon standard AMI, which runs some version of
Note that the non-slow kernal version was lower than the slow (Ubuntu)
I couldn't find a way to set TCP_NODELAY cleanly. Did I miss something?
I ended up having to set the option on _sock transport attributes,
I think TCP_NODELAY should be set by default. Perhaps it shouldn't be
I also think there should be a way to set it cleanly.
IMO, this is extremely important. Linux is a wildly important platform
See also python/asyncio#286
I also wanted to raise this question. I think transports should set NODELAY by default (as Golang, for instance). I've been hit by this thing a few times already -- performance of protocols over TCP is terrible because somebody forgot to set this flag.
Seems like this fix is incomplete. It contains this check:
But sock.type is not only a type (at least in Linux and FreeBSD), it also may contain SOCK_NONBLOCK and SOCK_CLOEXEC flags. So I'm hitting the same problem: on the Linux in asyncio I have:
So this check isn't working and TCP_NODELAY still disabled by default.
Linux has SOCK_TYPE_MASK definition equal to 0xf, but I can't find such definition in the FreeBSD sources. And I don't know how to reliably and with forward compatibility check sock.type without calling getsockopt() syscall.
Currently I have a fix in my project, where:
_sock_type_mask = 0xf if hasattr(socket, 'SOCK_NONBLOCK') else 0xffffffff
And then in my own _set_nodelay(sock) function:
Should I make a pull request or someone knows more reliable check? Or it is ok to add one more syscall?