Skip to content
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

Avoid ResourceWarning if shutdown failed for some reason #272

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

jolaf
Copy link
Contributor

@jolaf jolaf commented Oct 9, 2021

The following warning appears transiently from time to time while working with websockets:

/usr/lib/python3/dist-packages/ws4py/websocket.py:230: ResourceWarning: unclosed <ssl.SSLSocket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('10.25.11.39', 40618)>
  self.sock = None
ResourceWarning: Enable tracemalloc to get the object allocation traceback

Investigation shows that this warning appears if self.sock.shutdown(socket.SHUT_RDWR) (line 225) throws exception and thus self.sock.close() (line 226) is not called and execution proceeds straight to self.sock = None (line 230), and that produces the ResourceWarning mentioned above.

The exception itself is hidden by pass statement (line 228), but additional investigation showed the following example of that exception:

File "/usr/lib/python3/dist-packages/ws4py/websocket.py", line 225, in close_connection
    self.sock.shutdown(socket.SHUT_RDWR)
  File "/usr/lib/python3.8/ssl.py", line 1280, in shutdown
    super().shutdown(how)
OSError: [Errno 107] Transport endpoint is not connected

The reliable reproduction of this situation is problematic, but I've created the following test that reproduces the problem reliably and should pass if the problem is fixed:

from ws4py.client.threadedclient import WebSocketClient
  
def received_message(self, m):
    self.close()

def opened(self):
    self.send('blah\n' * 10000)

def shutdown(self):
    raise Exception('shutdown')

def close_connection(self):
    self.sock.shutdown = shutdown
    original_close_connection(self)

WebSocketClient.received_message = received_message
WebSocketClient.opened = opened

original_close_connection = WebSocketClient.close_connection

WebSocketClient.close_connection = close_connection

ws = WebSocketClient('wss://websocketstest.com/service')
ws.connect()
ws.run_forever()

Here's the output:

$ python3 -W all test.py 
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/ws4py/websocket.py", line 225, in close_connection
    self.sock.shutdown(socket.SHUT_RDWR)
  File "test.py", line 10, in shutdown
    raise Exception('shutdown')
Exception: shutdown

/usr/lib/python3/dist-packages/ws4py/websocket.py:231: ResourceWarning: unclosed <ssl.SSLSocket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('192.168.1.4', 50110), raddr=('88.198.55.153', 443)>
  self.sock = None
ResourceWarning: Enable tracemalloc to get the object allocation traceback

$ python3
Python 3.8.10 (default, Sep 28 2021, 16:10:42) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ws4py
>>> ws4py.__version__
'0.5.1'

$ uname -a
Linux i-buildcore-01-11 5.4.0-89-generic #100-Ubuntu SMP Fri Sep 24 14:50:10 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

$ cat /etc/issue
Ubuntu 20.04.3 LTS \n \l

Typically it looks like this:
/home/user/.local/lib/python3.8/site-packages/ws4py/websocket.py:230: ResourceWarning: unclosed <ssl.SSLSocket fd=8, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('10.200.11.18', 40248)>
@jolaf jolaf changed the title Avoiding ResourceWarning if shutdown failed for some reason. Avoid ResourceWarning if shutdown failed for some reason Oct 9, 2021
@jolaf
Copy link
Contributor Author

jolaf commented Nov 1, 2021

I've provided a test to reproduce the problem.

Copy link
Collaborator

@auvipy auvipy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible to add the test in the test suite?

@jolaf
Copy link
Contributor Author

jolaf commented Sep 8, 2024

is it possible to add the test in the test suite?

I'm not sure. This test is "dirty", it reassigns methods in system classes, I'm not sure it's a good idea to add it to the test suite.

Copy link
Collaborator

@auvipy auvipy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you just rebase it?

@jolaf
Copy link
Contributor Author

jolaf commented Sep 17, 2024

can you just rebase it?

Done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants