diff mbox series

[ovs-dev,branch-2.15,1/1] python: Add cooperative_yield() API method to Idl

Message ID 20211203150410.3588586-1-twilson@redhat.com
State Accepted
Headers show
Series [ovs-dev,branch-2.15,1/1] python: Add cooperative_yield() API method to Idl | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test success github build: passed

Commit Message

Terry Wilson Dec. 3, 2021, 3:04 p.m. UTC
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 <twilson@redhat.com>
(cherry picked from commit d28c5ca57650d6866453d0adb9a2e048cda21a86)
---
 NEWS                 |  6 ++++++
 python/ovs/db/idl.py | 11 +++++++++++
 2 files changed, 17 insertions(+)

Comments

Ilya Maximets Dec. 17, 2021, 9:05 p.m. UTC | #1
On 12/3/21 16:04, Terry Wilson wrote:
> 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 <twilson@redhat.com>
> (cherry picked from commit d28c5ca57650d6866453d0adb9a2e048cda21a86)
> ---
>  NEWS                 |  6 ++++++
>  python/ovs/db/idl.py | 11 +++++++++++
>  2 files changed, 17 insertions(+)

Makes sense.  Applied to branch-2.15.  Thanks!

Best regards, Ilya Maximets.
diff mbox series

Patch

diff --git a/NEWS b/NEWS
index d0f0cc8d8..a8ab1aa8b 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,11 @@ 
 v2.15.3 - xx xxx xxxx
 ---------------------
+   - 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: