-
-
Notifications
You must be signed in to change notification settings - Fork 30.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
asyncio: ConnectionResetError after StreamWriter is garbage collected #109321
Comments
If you want to just use the transport then you should |
It's not about manually instantiating the StreamWriter....
I want to reuse the transport received from some third-party component that uses the streams api (StreamReader, StreamWriter) to communicate with the remote host. This approach worked fine until version 3.11.5 and this PR #107656 What was the purpose of closing the transport in the StreamWriter This PR has already broken some libraries: romis2012/aiohttp-socks#27 (comment) The mentioned PR at least breaks backward compatibility |
@kumaraditya303, if you don't have any arguments, please reopen the issue. |
This should fix an issue when running with python 3.11 (possibly only 3.11.5<= ). ``` 47.45 | I | exchange_rate.CoinGecko | getting fx quotes for EUR 48.18 | E | exchange_rate.CoinGecko | failed fx quotes: ClientOSError('Cannot write to closing transport') Traceback (most recent call last): File "...\electrum\env11\Lib\site-packages\aiohttp\client.py", line 599, in _request resp = await req.send(conn) ^^^^^^^^^^^^^^^^^^^^ File "...\electrum\env11\Lib\site-packages\aiohttp\client_reqrep.py", line 712, in send await writer.write_headers(status_line, self.headers) File "...\electrum\env11\Lib\site-packages\aiohttp\http_writer.py", line 130, in write_headers self._write(buf) File "...\electrum\env11\Lib\site-packages\aiohttp\http_writer.py", line 75, in _write raise ConnectionResetError("Cannot write to closing transport") ConnectionResetError: Cannot write to closing transport The above exception was the direct cause of the following exception: Traceback (most recent call last): File "...\electrum\electrum\exchange_rate.py", line 85, in update_safe self._quotes = await self.get_rates(ccy) ^^^^^^^^^^^^^^^^^^^^^^^^^ File "...\electrum\electrum\exchange_rate.py", line 345, in get_rates json = await self.get_json('api.coingecko.com', '/api/v3/exchange_rates') ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "...\electrum\electrum\exchange_rate.py", line 69, in get_json async with session.get(url) as response: File "...\electrum\env11\Lib\site-packages\aiohttp\client.py", line 1187, in __aenter__ self._resp = await self._coro ^^^^^^^^^^^^^^^^ File "...\electrum\env11\Lib\site-packages\aiohttp\client.py", line 613, in _request raise ClientOSError(*exc.args) from exc aiohttp.client_exceptions.ClientOSError: Cannot write to closing transport ``` related: romis2012/aiohttp-socks#27 python/cpython#109321
The current asyncio API provides no way to attach #107656 unexpectedly closing the transport on # Transport is already open
transport = ...
loop = asyncio.get_running_loop()
reader = asyncio.StreamReader(limit=65536, loop=loop)
protocol = asyncio.StreamReaderProtocol(reader, loop=loop)
writer = asyncio.StreamWriter(transport, protocol, reader, loop)
transport.set_protocol(protocol)
# Do line-based operations using `reader` and `writer`
...
# Change protocols
transport.set_protocol(new_protocol) There is no way to detach the transport without digging into class MockTransport:
def close(self):
pass
writer._transport = MockTransport()
del writer It would be nice to have an API to clear |
If that's your main point, could you open a new issue please? While I'm not sure that this issue should remain closed, I don't think it's the place to discuss new feature requests. |
AFAICT the reason is because the transport is not under our control -- there are many possible transports and we don't want to add a FWIW: The asyncio streams implementation is not very flexible. There are a variety of design aspects that we wish we had done differently. But it's about a decade too late. We've contemplated deprecating it, but didn't have the energy to design and implement something better to replace it. But it looks like you are trying to do something unusual with it, and it's just hard to support that. The changes that broke your code, after all, were put in place to fix someone else's code. Alas. |
Bug report
Bug description:
The code below works perfectly on Python 3.11.4 but fails with
ConnectionResetError
on Python 3.11.5CPython versions tested on:
3.11
Operating systems tested on:
Linux
The text was updated successfully, but these errors were encountered: