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 SSL keep-alive connections raise errors after loop close. #80890
Comments
If an asyncio SSL connection is left open (eg. any kind of keep-alive connection) then after closing the event loop, an exception will be raised... Python:
Traceback:
It looks to me like the original "OSError: [Errno 9] Bad file descriptor" probably shouldn't be raised in any case - if when attempting to tear down the SSL connection, then we should probably pass silently in the case that the socket has already been closed uncleanly. Bought to my attention via: encode/httpcore#16 |
This appears somewhat related: https://bugs.python.org/issue34506 As it also logs exceptions occuring during |
From my understanding, the correct code should close all transports and wait for their connection_lost() callbacks before closing the loop. |
Ideally, yes, although we should be able to expect that an SSL connection that hasn't been gracefully closed wouldn't loudly error on teardown like that. In standard sync code, the equivelent would running something like this... session = requests.Session()
session.get('https://example.com/') We wouldn't expect a traceback to be raised on exiting. (Even though the user *hasn't* explicitly closed the session, and even though a keep alive SSL connection will be open at the point of exit.) |
I would say that if requests a designed from scratch more idiomatic way could be with requests.Session() as session:
session.get('https://example.com/') or session = requests.Session()
session.get('https://example.com/')
session.close() Like the recommended way to handle files. |
Right, and The point more being that *not* having closed the transport at the point of exit shouldn't end up raising a hard error. It doesn't raise errors in sync-land, and it shouldn't do so in async-land. Similarly, we wouldn't expect an open file resource to cause errors to be raised at the point of exit. |
The difference is that socket.close() is an instant call. In case of SSL it may take much longer. Sorry, that's how asyncio is designed. |
Andrew, couldn't we provide a "stream.terminate()" method (not a coroutine) that would do the following:
This way Tom could have a weakref to the stream object from his high-level wrapper, and whenever the wrapper object is dereferenced it could terminate its stream.
I think it's a real problem, let's try to find out if we can provide a solution. |
It's not about streams only. But transport emits a warning like "unclosed transport ..." Not sure if we have to drop this warning, it enforces writing good code that controls all created resources lifecycle. |
Right, maybe we add "transport.terminate()" as well? Synchronously & immediately closing a transport is a valid use case. TBH I don't see why we absolutely must wait the "connection_lost" callback call. I mean it would be reasonable to allow users to terminate the connection (even if it means that in some cases, like SSL, it won't be correctly closed) and not care about what happens to it next. |
Sorry, I'm not comfortable with such change just before the feature freeze. |
This seems to be an asyncio problem. |
The original issue is fixed on main branch with bpo-44011 #75458, ----------------------------------------------------------- ----------------------------------------------------------- @asvetlvo This can be closed now. |
Thanks! |
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:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: