File: Clean-up_memcache_connection_sockets.patch

package info (click to toggle)
python-oslo.cache 3.10.1-3
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 776 kB
  • sloc: python: 3,055; sh: 31; makefile: 24
file content (49 lines) | stat: -rw-r--r-- 2,127 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
Description: WIP dont-merge: Clean-up memcache connection sockets
 The ConnectionPool currently opens sockets, but never closes them. As a
 result, any client using oslo.cache memcache pool leaves sockets in a
 CLOSE_WAIT state, with the source port not being re-usable.
 .
 In our production system, were we have A LOT of activity, this creates
 a storm of non-reusable ports: all source ports are in use, making the
 node unuseable for other things.
 .
 This patch adds a __del__ destructor closing inactive connections,
 fixing the issue.
Author: Thomas Goirand <zigo@debian.org>
Date: Mon, 06 Nov 2023 10:55:45 +0100
Change-Id: I09d632346c76d1aff7c534f0d040162d1985f548
Forwarded: https://review.opendev.org/c/openstack/oslo.cache/+/900158
Last-Update: 2023-11-14

Index: python-oslo.cache/oslo_cache/_memcache_pool.py
===================================================================
--- python-oslo.cache.orig/oslo_cache/_memcache_pool.py
+++ python-oslo.cache/oslo_cache/_memcache_pool.py
@@ -114,6 +114,27 @@ class ConnectionPool(queue.Queue):
                 self._do_log(
                     LOG.warning, "Unable to cleanup a connection: %s", e)
 
+    def __del__(self):
+        """Delete the connection pool.
+
+        Destory all connections left in the queue.
+        """
+        while True:
+            # As per https://docs.python.org/3/library/collections.html
+            # self.queue.pop() will raise IndexError when no elements are
+            # present, ending the while True: loop.
+            # The logic loops over all connections in the queue but it does
+            # not retry for a single one in case a connection closure fails
+            # then it leaves that one and process the next.
+            try:
+                conn = self.queue.pop().connection
+                self._destroy_connection(conn)
+            except IndexError:
+                break
+            except Exception as e:
+                self._do_log(
+                    LOG.warning, "Unable to cleanup a connection: %s", e)
+
     def _create_connection(self):
         """Returns a connection instance.