launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #16211
[Merge] lp:~wgrant/launchpad/antibfjo-2-garbo into lp:launchpad
William Grant has proposed merging lp:~wgrant/launchpad/antibfjo-2-garbo into lp:launchpad with lp:~wgrant/launchpad/antibfjo-1-set as a prerequisite.
Commit message:
Add a garbo job to backfill existing BuildQueue rows.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~wgrant/launchpad/antibfjo-2-garbo/+merge/195887
IBuildFarmJobOld and its implementations (BuildPackageJob, SourcePackageRecipeBuildJob, TranslationTemplatesBuildJob) are finally being replaced with an FK from BuildQueue to BuildFarmJob. Additionally, the two fields of Job that are used by BuildQueue are being inlined, and the FK to Job dropped, for performance reasons.
This branch adds a garbo job to backfill existing BuildQueue rows.
--
https://code.launchpad.net/~wgrant/launchpad/antibfjo-2-garbo/+merge/195887
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wgrant/launchpad/antibfjo-2-garbo into lp:launchpad.
=== modified file 'database/schema/security.cfg'
--- database/schema/security.cfg 2013-10-03 04:37:30 +0000
+++ database/schema/security.cfg 2013-11-20 00:21:46 +0000
@@ -2241,6 +2241,7 @@
public.bugtaskflat = SELECT
public.bugwatch = SELECT, UPDATE
public.bugwatchactivity = SELECT, DELETE
+public.buildqueue = SELECT, UPDATE
public.codeimportevent = SELECT, DELETE
public.codeimporteventdata = SELECT, DELETE
public.codeimportresult = SELECT, DELETE
=== modified file 'lib/lp/scripts/garbo.py'
--- lib/lp/scripts/garbo.py 2013-06-20 05:50:00 +0000
+++ lib/lp/scripts/garbo.py 2013-11-20 00:21:46 +0000
@@ -57,6 +57,8 @@
BugWatchScheduler,
MAX_SAMPLE_SIZE,
)
+from lp.buildmaster.enums import BuildQueueStatus
+from lp.buildmaster.model.buildqueue import BuildQueue
from lp.code.interfaces.revision import IRevisionSet
from lp.code.model.codeimportevent import CodeImportEvent
from lp.code.model.codeimportresult import CodeImportResult
@@ -99,6 +101,7 @@
from lp.services.identity.interfaces.emailaddress import EmailAddressStatus
from lp.services.identity.model.account import Account
from lp.services.identity.model.emailaddress import EmailAddress
+from lp.services.job.interfaces.job import JobStatus
from lp.services.job.model.job import Job
from lp.services.librarian.model import TimeLimitedToken
from lp.services.log.logger import PrefixFilter
@@ -1359,6 +1362,41 @@
transaction.commit()
+class BuildQueueMigrator(TunableLoop):
+ """Populate the status and build_farm_job columns of BuildQueue."""
+
+ maximum_chunk_size = 5000
+
+ status_map = {
+ JobStatus.WAITING: BuildQueueStatus.WAITING,
+ JobStatus.RUNNING: BuildQueueStatus.RUNNING,
+ JobStatus.SUSPENDED: BuildQueueStatus.SUSPENDED,
+ }
+
+ def __init__(self, log, abort_time=None):
+ super(BuildQueueMigrator, self).__init__(log, abort_time)
+ self.start_at = 1
+ self.store = IMasterStore(BuildQueue)
+
+ def findBuildQueues(self):
+ return self.store.find(
+ BuildQueue, BuildQueue.id >= self.start_at).order_by(BuildQueue.id)
+
+ def isDone(self):
+ return (
+ not getFeatureFlag('buildmaster.buildqueuemigrator.enabled')
+ or self.findBuildQueues().is_empty())
+
+ def __call__(self, chunk_size):
+ bqs = list(self.findBuildQueues()[:chunk_size])
+ for bq in bqs:
+ bq._build_farm_job = bq.specific_job.build.build_farm_job
+ bq._date_started = bq.job.date_started
+ bq.status = self.status_map[bq.job.status]
+ self.start_at = bqs[-1].id + 1
+ transaction.commit()
+
+
class BaseDatabaseGarbageCollector(LaunchpadCronScript):
"""Abstract base class to run a collection of TunableLoops."""
script_name = None # Script name for locking and database user. Override.
@@ -1613,6 +1651,7 @@
UnusedSessionPruner,
DuplicateSessionPruner,
BugHeatUpdater,
+ BuildQueueMigrator,
]
experimental_tunable_loops = []
=== modified file 'lib/lp/scripts/tests/test_garbo.py'
--- lib/lp/scripts/tests/test_garbo.py 2013-06-20 05:50:00 +0000
+++ lib/lp/scripts/tests/test_garbo.py 2013-11-20 00:21:46 +0000
@@ -1,5 +1,6 @@
-# Copyright 2009-2013 Canonical Ltd. This software is licensed under the
-# GNU Affero General Public License version 3 (see the file LICENSE).
+# Copyright 2009-2013 Canonical Ltd. This software is licensed under
+# the GNU Affero General Public License version 3 (see the file
+# LICENSE).
"""Test the database garbage collector."""
@@ -28,6 +29,7 @@
)
from storm.store import Store
from testtools.matchers import (
+ ContainsAll,
Equals,
GreaterThan,
)
@@ -41,6 +43,7 @@
BugNotification,
BugNotificationRecipient,
)
+from lp.buildmaster.interfaces.buildqueue import IBuildQueueSet
from lp.code.bzr import (
BranchFormat,
RepositoryFormat,
@@ -1023,6 +1026,36 @@
"SELECT COUNT(*) FROM BugSummaryJournal").get_one()[0]
self.assertThat(num_rows, Equals(0))
+ def test_BuildQueueMigrator(self):
+ switch_dbuser('testadmin')
+ store = IMasterStore(CommercialSubscription)
+ tbq = self.factory.makeTranslationTemplatesBuild().queueBuild()
+ sbq = self.factory.makeSourcePackageRecipeBuild().queueBuild()
+ bbq = self.factory.makeBinaryPackageBuild().queueBuild()
+ expected = [
+ (bq.id, bq.status.value,
+ removeSecurityProxy(bq)._build_farm_job.id)
+ for bq in (tbq, sbq, bbq)]
+
+ def get_bq_bits():
+ return store.execute(
+ "SELECT id, status, build_farm_job FROM buildqueue").get_all()
+
+ def count_bq_empties():
+ return store.execute(
+ "SELECT COUNT(*) FROM BuildQueue "
+ "WHERE status IS NULL OR build_farm_job IS NULL").get_one()[0]
+ self.assertThat(get_bq_bits(), ContainsAll(expected))
+ store.execute(
+ "UPDATE BuildQueue SET status = NULL, build_farm_job = NULL")
+ self.assertEqual(5, count_bq_empties())
+ IMasterStore(FeatureFlag).add(FeatureFlag(
+ u'default', 0, u'buildmaster.buildqueuemigrator.enabled',
+ u'please'))
+ self.runHourly()
+ self.assertThat(get_bq_bits(), ContainsAll(expected))
+ self.assertEqual(0, count_bq_empties())
+
def test_VoucherRedeemer(self):
switch_dbuser('testadmin')
Follow ups