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
diff --git a/phased-updater b/phased-updater
index e457e33..e072bc8 100755
--- a/phased-updater
+++ b/phased-updater
@@ -612,10 +612,11 @@ def main():
612612
613 releases = []613 releases = []
614 for series in ubuntu.series:614 for series in ubuntu.series:
615 if series.active:615 # XXX - trusty and xenial ESM
616 if series.status == 'Active Development':616 if not series.active or series.status == 'Active Development' \
617 continue617 or series.name in ('trusty', 'xenial'):
618 releases.append(series)618 continue
619 releases.append(series)
619 releases.reverse()620 releases.reverse()
620 issues = {}621 issues = {}
621 for release in releases:622 for release in releases:
@@ -624,9 +625,6 @@ def main():
624 rname = release.name625 rname = release.name
625 rvers = release.version626 rvers = release.version
626 issues[rname] = OrderedDict()627 issues[rname] = OrderedDict()
627 # XXX - trusty and xenial ESM
628 if rname in ('trusty', 'xenial'):
629 continue
630 pub_sources = archive.getPublishedSources(628 pub_sources = archive.getPublishedSources(
631 created_since_date=cdate,629 created_since_date=cdate,
632 order_by_date=True,630 order_by_date=True,
@@ -644,33 +642,31 @@ def main():
644 continue642 continue
645 version = pub_source.source_package_version643 version = pub_source.source_package_version
646 spph_link = pub_source.self_link644 spph_link = pub_source.self_link
647 pbs = None
648 try:645 try:
649 pbs = [pb for pb in pub_source.getPublishedBinaries()646 # the p-u-p is currently the same for all binary packages
650 if pb.phased_update_percentage is not None]647 pb = pub_source.getPublishedBinaries()[0]
648 last_pup = pb.phased_update_percentage
651 # workaround for LP: #1695113649 # workaround for LP: #1695113
652 except lazr.restfulclient.errors.ServerError as e:650 except lazr.restfulclient.errors.ServerError as e:
653 if 'HTTP Error 503' in str(e):651 if 'HTTP Error 503' in str(e):
654 logging.info('Skipping 503 Error for %s' % src_pkg)652 logging.info('Skipping 503 Error for %s' % src_pkg)
655 pass653 pass
656 if not pbs:654 # no binary publications
655 except IndexError:
656 continue
657 if last_pup is None:
657 continue658 continue
658 if pbs:
659 # the p-u-p is currently the same for all binary packages
660 last_pup = pbs[0].phased_update_percentage
661 else:
662 last_pup = None
663 max_pup = 0659 max_pup = 0
664 if last_pup == 0:660 if last_pup == 0:
665 for allpb in archive.getPublishedBinaries(661 for allpb in archive.getPublishedBinaries(
666 exact_match=True, pocket='Updates',662 exact_match=True, pocket='Updates',
667 binary_name=pbs[0].binary_package_name):663 binary_name=pb.binary_package_name):
668 if allpb.distro_arch_series.distroseries == release:664 if allpb.distro_arch_series.distroseries == release:
669 if allpb.phased_update_percentage > 0:665 if allpb.phased_update_percentage > 0:
670 max_pup = allpb.phased_update_percentage666 max_pup = allpb.phased_update_percentage
671 break667 break
672 if pbs[0].creator_link:668 if pb.creator_link:
673 creator = pbs[0].creator_link.split('/')[-1]669 creator = pb.creator_link.split('/')[-1]
674 else:670 else:
675 creator = '~ubuntu-archive-robot'671 creator = '~ubuntu-archive-robot'
676 # the phasing was manually set to 0 by someone672 # the phasing was manually set to 0 by someone
@@ -707,19 +703,17 @@ def main():
707 if spph_link not in issues[rname]:703 if spph_link not in issues[rname]:
708 issues[rname][spph_link] = {}704 issues[rname][spph_link] = {}
709 issues[rname][spph_link]['rate'] = rate_increase705 issues[rname][spph_link]['rate'] = rate_increase
710 if pbs:706 if spph_link not in issues[rname]:
711 if spph_link not in issues[rname]:707 issues[rname][spph_link] = {}
712 issues[rname][spph_link] = {}708 # phasing has stopped so check what the max value was
713 # phasing has stopped so check what the max value was709 if last_pup == 0:
714 if last_pup == 0:710 issues[rname][spph_link]['max_pup'] = max_pup
715 issues[rname][spph_link]['max_pup'] = max_pup711 issues[rname][spph_link]['pup'] = last_pup
716 issues[rname][spph_link]['pup'] = last_pup
717 suite = rname + '-updates'712 suite = rname + '-updates'
718 if spph_link not in issues[rname]:713 if spph_link not in issues[rname]:
719 continue714 continue
720 elif ('rate' not in issues[rname][spph_link] and715 elif ('rate' not in issues[rname][spph_link] and
721 'buckets' not in issues[rname][spph_link] and716 'buckets' not in issues[rname][spph_link]):
722 pbs):
723 # there is not an error so increment the phasing717 # there is not an error so increment the phasing
724 current_pup = issues[rname][spph_link]['pup']718 current_pup = issues[rname][spph_link]['pup']
725 # if this is an update that is restarting we want to start at719 # if this is an update that is restarting we want to start at
@@ -734,7 +728,7 @@ def main():
734 if not options.no_act:728 if not options.no_act:
735 set_pup(current_pup, new_pup, release, suite, src_pkg)729 set_pup(current_pup, new_pup, release, suite, src_pkg)
736 issues[rname][spph_link]['pup'] = new_pup730 issues[rname][spph_link]['pup'] = new_pup
737 elif pbs:731 else:
738 # there is an error and pup is not None so stop the phasing732 # there is an error and pup is not None so stop the phasing
739 current_pup = issues[rname][spph_link]['pup']733 current_pup = issues[rname][spph_link]['pup']
740 if 'max_pup' in issues[rname][spph_link]:734 if 'max_pup' in issues[rname][spph_link]:

Subscribers

People subscribed via source and target branches