Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 758755 - sys-apps/portage: use default asyncio event loop implementation in API consumer threads
Summary: sys-apps/portage: use default asyncio event loop implementation in API consum...
Status: RESOLVED FIXED
Alias: None
Product: Portage Development
Classification: Unclassified
Component: Core (show other bugs)
Hardware: All All
: Normal normal (vote)
Assignee: Portage team
URL:
Whiteboard:
Keywords: InVCS
Depends on:
Blocks: 758719 756028
  Show dependency tree
 
Reported: 2020-12-06 09:24 UTC by Zac Medico
Modified: 2021-06-26 18:57 UTC (History)
0 users

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Zac Medico gentoo-dev 2020-12-06 09:24:30 UTC
Currently portage uses its internal EventLoop implementation in API consumer threads, but it can use the default asyncio event loop implementation instead.
Comment 3 Larry the Git Cow gentoo-dev 2020-12-07 02:50:31 UTC
The bug has been referenced in the following commit(s):

https://gitweb.gentoo.org/proj/portage.git/commit/?id=cecd2f8a259cf2991f2324c9a14e26170ba0ddcf

commit cecd2f8a259cf2991f2324c9a14e26170ba0ddcf
Author:     Zac Medico <zmedico@gentoo.org>
AuthorDate: 2020-12-06 09:25:17 +0000
Commit:     Zac Medico <zmedico@gentoo.org>
CommitDate: 2020-12-07 02:32:27 +0000

    Use default asyncio event loop implementation in API consumer threads
    
    Make the _safe_loop function return an AsyncioEventLoop instance,
    so that the default asyncio event loop implementation will be used
    in API consumer threads. This is possible because the underlying
    asyncio.get_event_loop() function returns a separate  event loop for
    each thread. The AsyncioEventLoop _run_until_complete method will
    now appropriately handle a ValueError from signal.set_wakeup_fd(-1)
    if it is not called in the main thread.
    
    For external API consumers calling from a non-main thread, an
    asyncio loop must be registered for the current thread, or else an
    error will be raised like this:
    
      RuntimeError: There is no current event loop in thread 'Thread-1'.
    
    In order to avoid this RuntimeError, the external API consumer
    is responsible for setting an event loop and managing its lifecycle.
    For example, this code will set an event loop for the current thread:
    
      asyncio.set_event_loop(asyncio.new_event_loop())
    
    In order to avoid a ResourceWarning, the caller should also close
    the corresponding loop before the current thread terminates.
    
    Bug: https://bugs.gentoo.org/758755
    Signed-off-by: Zac Medico <zmedico@gentoo.org>

 lib/portage/util/_eventloop/asyncio_event_loop.py |  6 +++++-
 lib/portage/util/futures/_asyncio/__init__.py     | 26 +++++++++++++++++------
 2 files changed, 24 insertions(+), 8 deletions(-)
Comment 4 Larry the Git Cow gentoo-dev 2020-12-07 08:41:22 UTC
The bug has been referenced in the following commit(s):

https://gitweb.gentoo.org/proj/portage.git/commit/?id=dcbcac809213537afaa6b4f9822146a2e984f773

commit dcbcac809213537afaa6b4f9822146a2e984f773
Author:     Zac Medico <zmedico@gentoo.org>
AuthorDate: 2020-12-07 06:05:04 +0000
Commit:     Zac Medico <zmedico@gentoo.org>
CommitDate: 2020-12-07 07:48:10 +0000

    _safe_loop: instantiate asyncio loop for API consumer thread
    
    In order to maintain compatibility with an API consumer thread which
    has not instantiated an asyncio loop for the current thread prior
    to calling the portage API, instantiate a loop on its behalf. Since
    a ResourceWarning will be triggered if the loop has not been closed
    before the process exits, add the loop to a WeakValueDictionary,
    and close it if it still exists during exit for the current pid.
    
    Fixes: cecd2f8a259c ("Use default asyncio event loop implementation in API consumer threads")
    Bug: https://bugs.gentoo.org/758755
    Signed-off-by: Zac Medico <zmedico@gentoo.org>

 lib/portage/util/futures/_asyncio/__init__.py | 49 ++++++++++++++++++++++-----
 1 file changed, 40 insertions(+), 9 deletions(-)
Comment 5 Larry the Git Cow gentoo-dev 2020-12-07 08:49:28 UTC
The bug has been referenced in the following commit(s):

https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=6a1a30033dd0e79e4678a5a6a8ce8d3ceddf265c

commit 6a1a30033dd0e79e4678a5a6a8ce8d3ceddf265c
Author:     Zac Medico <zmedico@gentoo.org>
AuthorDate: 2020-12-07 08:13:48 +0000
Commit:     Zac Medico <zmedico@gentoo.org>
CommitDate: 2020-12-07 08:48:09 +0000

    sys-apps/portage: Bump to version 3.0.12
    
     #758740 Use default asyncio event loop in child processes
     #758755 Use default asyncio event loop in API consumer threads
    
    Bug: https://bugs.gentoo.org/758740
    Bug: https://bugs.gentoo.org/758755
    Bug: https://bugs.gentoo.org/756028
    Package-Manager: Portage-3.0.12, Repoman-3.0.2
    Signed-off-by: Zac Medico <zmedico@gentoo.org>

 sys-apps/portage/Manifest              |   1 +
 sys-apps/portage/portage-3.0.12.ebuild | 267 +++++++++++++++++++++++++++++++++
 2 files changed, 268 insertions(+)
Comment 6 Zac Medico gentoo-dev 2020-12-07 09:11:20 UTC
If an asyncio loop is not running in the main thread, then API consumer threads will not work in practice with less than python3.8, since https://bugs.python.org/issue35621 makes MultiLoopChildWatcher necessary in order to avoid errors like this:

> RuntimeError: Cannot add child handler, the child watcher does not have a loop attached.