WSS: _pong_not_received works (mostly) correctly but outcome is erased by receive's except EofStream: #8540
Description
Describe the bug
I'm testing a condition where a network connection is severed to see how application behaves and recovers. This is accomplished by switching the laptop into an airplane mode, disabling the WiFi interface, i.e. a hard disconnect.
I noticed that application shuts down as if receiving a normal exit signal, which isn't supposed to happen.
Tracked this down to the following:
When connection is severed with my activated heartbeat of 5.0, _pong_not_received works mostly correctly:
Lines 116 to 121 in e057906
However, the concurrent receive that returns some time thereafter with EofStream erases all information about the abnormal shutdown:
Lines 253 to 256 in e057906
Additionally, and corollary to the above, the way _pong_not_received closes the connection does not unblock the receive at all, because self._close is set as opposed to calling self.close(), which would then feed receive termination data immediately. That doesn't happen and when receive finally receives the EofStream, it's oblivious as to the cause.
I'm working on a patch.
To Reproduce
- Connect to WSS endpoint and set frequent heartbeats and start receiving.
- Sever network connection for long enough for heartbeat to timeout.
- Observe that receive returns
WSCloseCode.OKwaaaay past the heartbeat timeout with no indication anything went wrong.
Expected behavior
receive:
- does not erase the error information from the
_pong_not_receivedwhenEofStreamis received. - terminates immediately upon
_pong_not_receivedwith proper termination cause. _pong_not_receivedshould probably useself.close()
Logs/tracebacks
AbovePython Version
$ python --version
Not relevant, but `Python 3.12.4`aiohttp Version
$ python -m pip show aiohttp
3.9.5multidict Version
$ python -m pip show multidict
Not relevantyarl Version
$ python -m pip show yarl
Not relevantOS
Fedora 40, Linux, x86_64
Related component
Client
Additional context
No response
Code of Conduct
- I agree to follow the aio-libs Code of Conduct