Skip to content

Commit

Permalink
SpawnProcess: use async_start method (bug 709746)
Browse files Browse the repository at this point in the history
Convert SpawnProcess to use the async_start method, since
eventually this method will need to be a coroutine in order to write
messages to the build log as discussed in bug 709746.

Also update AbstractEbuildProcess, AsynchronousLock,
BinpkgExtractorAsync, BinpkgFetcher, EbuildFetcher,
IterCompletedTestCase, AsyncFunction, and FileDigester for
compatibility with SpawnProcess async_start.

Bug: https://bugs.gentoo.org/709746
Signed-off-by: Zac Medico <zmedico@gentoo.org>
  • Loading branch information
zmedico committed Feb 24, 2020
1 parent 4df7a0a commit 5c40c3e
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 19 deletions.
2 changes: 1 addition & 1 deletion lib/_emerge/AbstractEbuildProcess.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def _async_start(self):
self.fd_pipes[0] = null_fd

try:
SpawnProcess._start(self)
yield SpawnProcess._async_start(self)
finally:
if null_fd is not None:
os.close(null_fd)
Expand Down
15 changes: 12 additions & 3 deletions lib/_emerge/AsynchronousLock.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2010-2018 Gentoo Foundation
# Copyright 2010-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

import fcntl
Expand All @@ -21,6 +21,7 @@
from portage.localization import _
from portage.locks import lockfile, unlockfile
from portage.util import writemsg_level
from portage.util.futures.compat_coroutine import coroutine
from _emerge.AbstractPollTask import AbstractPollTask
from _emerge.AsynchronousTask import AsynchronousTask
from _emerge.SpawnProcess import SpawnProcess
Expand All @@ -43,6 +44,10 @@ class AsynchronousLock(AsynchronousTask):
_use_process_by_default = True

def _start(self):
self.scheduler.run_until_complete(self._async_start())

@coroutine
def _async_start(self):

if not self._force_async:
try:
Expand All @@ -65,7 +70,7 @@ def _start(self):
_force_dummy=self._force_dummy)

self._imp.addExitListener(self._imp_exit)
self._imp.start()
yield self._imp.async_start()

def _imp_exit(self, imp):
# call exit listeners
Expand Down Expand Up @@ -183,6 +188,10 @@ class _LockProcess(AbstractPollTask):
('_acquired', '_kill_test', '_proc', '_files', '_unlock_future')

def _start(self):
self.scheduler.run_until_complete(self._async_start())

@coroutine
def _async_start(self):
in_pr, in_pw = os.pipe()
out_pr, out_pw = os.pipe()
self._files = {}
Expand Down Expand Up @@ -211,7 +220,7 @@ def _start(self):
fd_pipes={0:out_pr, 1:in_pw, 2:sys.__stderr__.fileno()},
scheduler=self.scheduler)
self._proc.addExitListener(self._proc_exit)
self._proc.start()
yield self._proc.async_start()
os.close(out_pr)
os.close(in_pw)

Expand Down
9 changes: 7 additions & 2 deletions lib/_emerge/BinpkgExtractorAsync.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 1999-2013 Gentoo Foundation
# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

