From 081cb88bdc528719a6a775fb4f2351c9c378217b Mon Sep 17 00:00:00 2001 From: Nicola Coretti Date: Tue, 21 Nov 2023 16:06:25 +0100 Subject: [PATCH] Fix websocket connection isn't properly closed (#109) * Add additional information regarding #108 * Add known issues to docs * Added additional information regarding the impact on DB side --- docs/KNOWN_ISSUES.md | 25 +++++++++++++++++++++++++ pyexasol/connection.py | 24 ++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 docs/KNOWN_ISSUES.md diff --git a/docs/KNOWN_ISSUES.md b/docs/KNOWN_ISSUES.md new file mode 100644 index 0000000..655fab4 --- /dev/null +++ b/docs/KNOWN_ISSUES.md @@ -0,0 +1,25 @@ +# Known Issues + + +## `ssl.SSLError: Underlying socket connection gone (_ssl.c:...)` + +This error can occur in rare cases, for additional details see [GH-Issue #108](https://github.com/exasol/pyexasol/issues/108) +and `pyexasol.connection.ExaConnection:__del__`. +The root cause of this issue usually stems from a connection not being properly closed before program exit (interpreter shutdown). + + +Example Output: +```python +Exception ignored in: +Traceback (most recent call last): + File ".../test_case.py", line 14, in __del__ + File ".../lib/python3.10/site-packages/pyexasol/connection.py", line 456, in close + File ".../lib/python3.10/site-packages/pyexasol/connection.py", line 524, in req + File ".../lib/python3.10/site-packages/websocket/_core.py", line 285, in send + File ".../lib/python3.10/site-packages/websocket/_core.py", line 313, in send_frame + File ".../lib/python3.10/site-packages/websocket/_core.py", line 527, in _send + File ".../lib/python3.10/site-packages/websocket/_socket.py", line 172, in send + File ".../lib/python3.10/site-packages/websocket/_socket.py", line 149, in _send + File "/usr/lib/python3.10/ssl.py", line 1206, in send +ssl.SSLError: Underlying socket connection gone (_ssl.c:2326)` +``` \ No newline at end of file diff --git a/pyexasol/connection.py b/pyexasol/connection.py index bd4fff4..4e5d7a7 100644 --- a/pyexasol/connection.py +++ b/pyexasol/connection.py @@ -890,6 +890,30 @@ def __del__(self): 2) make sure connection is closed immediately even if garbage collection was disabled for any reasons 3) write debug logs """ + # Based on our investigations, two scenarios have emerged, one of which does not function correctly: + # + # 1. `__del__` is invoked during a regular garbage collector run while the process remains active. + # 2. `__del__` is invoked during interpreter shutdown (throws an exception). + # * This leads to a minor residual on the database, which will automatically be cleared up within a couple of hours + # + # In situations where interpreter shutdown occurs while a connection remains unclosed + # due to not being addressed during a regular garbage collector run or manual close, + # the error scenario (2.) will be triggered. + # + # The issue arises because during interpreter shutdown, orderly deletion is not guaranteed + # (see also [Python documentation](https://docs.python.org/3/reference/datamodel.html#object.__del__) and + # [C-API documentation](https://docs.python.org/3/c-api/init.html#c.Py_FinalizeEx)). + # Consequently, scenarios may occur where the underlying socket is already closed or cleaned up while + # the connection still tries using it (see [#108](https://github.com/exasol/pyexasol/issues/108)). + # + # Despite this problem, having a `__del__` method that performs cleanup remains valuable, + # particularly in the context of long-running processes, to prevent resource leaks. + # + # Possible alternative solutions to address this would be: + # * Within the catch, report a clear error message that the user did not close all the connections which were opened. + # * Remove the `__del__` function to "force" the user to always address open/close in a clean manner. + # + # Still, the feedback we received from users so far indicates that neither alternative is desirable for them. try: self.close() except Exception: