Skip to content

Commit db56d74

Browse files
bdracojavitonino
andauthored
[PR #10171/5185f93 backport][3.11] Stream unpauses protocol before releasing connection (#10179)
Co-authored-by: Javier Torres <[email protected]>
1 parent 8c96a62 commit db56d74

File tree

4 files changed

+30
-0
lines changed

4 files changed

+30
-0
lines changed

CHANGES/10169.bugfix.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fixed a hang where a connection previously used for a streaming
2+
download could be returned to the pool in a paused state.
3+
-- by :user:`javitonino`.

CONTRIBUTORS.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ Jan Buchar
171171
Jan Gosmann
172172
Jarno Elonen
173173
Jashandeep Sohi
174+
Javier Torres
174175
Jean-Baptiste Estival
175176
Jens Steinhauser
176177
Jeonghun Lee

aiohttp/streams.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,9 @@ def feed_eof(self) -> None:
220220
self._eof_waiter = None
221221
set_result(waiter, None)
222222

223+
if self._protocol._reading_paused:
224+
self._protocol.resume_reading()
225+
223226
for cb in self._eof_callbacks:
224227
try:
225228
cb()

tests/test_flowcontrol_streams.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import pytest
55

66
from aiohttp import streams
7+
from aiohttp.base_protocol import BaseProtocol
78

89

910
@pytest.fixture
@@ -112,6 +113,15 @@ async def test_read_nowait(self, stream) -> None:
112113
assert res == b""
113114
assert stream._protocol.resume_reading.call_count == 1 # type: ignore[attr-defined]
114115

116+
async def test_resumed_on_eof(self, stream: streams.StreamReader) -> None:
117+
stream.feed_data(b"data")
118+
assert stream._protocol.pause_reading.call_count == 1 # type: ignore[attr-defined]
119+
assert stream._protocol.resume_reading.call_count == 0 # type: ignore[attr-defined]
120+
stream._protocol._reading_paused = True
121+
122+
stream.feed_eof()
123+
assert stream._protocol.resume_reading.call_count == 1 # type: ignore[attr-defined]
124+
115125

116126
async def test_flow_control_data_queue_waiter_cancelled(
117127
buffer: streams.FlowControlDataQueue,
@@ -180,3 +190,16 @@ async def test_flow_control_data_queue_read_eof(
180190
buffer.feed_eof()
181191
with pytest.raises(streams.EofStream):
182192
await buffer.read()
193+
194+
195+
async def test_stream_reader_eof_when_full() -> None:
196+
loop = asyncio.get_event_loop()
197+
protocol = BaseProtocol(loop=loop)
198+
protocol.transport = asyncio.Transport()
199+
stream = streams.StreamReader(protocol, 1024, loop=loop)
200+
201+
data_len = stream._high_water + 1
202+
stream.feed_data(b"0" * data_len)
203+
assert protocol._reading_paused
204+
stream.feed_eof()
205+
assert not protocol._reading_paused

0 commit comments

Comments
 (0)