From 66bfe63875bdd8b2049b415986669aaa96494953 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Mon, 28 May 2018 16:19:39 -0400 Subject: [PATCH 1/2] bpo-32410: Avoid blocking on file IO in sendfile fallback code --- Lib/asyncio/base_events.py | 7 +++++-- Lib/asyncio/constants.py | 4 ++++ Lib/test/test_asyncio/test_base_events.py | 3 +++ .../next/Library/2018-05-28-16-19-35.bpo-32410.Z1DZaF.rst | 1 + 4 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-05-28-16-19-35.bpo-32410.Z1DZaF.rst diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index a0243f5bac9a2c..ffd2513e33a6a0 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -800,7 +800,10 @@ async def _sock_sendfile_native(self, sock, file, offset, count): async def _sock_sendfile_fallback(self, sock, file, offset, count): if offset: file.seek(offset) - blocksize = min(count, 16384) if count else 16384 + blocksize = ( + min(count, constants.SENDFILE_FALLBACK_READBUFFER_SIZE) + if count else constants.SENDFILE_FALLBACK_READBUFFER_SIZE + ) buf = bytearray(blocksize) total_sent = 0 try: @@ -810,7 +813,7 @@ async def _sock_sendfile_fallback(self, sock, file, offset, count): if blocksize <= 0: break view = memoryview(buf)[:blocksize] - read = file.readinto(view) + read = await self.run_in_executor(None, file.readinto, view) if not read: break # EOF await self.sock_sendall(sock, view) diff --git a/Lib/asyncio/constants.py b/Lib/asyncio/constants.py index 739b0a70c13e06..d7ba4969428969 100644 --- a/Lib/asyncio/constants.py +++ b/Lib/asyncio/constants.py @@ -14,6 +14,10 @@ # Number of seconds to wait for SSL handshake to complete SSL_HANDSHAKE_TIMEOUT = 10.0 +# Used in sendfile fallback code. We use fallback for platforms +# that don't support sendfile, or for TLS connections. +SENDFILE_FALLBACK_READBUFFER_SIZE = 1024 * 256 + # The enum should be here to break circular dependencies between # base_events and sslproto class _SendfileMode(enum.Enum): diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index 8566a9d5504f2b..11e9465d392179 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -1818,12 +1818,15 @@ async def wait_closed(self): @classmethod def setUpClass(cls): + cls.__old_bufsize = constants.SENDFILE_FALLBACK_READBUFFER_SIZE + constants.SENDFILE_FALLBACK_READBUFFER_SIZE = 1024 * 16 with open(support.TESTFN, 'wb') as fp: fp.write(cls.DATA) super().setUpClass() @classmethod def tearDownClass(cls): + constants.SENDFILE_FALLBACK_READBUFFER_SIZE = cls.__old_bufsize support.unlink(support.TESTFN) super().tearDownClass() diff --git a/Misc/NEWS.d/next/Library/2018-05-28-16-19-35.bpo-32410.Z1DZaF.rst b/Misc/NEWS.d/next/Library/2018-05-28-16-19-35.bpo-32410.Z1DZaF.rst new file mode 100644 index 00000000000000..2d7bb2032ac5cc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-05-28-16-19-35.bpo-32410.Z1DZaF.rst @@ -0,0 +1 @@ +Avoid blocking on file IO in sendfile fallback code From c6a2a85f3742db73c3533a3d371ee9e98de194fe Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Mon, 28 May 2018 16:58:41 -0400 Subject: [PATCH 2/2] Fix tests on win --- Lib/test/test_asyncio/test_events.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index d7b0a665a0abc1..c0763821e9a14e 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -2142,6 +2142,17 @@ def connection_lost(self, exc): async def wait_closed(self): await self.fut + @classmethod + def setUpClass(cls): + cls.__old_bufsize = constants.SENDFILE_FALLBACK_READBUFFER_SIZE + constants.SENDFILE_FALLBACK_READBUFFER_SIZE = 1024 * 16 + super().setUpClass() + + @classmethod + def tearDownClass(cls): + constants.SENDFILE_FALLBACK_READBUFFER_SIZE = cls.__old_bufsize + super().tearDownClass() + def set_socket_opts(self, sock): # On macOS, SO_SNDBUF is reset by connect(). So this method # should be called after the socket is connected.