You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Asyncio StreamReader fails to close Transport #78357
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
GitHub fields:
assignee=Noneclosed_at=Nonecreated_at=<Date2018-07-21.00:30:19.386>labels= ['type-bug', '3.7', 'expert-asyncio']
title='Asyncio StreamReader fails to close Transport'updated_at=<Date2018-07-21.00:30:19.386>user='https://github.com/JDLH'
Asyncio's StreamReaderProtocol[1] often returns True from Protocol.eof_received(). This tells the Transport that "closing the transport is up to the protocol" [2]. However, StreamReaderProtocol does not call Transport.close(). More precisely, StreamReaderProtocol leaves the transport interaction to StreamReader. It calls StreamReader.feed_eof()[3]. But StreamReader does not call self._transport.close(). It only sets a self._eof flag, and awakens any of its functions which were waiting for data.
The only occurrence of self._transport.close() occurs in StreamWriter[4]. There is none in StreamReader or StreamReaderProtocol.
I believe that the fix should be for StreamReader to call self._transport.close(). However, it may need to avoid this if StreamReaderProtocol._over_ssl is True, and I don't immediately see how it can tell this. Also, it may need to wait for anything waiting for self._waiter to run, before closing the Transport.
Or, maybe StreamReaderProtocol should not return True from Protocol.eof_received().
I discovered this when using a Transport of my own devising, which reads from a file instead of from a socket, with asyncio.streams. The file did not close in the unit test. My transport duly called Protocol.eof_received(), but received a True in response, so did not close the file.
My workaround will probably be to not believe what Protocol.eof_received() tells me, and to close my transport regardless.
Python 3.7 is not supported anymore, moreover the issue does not has a reproducer to reproduce the issue and is out of date so closing. If this issue still exists, create a new issue with reproducer.
Activity
jdlh commentedon Jul 21, 2018
Asyncio's StreamReaderProtocol[1] often returns True from Protocol.eof_received(). This tells the Transport that "closing the transport is up to the protocol" [2]. However, StreamReaderProtocol does not call Transport.close(). More precisely, StreamReaderProtocol leaves the transport interaction to StreamReader. It calls StreamReader.feed_eof()[3]. But StreamReader does not call self._transport.close(). It only sets a self._eof flag, and awakens any of its functions which were waiting for data.
The only occurrence of self._transport.close() occurs in StreamWriter[4]. There is none in StreamReader or StreamReaderProtocol.
I believe that the fix should be for StreamReader to call self._transport.close(). However, it may need to avoid this if StreamReaderProtocol._over_ssl is True, and I don't immediately see how it can tell this. Also, it may need to wait for anything waiting for self._waiter to run, before closing the Transport.
Or, maybe StreamReaderProtocol should not return True from Protocol.eof_received().
I discovered this when using a Transport of my own devising, which reads from a file instead of from a socket, with asyncio.streams. The file did not close in the unit test. My transport duly called Protocol.eof_received(), but received a True in response, so did not close the file.
My workaround will probably be to not believe what Protocol.eof_received() tells me, and to close my transport regardless.
[1] Lib/asyncio.streams.StreamReaderProtocol.eof_received, line 259-266.
[2] 19.5.4.2.3. "Streaming protocols" <https://docs.python.org/3/library/asyncio-protocol.html\>
[3] Lib/Lib/asyncio.streams.StreamReader.feed_eof, lines 419-421.
[4] Lib/Lib/asyncio.streams.StreamWriter.close, lines 316-317.
All line numbers are as of tag v3.7.0, commit 1bf9cc5 .
Bug observed in v3.7.0. Not yet investigated in HEAD revision.
kumaraditya303 commentedon May 31, 2022
Python 3.7 is not supported anymore, moreover the issue does not has a reproducer to reproduce the issue and is out of date so closing. If this issue still exists, create a new issue with reproducer.
kumaraditya303 commentedon May 31, 2022
Also 3.11 has rewritten ssl implementation as of #31275.