Merge ubuntu-archive-tools:optimize-phased-updater into ubuntu-archive-tools:main

Proposed by Steve Langasek
Status: Needs review
Proposed branch: ubuntu-archive-tools:optimize-phased-updater
Merge into: ubuntu-archive-tools:main
Diff against target: 110 lines (+23/-29)
1 file modified
phased-updater (+23/-29)
Reviewer Review Type Date Requested Status
Brian Murray Needs Information
Review via email: mp+426990@code.launchpad.net

Description of the change

This is a 30% reduction locally in the runtime of the phased-updater script; for a script that runs for 2 hours, that seems worth doing.

I do note one behavior difference here, which is that we are now only ever looking at the first record returned by getPublishedBinaries(), so if this ever returns a mix of records with p-u-p and without (such as with UEFI signed binaries?), we should instead loop over the records and break as soon as we find one that's non-null. That would reduce the runtime savings (especially as the majority of SRUs are going to be older kernel SRUs that have been fully phased and superseded), but might still be worthwhile.

To post a comment you must log in.
Revision history for this message
Steve Langasek (vorlon) wrote :

poked around with the API and confirmed that binary payloads for signing do not show up in the output of getPublishedBinaries(); so as long as the assumption holds that p-u-p is the same for all binaries from a source, this implementation should be safe, and a lot faster.

Revision history for this message
Steve Langasek (vorlon) wrote :

I've done a test run of the script here btw and the html output looks equivalent to https://people.canonical.com/~ubuntu-archive/phased-updates.html

Revision history for this message
Brian Murray (brian-murray) wrote (last edit ):

I was testing this today and ran it locally and then waited for the server to finish running its version of the report. Strangely, the one I ran locally show gce-compute-image-packages as being phased to 40% while the report on ubuntu-archive-team showed it as being phased to 30%. Additionally, checking in Launchpad right now show both binary packages as being phased at 30%. So I'm a bit concerned something is awry with this change and think it bears further investigation.

review: Needs Information

Unmerged commits

c2dd209... by Steve Langasek

Optimize the inner loop of phased-updater by not querying for extra binaries

Currently the code walks all of the binary publications for each SRU source,
but immediately afterwards there is a comment that "the p-u-p is currently
the same for all binary packages". This causes us to spend quite a lot of
time on API queries for other binaries, only to ignore the results.

Refactor the code to always only look at the first record returned from
getPublishedBinaries(), which has the same result *unless*
getPublishedBinaries() can return a mix of records with p-u-p and without;
and saves about 30% of the runtime of the script.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/phased-updater b/phased-updater
2index e457e33..e072bc8 100755
3--- a/phased-updater
4+++ b/phased-updater
5@@ -612,10 +612,11 @@ def main():
6
7 releases = []
8 for series in ubuntu.series:
9- if series.active:
10- if series.status == 'Active Development':
11- continue
12- releases.append(series)
13+ # XXX - trusty and xenial ESM
14+ if not series.active or series.status == 'Active Development' \
15+ or series.name in ('trusty', 'xenial'):
16+ continue
17+ releases.append(series)
18 releases.reverse()
19 issues = {}
20 for release in releases:
21@@ -624,9 +625,6 @@ def main():
22 rname = release.name
23 rvers = release.version
24 issues[rname] = OrderedDict()
25- # XXX - trusty and xenial ESM
26- if rname in ('trusty', 'xenial'):
27- continue
28 pub_sources = archive.getPublishedSources(
29 created_since_date=cdate,
30 order_by_date=True,
31@@ -644,33 +642,31 @@ def main():
32 continue
33 version = pub_source.source_package_version
34 spph_link = pub_source.self_link
35- pbs = None
36 try:
37- pbs = [pb for pb in pub_source.getPublishedBinaries()
38- if pb.phased_update_percentage is not None]
39+ # the p-u-p is currently the same for all binary packages
40+ pb = pub_source.getPublishedBinaries()[0]
41+ last_pup = pb.phased_update_percentage
42 # workaround for LP: #1695113
43 except lazr.restfulclient.errors.ServerError as e:
44 if 'HTTP Error 503' in str(e):
45 logging.info('Skipping 503 Error for %s' % src_pkg)
46 pass
47- if not pbs:
48+ # no binary publications
49+ except IndexError:
50+ continue
51+ if last_pup is None:
52 continue
53- if pbs:
54- # the p-u-p is currently the same for all binary packages
55- last_pup = pbs[0].phased_update_percentage
56- else:
57- last_pup = None
58 max_pup = 0
59 if last_pup == 0:
60 for allpb in archive.getPublishedBinaries(
61 exact_match=True, pocket='Updates',
62- binary_name=pbs[0].binary_package_name):
63+ binary_name=pb.binary_package_name):
64 if allpb.distro_arch_series.distroseries == release:
65 if allpb.phased_update_percentage > 0:
66 max_pup = allpb.phased_update_percentage
67 break
68- if pbs[0].creator_link:
69- creator = pbs[0].creator_link.split('/')[-1]
70+ if pb.creator_link:
71+ creator = pb.creator_link.split('/')[-1]
72 else:
73 creator = '~ubuntu-archive-robot'
74 # the phasing was manually set to 0 by someone
75@@ -707,19 +703,17 @@ def main():
76 if spph_link not in issues[rname]:
77 issues[rname][spph_link] = {}
78 issues[rname][spph_link]['rate'] = rate_increase
79- if pbs:
80- if spph_link not in issues[rname]:
81- issues[rname][spph_link] = {}
82- # phasing has stopped so check what the max value was
83- if last_pup == 0:
84- issues[rname][spph_link]['max_pup'] = max_pup
85- issues[rname][spph_link]['pup'] = last_pup
86+ if spph_link not in issues[rname]:
87+ issues[rname][spph_link] = {}
88+ # phasing has stopped so check what the max value was
89+ if last_pup == 0:
90+ issues[rname][spph_link]['max_pup'] = max_pup
91+ issues[rname][spph_link]['pup'] = last_pup
92 suite = rname + '-updates'
93 if spph_link not in issues[rname]:
94 continue
95 elif ('rate' not in issues[rname][spph_link] and
96- 'buckets' not in issues[rname][spph_link] and
97- pbs):
98+ 'buckets' not in issues[rname][spph_link]):
99 # there is not an error so increment the phasing
100 current_pup = issues[rname][spph_link]['pup']
101 # if this is an update that is restarting we want to start at
102@@ -734,7 +728,7 @@ def main():
103 if not options.no_act:
104 set_pup(current_pup, new_pup, release, suite, src_pkg)
105 issues[rname][spph_link]['pup'] = new_pup
106- elif pbs:
107+ else:
108 # there is an error and pup is not None so stop the phasing
109 current_pup = issues[rname][spph_link]['pup']
110 if 'max_pup' in issues[rname][spph_link]:

Subscribers

People subscribed via source and target branches