From e3ec37a36082ba4ac97993961d4073bf43177d38 Mon Sep 17 00:00:00 2001
From: Takashi Kajinami <kajinamit@oss.nttdata.com>
Date: Fri, 21 Feb 2025 21:14:47 +0900
Subject: [PATCH] Do not un-patch threading

Current un-patching causes conflict with a few other moduels such as
queue patched, which is causing undesired delays. Let's remove it to
use unpatched modules or patched modules consistently.

Co-Authored-By: Artem Vasilyev <artem.v.vasilyev@gmail.com>
Closes-Bug: #2098714
Change-Id: I3c5ce7cc399c76afcee57d92d6a3a0f2b680efce
---
 oslo_messaging/_metrics/client.py             | 20 ++++---------------
 .../notes/bug-2098714-d55094fa4fbb3178.yaml   |  7 +++++++
 2 files changed, 11 insertions(+), 16 deletions(-)
 create mode 100644 releasenotes/notes/bug-2098714-d55094fa4fbb3178.yaml

diff --git a/oslo_messaging/_metrics/client.py b/oslo_messaging/_metrics/client.py
index 5284be172..964831390 100644
--- a/oslo_messaging/_metrics/client.py
+++ b/oslo_messaging/_metrics/client.py
@@ -20,24 +20,10 @@ import time
 from oslo_config import cfg
 from oslo_log import log as logging
 from oslo_metrics import message_type
-from oslo_utils import eventletutils
-from oslo_utils import importutils
 
 
 LOG = logging.getLogger(__name__)
 
-eventlet = importutils.try_import('eventlet')
-if eventlet and eventletutils.is_monkey_patched("thread"):
-    # Here we initialize module with the native python threading module
-    # if it was already monkey patched by eventlet/greenlet.
-    stdlib_threading = eventlet.patcher.original('threading')
-else:
-    # Manage the case where we run this driver in a non patched environment
-    # and where user even so configure the driver to run heartbeat through
-    # a python thread, if we don't do that when the heartbeat will start
-    # we will facing an issue by trying to override the threading module.
-    stdlib_threading = threading
-
 
 oslo_messaging_metrics = [
     cfg.BoolOpt('metrics_enabled', default=False,
@@ -114,6 +100,10 @@ class MetricsCollectorClient:
             self.send_thread = threading.Thread(target=self.send_loop)
             self.send_thread.start()
 
+        # TODO(tkajinam): This is needed to ensure context switch in eventlet
+        # case and may be removed after eventlet support is removed.
+        time.sleep(0)
+
     def send_loop(self):
         timeout = self.conf.metrics_thread_stop_timeout
         stoptime = time.time() + timeout
@@ -247,8 +237,6 @@ METRICS_COLLECTOR = None
 
 
 def get_collector(conf, metrics_type, **kwargs):
-    global threading
-    threading = stdlib_threading
     global METRICS_COLLECTOR
     if METRICS_COLLECTOR is None:
         METRICS_COLLECTOR = MetricsCollectorClient(
diff --git a/releasenotes/notes/bug-2098714-d55094fa4fbb3178.yaml b/releasenotes/notes/bug-2098714-d55094fa4fbb3178.yaml
new file mode 100644
index 000000000..87d2e9d8d
--- /dev/null
+++ b/releasenotes/notes/bug-2098714-d55094fa4fbb3178.yaml
@@ -0,0 +1,7 @@
+---
+fixes:
+  - |
+    Fixes delayed metrics processing in services using eventlet, caused by
+    mixing a native thread with an eventlet-patched queue.
+    See `bug 2098714 <https://launchpad.net/bugs/2098714>`__
+    for details.