import logging
Expand All @@ -10,6 +10,7 @@
compression_probe,
_compressors,
)
from portage.util.futures.compat_coroutine import coroutine
from portage.process import find_binary
from portage.util import (
shlex_split,
Expand All @@ -27,6 +28,10 @@ class BinpkgExtractorAsync(SpawnProcess):
_shell_binary = portage.const.BASH_BINARY

def _start(self):
self.scheduler.run_until_complete(self._async_start())

@coroutine
def _async_start(self):
tar_options = ""
if "xattr" in self.features:
process = subprocess.Popen(["tar", "--help"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Expand Down Expand Up @@ -105,4 +110,4 @@ def _start(self):
portage._shell_quote(self.image_dir),
128 + signal.SIGPIPE)]

SpawnProcess._start(self)
yield SpawnProcess._async_start(self)
9 changes: 7 additions & 2 deletions lib/_emerge/BinpkgFetcher.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 1999-2018 Gentoo Foundation
# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

import functools
Expand All @@ -16,6 +16,7 @@
from portage import os
from portage.util._async.AsyncTaskFuture import AsyncTaskFuture
from portage.util._pty import _create_pty_or_pipe
from portage.util.futures.compat_coroutine import coroutine

if sys.hexversion >= 0x3000000:
long = int
Expand Down Expand Up @@ -85,6 +86,10 @@ class _BinpkgFetcherProcess(SpawnProcess):
__slots__ = ("pkg", "pretend", "locked", "pkg_path", "_lock_obj")

def _start(self):
self.scheduler.run_until_complete(self._async_start())

@coroutine
def _async_start(self):
pkg = self.pkg
pretend = self.pretend
bintree = pkg.root_config.trees["bintree"]
Expand Down Expand Up @@ -158,7 +163,7 @@ def _start(self):
self.env = fetch_env
if settings.selinux_enabled():
self._selinux_type = settings["PORTAGE_FETCH_T"]
SpawnProcess._start(self)
yield SpawnProcess._async_start(self)

def _pipe(self, fd_pipes):
"""When appropriate, use a pty so that fetcher progress bars,
Expand Down
9 changes: 7 additions & 2 deletions lib/_emerge/EbuildFetcher.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 1999-2018 Gentoo Foundation
# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

import copy
Expand All @@ -15,6 +15,7 @@
from portage.package.ebuild.fetch import _check_distfile, fetch
from portage.util._async.AsyncTaskFuture import AsyncTaskFuture
from portage.util._async.ForkProcess import ForkProcess
from portage.util.futures.compat_coroutine import coroutine
from portage.util._pty import _create_pty_or_pipe
from _emerge.CompositeTask import CompositeTask

Expand Down Expand Up @@ -182,6 +183,10 @@ def _check_already_fetched(self, settings, uri_map):
return success

def _start(self):
self.scheduler.run_until_complete(self._async_start())

@coroutine
def _async_start(self):

root_config = self.pkg.root_config
portdb = root_config.trees["porttree"].dbapi
Expand Down Expand Up @@ -220,7 +225,7 @@ def _start(self):
settings["NOCOLOR"] = nocolor

self._settings = settings
ForkProcess._start(self)
yield ForkProcess._async_start(self)

# Free settings now since it's no longer needed in
# this process (the subprocess has a private copy).
Expand Down
8 changes: 6 additions & 2 deletions lib/_emerge/SpawnProcess.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2008-2018 Gentoo Foundation
# Copyright 2008-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

try:
Expand All @@ -20,6 +20,7 @@
from portage.output import EOutput
from portage.util import writemsg_level
from portage.util._async.PipeLogger import PipeLogger
from portage.util.futures.compat_coroutine import coroutine

class SpawnProcess(SubProcess):

Expand All @@ -42,7 +43,10 @@ class SpawnProcess(SubProcess):
_CGROUP_CLEANUP_RETRY_MAX = 8

def _start(self):
self.scheduler.run_until_complete(self._async_start())

@coroutine
def _async_start(self):
if self.fd_pipes is None:
self.fd_pipes = {}
else:
Expand Down Expand Up @@ -142,8 +146,8 @@ def _start(self):
log_file_path=log_file_path,
stdout_fd=stdout_fd)
self._pipe_logger.addExitListener(self._pipe_logger_exit)
self._pipe_logger.start()
self._registered = True
yield self._pipe_logger.async_start()

def _can_log(self, slave_fd):
return True
Expand Down
4 changes: 2 additions & 2 deletions lib/portage/dbapi/bintree.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 1998-2019 Gentoo Authors
# Copyright 1998-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

from __future__ import unicode_literals
Expand Down Expand Up @@ -283,7 +283,7 @@ def unpack_contents(self, pkg, dest_dir):
logfile=settings.get('PORTAGE_LOG_FILE'),
scheduler=SchedulerInterface(loop))

extractor.start()
yield extractor.async_start()
yield extractor.async_wait()
if extractor.returncode != os.EX_OK:
raise PortageException("Error Extracting '{}'".format(pkg_path))
Expand Down
6 changes: 5 additions & 1 deletion lib/portage/tests/util/futures/test_iter_completed.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@
class SleepProcess(ForkProcess):
__slots__ = ('future', 'seconds')
def _start(self):
self.scheduler.run_until_complete(self._async_start())

@coroutine
def _async_start(self):
self.addExitListener(self._future_done)
ForkProcess._start(self)
yield ForkProcess._async_start(self)

def _future_done(self, task):
if not self.future.cancelled():
Expand Down
9 changes: 7 additions & 2 deletions lib/portage/util/_async/AsyncFunction.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# Copyright 2015 Gentoo Foundation
# Copyright 2015-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

import pickle
import traceback

from portage import os
from portage.util._async.ForkProcess import ForkProcess
from portage.util.futures.compat_coroutine import coroutine
from _emerge.PipeReader import PipeReader

class AsyncFunction(ForkProcess):
Expand All @@ -22,6 +23,10 @@ class AsyncFunction(ForkProcess):
'_async_func_reader', '_async_func_reader_pw')

def _start(self):
self.scheduler.run_until_complete(self._async_start())

@coroutine
def _async_start(self):
pr, pw = os.pipe()
self.fd_pipes = {}
self.fd_pipes[pw] = pw
Expand All @@ -31,7 +36,7 @@ def _start(self):
scheduler=self.scheduler)
self._async_func_reader.addExitListener(self._async_func_reader_exit)
self._async_func_reader.start()
ForkProcess._start(self)
yield ForkProcess._async_start(self)
os.close(pw)

def _run(self):
Expand Down
9 changes: 7 additions & 2 deletions lib/portage/util/_async/FileDigester.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Copyright 2013 Gentoo Foundation
# Copyright 2013-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

from portage import os
from portage.checksum import perform_multiple_checksums
from portage.util._async.ForkProcess import ForkProcess
from portage.util.futures.compat_coroutine import coroutine
from _emerge.PipeReader import PipeReader

class FileDigester(ForkProcess):
Expand All @@ -18,6 +19,10 @@ class FileDigester(ForkProcess):
'_digest_pipe_reader', '_digest_pw')

def _start(self):
self.scheduler.run_until_complete(self._async_start())

@coroutine
def _async_start(self):
pr, pw = os.pipe()
self.fd_pipes = {}
self.fd_pipes[pw] = pw
Expand All @@ -27,7 +32,7 @@ def _start(self):
scheduler=self.scheduler)
self._digest_pipe_reader.addExitListener(self._digest_pipe_reader_exit)
self._digest_pipe_reader.start()
ForkProcess._start(self)
yield ForkProcess._async_start(self)
os.close(pw)

def _run(self):
Expand Down

0 comments on commit 5c40c3e

Please sign in to comment.