Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o, Brian Dolbec <dolsen@g.o>
Subject: Re: [gentoo-portage-dev] [PATCH] BinpkgFetcher: use async lock (bug 614110)
Date: Sun, 22 Apr 2018 22:38:17
Message-Id: b857bc30-9344-7b38-1d70-956b1c257c24@gentoo.org
In Reply to: Re: [gentoo-portage-dev] [PATCH] BinpkgFetcher: use async lock (bug 614110) by Brian Dolbec
1 On 04/21/2018 03:07 PM, Brian Dolbec wrote:
2 > On Sat, 21 Apr 2018 12:27:28 -0700
3 > Zac Medico <zmedico@g.o> wrote:
4 >
5 >> In order to avoid event loop recursion, convert the
6 >> _BinpkgFetcherProcess.lock() method to an async_lock
7 >> method for use by BinpkgFetcher.
8 >>
9 >> Bug: https://bugs.gentoo.org/614110
10 >> ---
11 >> pym/_emerge/BinpkgFetcher.py | 53
12 >> +++++++++++++++++++++++++++----------------- 1 file changed, 33
13 >> insertions(+), 20 deletions(-)
14 >>
15 >> diff --git a/pym/_emerge/BinpkgFetcher.py
16 >> b/pym/_emerge/BinpkgFetcher.py index 5ca7a45cf..2bbc0a26f 100644
17 >> --- a/pym/_emerge/BinpkgFetcher.py
18 >> +++ b/pym/_emerge/BinpkgFetcher.py
19 >> @@ -32,11 +32,24 @@ class BinpkgFetcher(CompositeTask):
20 >> pkg.cpv) + ".partial"
21 >>
22 >> def _start(self):
23 >> - self._start_task(
24 >> -
25 >> _BinpkgFetcherProcess(background=self.background,
26 >> - logfile=self.logfile, pkg=self.pkg,
27 >> pkg_path=self.pkg_path,
28 >> - pretend=self.pretend,
29 >> scheduler=self.scheduler),
30 >> - self._fetcher_exit)
31 >> + fetcher =
32 >> _BinpkgFetcherProcess(background=self.background,
33 >> + logfile=self.logfile, pkg=self.pkg,
34 >> pkg_path=self.pkg_path,
35 >> + pretend=self.pretend,
36 >> scheduler=self.scheduler) +
37 >> + if not self.pretend:
38 >> +
39 >> portage.util.ensure_dirs(os.path.dirname(self.pkg_path))
40 >> + if "distlocks" in
41 >> self.pkg.root_config.settings.features:
42 >> + self._start_task(
43 >> +
44 >> AsyncTaskFuture(future=fetcher.async_lock()),
45 >> +
46 >> functools.partial(self._start_locked, fetcher))
47 >> + return
48 >> +
49 >> + self._start_task(fetcher, self._fetcher_exit)
50 >> +
51 >> + def _start_locked(self, fetcher, lock_task):
52 >> + self._assert_current(lock_task)
53 >> + lock_task.future.result()
54 >> + self._start_task(fetcher, self._fetcher_exit)
55 >>
56 >> def _fetcher_exit(self, fetcher):
57 >> self._assert_current(fetcher)
58 >> @@ -68,13 +81,8 @@ class _BinpkgFetcherProcess(SpawnProcess):
59 >> pretend = self.pretend
60 >> bintree = pkg.root_config.trees["bintree"]
61 >> settings = bintree.settings
62 >> - use_locks = "distlocks" in settings.features
63 >> pkg_path = self.pkg_path
64 >>
65 >> - if not pretend:
66 >> -
67 >> portage.util.ensure_dirs(os.path.dirname(pkg_path))
68 >> - if use_locks:
69 >> - self.lock()
70 >> exists = os.path.exists(pkg_path)
71 >> resume = exists and os.path.basename(pkg_path) in
72 >> bintree.invalids if not (pretend or resume):
73 >> @@ -184,7 +192,7 @@ class _BinpkgFetcherProcess(SpawnProcess):
74 >> except
75 >> OSError: pass
76 >>
77 >> - def lock(self):
78 >> + def async_lock(self):
79 >> """
80 >> This raises an AlreadyLocked exception if lock() is
81 >> called while a lock is already held. In order to avoid this, call
82 >> @@ -194,17 +202,22 @@ class _BinpkgFetcherProcess(SpawnProcess):
83 >> if self._lock_obj is not None:
84 >> raise self.AlreadyLocked((self._lock_obj,))
85 >>
86 >> - async_lock = AsynchronousLock(path=self.pkg_path,
87 >> - scheduler=self.scheduler)
88 >> - async_lock.start()
89 >> + result = self.scheduler.create_future()
90 >>
91 >> - if async_lock.wait() != os.EX_OK:
92 >> - # TODO: Use CompositeTask for better
93 >> handling, like in EbuildPhase.
94 >> - raise AssertionError("AsynchronousLock
95 >> failed with returncode %s" \
96 >> - % (async_lock.returncode,))
97 >> + def acquired_lock(async_lock):
98 >> + if async_lock.wait() == os.EX_OK:
99 >> + self.locked = True
100 >> + result.set_result(None)
101 >> + else:
102 >> + result.set_exception(AssertionError(
103 >> + "AsynchronousLock failed
104 >> with returncode %s"
105 >> + % (async_lock.returncode,)))
106 >>
107 >> - self._lock_obj = async_lock
108 >> - self.locked = True
109 >> + self._lock_obj = AsynchronousLock(path=self.pkg_path,
110 >> + scheduler=self.scheduler)
111 >> + self._lock_obj.addExitListener(acquired_lock)
112 >> + self._lock_obj.start()
113 >> + return result
114 >>
115 >> class AlreadyLocked(portage.exception.PortageException):
116 >> pass
117 >
118 >
119 > Looks fine to me :)
120 >
121
122 Thanks, merged:
123
124 https://gitweb.gentoo.org/proj/portage.git/commit/?id=adf2e6dd57b5bcaa4a668e3085024ebc3224a2ca
125
126 --
127 Thanks,
128 Zac

Attachments

File name MIME type
signature.asc application/pgp-signature