When using eventlet monkey_patch()'d code, greenthreads can be
blocked on connection for several seconds while the database
contents are parsed. Eventlet recommends adding a sleep(0) call
to cooperatively yield in cpu-bound code. asyncio code has
asyncio.sleep(0). This patch adds an API method that defaults to
doing nothing, but can be overridden to yield as needed.
Signed-off-by: Terry Wilson
(cherry picked from commit d28c5ca57650d6866453d0adb9a2e048cda21a86)
---
NEWS | 6 ++
python/ovs/db/idl.py | 11 +++
2 files changed, 17 insertions(+)
diff --git a/NEWS b/NEWS
index d0f0cc8d8..a8ab1aa8b 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,11 @@
v2.15.3 - xx xxx
-
+ - The Python Idl class now has a cooperative_yield() method that can be
+ overridden by an application that uses eventlet / gevent / asyncio with
+ the desired yield method (e.g. {eventlet,gevent,asyncio}.sleep(0)) to
+ prevent the application from being blocked for a long time while
+ processing database updates.
+
v2.15.2 - 21 Oct 2021
-
diff --git a/python/ovs/db/idl.py b/python/ovs/db/idl.py
index 3ca47f96b..7ecaeee6d 100644
--- a/python/ovs/db/idl.py
+++ b/python/ovs/db/idl.py
@@ -491,6 +491,15 @@ class Idl(object):
:type updates: Row
"""
+def cooperative_yield(self):
+"""Hook for cooperatively yielding to eventlet/gevent/asyncio/etc.
+
+When a block of code is going to spend a lot of time cpu-bound without
+doing any I/O, it can cause greenthread/coroutine libraries to block.
+This call should be added to code where this can happen, but defaults
+to doing nothing to avoid overhead where it is not needed.
+"""
+
def __send_cond_change(self, table, cond):
monitor_cond_change = {table.name: [{"where": cond}]}
old_uuid = str(self.uuid)
@@ -656,6 +665,8 @@ class Idl(object):
'is not an object'
% (table_name, uuid_string))
+self.cooperative_yield()
+
if version == OVSDB_UPDATE2:
changes = self.__process_update2(table, uuid, row_update)
if changes:
--
2.31.1
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev