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 |
Context | Check | Description |
---|---|---|
ovsrobot/apply-robot | success | apply and check: success |
ovsrobot/github-robot-_Build_and_Test | success | github build: passed |
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 --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:
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(+)