[Python-checkins] [3.6] bpo-35380: Enable TCP_NODELAY for proactor event loop (GH-10867). (GH-10874)

Andrew Svetlov webhook-mailer at python.org
Wed Dec 5 03:30:10 EST 2018


https://github.com/python/cpython/commit/bfb881849f588cd2046776fb431c3045781c8214
commit: bfb881849f588cd2046776fb431c3045781c8214
branch: 3.6
author: Andrew Svetlov <andrew.svetlov at gmail.com>
committer: GitHub <noreply at github.com>
date: 2018-12-05T10:30:06+02:00
summary:

[3.6] bpo-35380: Enable TCP_NODELAY for proactor event loop (GH-10867). (GH-10874)

* [3.6] bpo-35380: Enable TCP_NODELAY for proactor event loop (GH-10867).
(cherry picked from commit 3bc0ebab17bf5a2c29d2214743c82034f82e6573)

Co-authored-by: Andrew Svetlov <andrew.svetlov at gmail.com>

files:
A Misc/NEWS.d/next/Library/2018-12-03-14-41-11.bpo-35380.SdRF9l.rst
M Lib/asyncio/base_events.py
M Lib/asyncio/proactor_events.py
M Lib/asyncio/selector_events.py
M Lib/test/test_asyncio/test_base_events.py
M Lib/test/test_asyncio/test_selector_events.py

diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index accd669250cb..48dd1fc54ae4 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -182,6 +182,17 @@ def _ensure_resolved(address, *, family=0, type=socket.SOCK_STREAM, proto=0,
                                 proto=proto, flags=flags)
 
 
+if hasattr(socket, 'TCP_NODELAY'):
+    def _set_nodelay(sock):
+        if (sock.family in {socket.AF_INET, socket.AF_INET6} and
+                _is_stream_socket(sock.type) and
+                sock.proto == socket.IPPROTO_TCP):
+            sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
+else:
+    def _set_nodelay(sock):
+        pass
+
+
 def _run_until_complete_cb(fut):
     exc = fut._exception
     if (isinstance(exc, BaseException)
diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py
index 6f621ef0cc4f..079b7a24db42 100644
--- a/Lib/asyncio/proactor_events.py
+++ b/Lib/asyncio/proactor_events.py
@@ -350,6 +350,11 @@ class _ProactorSocketTransport(_ProactorReadPipeTransport,
                                transports.Transport):
     """Transport for connected sockets."""
 
+    def __init__(self, loop, sock, protocol, waiter=None,
+                 extra=None, server=None):
+        super().__init__(loop, sock, protocol, waiter, extra, server)
+        base_events._set_nodelay(sock)
+
     def _set_extra(self, sock):
         self._extra['socket'] = sock
         try:
diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py
index bc7c740cc2af..af21d5ee8914 100644
--- a/Lib/asyncio/selector_events.py
+++ b/Lib/asyncio/selector_events.py
@@ -40,17 +40,6 @@ def _test_selector_event(selector, fd, event):
         return bool(key.events & event)
 
 
-if hasattr(socket, 'TCP_NODELAY'):
-    def _set_nodelay(sock):
-        if (sock.family in {socket.AF_INET, socket.AF_INET6} and
-                base_events._is_stream_socket(sock.type) and
-                sock.proto == socket.IPPROTO_TCP):
-            sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
-else:
-    def _set_nodelay(sock):
-        pass
-
-
 class BaseSelectorEventLoop(base_events.BaseEventLoop):
     """Selector event loop.
 
@@ -691,7 +680,7 @@ def __init__(self, loop, sock, protocol, waiter=None,
         # Disable the Nagle algorithm -- small writes will be
         # sent without waiting for the TCP ACK.  This generally
         # decreases the latency (in some cases significantly.)
-        _set_nodelay(self._sock)
+        base_events._set_nodelay(self._sock)
 
         self._loop.call_soon(self._protocol.connection_made, self)
         # only start reading when connection_made() has been called
diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py
index 09f71f2f3900..052a559c3cbb 100644
--- a/Lib/test/test_asyncio/test_base_events.py
+++ b/Lib/test/test_asyncio/test_base_events.py
@@ -27,7 +27,6 @@
     except ImportError:
         from asyncio.test_support import assert_python_ok
 
-
 MOCK_ANY = mock.ANY
 PY34 = sys.version_info >= (3, 4)
 
@@ -288,7 +287,7 @@ def cb():
         loop.set_debug(debug)
         if debug:
             msg = ("Non-thread-safe operation invoked on an event loop other "
-                  "than the current one")
+                   "than the current one")
             with self.assertRaisesRegex(RuntimeError, msg):
                 loop.call_soon(cb)
             with self.assertRaisesRegex(RuntimeError, msg):
@@ -1839,5 +1838,30 @@ def runner(loop):
 
 
 
+class TestSelectorUtils(test_utils.TestCase):
+    def check_set_nodelay(self, sock):
+        opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY)
+        self.assertFalse(opt)
+
+        base_events._set_nodelay(sock)
+
+        opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY)
+        self.assertTrue(opt)
+
+    @unittest.skipUnless(hasattr(socket, 'TCP_NODELAY'),
+                         'need socket.TCP_NODELAY')
+    def test_set_nodelay(self):
+        sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM,
+                             proto=socket.IPPROTO_TCP)
+        with sock:
+            self.check_set_nodelay(sock)
+
+        sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM,
+                             proto=socket.IPPROTO_TCP)
+        with sock:
+            sock.setblocking(False)
+            self.check_set_nodelay(sock)
+
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py
index 533d2898e7fc..6716e8916cd5 100644
--- a/Lib/test/test_asyncio/test_selector_events.py
+++ b/Lib/test/test_asyncio/test_selector_events.py
@@ -17,7 +17,6 @@
 from asyncio.selector_events import _SelectorSslTransport
 from asyncio.selector_events import _SelectorSocketTransport
 from asyncio.selector_events import _SelectorDatagramTransport
-from asyncio.selector_events import _set_nodelay
 
 
 MOCK_ANY = mock.ANY
@@ -1858,30 +1857,5 @@ def test_fatal_error_connected(self, m_exc):
             exc_info=(ConnectionRefusedError, MOCK_ANY, MOCK_ANY))
 
 
-class TestSelectorUtils(test_utils.TestCase):
-    def check_set_nodelay(self, sock):
-        opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY)
-        self.assertFalse(opt)
-
-        _set_nodelay(sock)
-
-        opt = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY)
-        self.assertTrue(opt)
-
-    @unittest.skipUnless(hasattr(socket, 'TCP_NODELAY'),
-                         'need socket.TCP_NODELAY')
-    def test_set_nodelay(self):
-        sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM,
-                             proto=socket.IPPROTO_TCP)
-        with sock:
-            self.check_set_nodelay(sock)
-
-        sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM,
-                             proto=socket.IPPROTO_TCP)
-        with sock:
-            sock.setblocking(False)
-            self.check_set_nodelay(sock)
-
-
 if __name__ == '__main__':
     unittest.main()
diff --git a/Misc/NEWS.d/next/Library/2018-12-03-14-41-11.bpo-35380.SdRF9l.rst b/Misc/NEWS.d/next/Library/2018-12-03-14-41-11.bpo-35380.SdRF9l.rst
new file mode 100644
index 000000000000..91f86e604ea8
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-12-03-14-41-11.bpo-35380.SdRF9l.rst
@@ -0,0 +1 @@
+Enable TCP_NODELAY on Windows for proactor asyncio event loop.



More information about the Python-checkins mailing list