]> granicus.if.org Git - python/commitdiff
bpo-35380: Enable TCP_NODELAY for proactor event loop (#10867)
authorAndrew Svetlov <andrew.svetlov@gmail.com>
Mon, 3 Dec 2018 19:08:13 +0000 (21:08 +0200)
committerGitHub <noreply@github.com>
Mon, 3 Dec 2018 19:08:13 +0000 (21:08 +0200)
Lib/asyncio/base_events.py
Lib/asyncio/proactor_events.py
Lib/asyncio/selector_events.py
Lib/test/test_asyncio/test_base_events.py
Lib/test/test_asyncio/test_selector_events.py
Misc/NEWS.d/next/Library/2018-12-03-14-41-11.bpo-35380.SdRF9l.rst [new file with mode: 0644]

index f5ab6e7b2d21d89be70c311d254a0a5dbd3af613..60a189bdfb7ec9c609fb0577de8e13ac0990fbc3 100644 (file)
@@ -168,6 +168,17 @@ def _run_until_complete_cb(fut):
     futures._get_loop(fut).stop()
 
 
+if hasattr(socket, 'TCP_NODELAY'):
+    def _set_nodelay(sock):
+        if (sock.family in {socket.AF_INET, socket.AF_INET6} and
+                sock.type == socket.SOCK_STREAM and
+                sock.proto == socket.IPPROTO_TCP):
+            sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
+else:
+    def _set_nodelay(sock):
+        pass
+
+
 class _SendfileFallbackProtocol(protocols.Protocol):
     def __init__(self, transp):
         if not isinstance(transp, transports._FlowControlMixin):
index ad23918802faadd0e6376bf7cbe0a85280ce3348..69d96a81035e04624198fd6a9f6c1101c11b8de8 100644 (file)
@@ -13,7 +13,6 @@ import warnings
 
 from . import base_events
 from . import constants
-from . import events
 from . import futures
 from . import exceptions
 from . import protocols
@@ -445,6 +444,11 @@ class _ProactorSocketTransport(_ProactorReadPipeTransport,
 
     _sendfile_compatible = constants._SendfileMode.TRY_NATIVE
 
+    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
 
index ad093001dd9a967f9eb6a43184c7b38d51207321..112c4b15b8d8cf38efe9081bb94a6291dc51a8d2 100644 (file)
@@ -39,17 +39,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
-                sock.type == socket.SOCK_STREAM 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.
 
@@ -742,7 +731,7 @@ class _SelectorSocketTransport(_SelectorTransport):
         # 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
index 6d544d1eda86354f545d6dfbd5d9d616379c4e7e..53854758a27d4c649d54c83778fe6c9ff3922a46 100644 (file)
@@ -2,7 +2,6 @@
 
 import concurrent.futures
 import errno
-import logging
 import math
 import os
 import socket
@@ -15,7 +14,6 @@ from unittest import mock
 import asyncio
 from asyncio import base_events
 from asyncio import constants
-from asyncio import events
 from test.test_asyncio import utils as test_utils
 from test import support
 from test.support.script_helper import assert_python_ok
@@ -288,7 +286,7 @@ class BaseEventLoopTests(test_utils.TestCase):
         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):
@@ -2075,5 +2073,31 @@ class BaseLoopSockSendfileTests(test_utils.TestCase):
             self.run_loop(self.loop.sock_sendfile(sock, self.file, -1))
 
 
+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()
index b99e8e6960702d7ae60c8ee1db5ffda567216cf9..d0d171a9853a33c630c868fc7db72f8dfcc2e413 100644 (file)
@@ -14,7 +14,6 @@ from asyncio.selector_events import BaseSelectorEventLoop
 from asyncio.selector_events import _SelectorTransport
 from asyncio.selector_events import _SelectorSocketTransport
 from asyncio.selector_events import _SelectorDatagramTransport
-from asyncio.selector_events import _set_nodelay
 from test.test_asyncio import utils as test_utils
 
 
@@ -1344,30 +1343,5 @@ class SelectorDatagramTransportTests(test_utils.TestCase):
             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 (file)
index 0000000..91f86e6
--- /dev/null
@@ -0,0 +1 @@
+Enable TCP_NODELAY on Windows for proactor asyncio event loop.