Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(572)

Side by Side Diff: third_party/buildbot_8_4p1/buildbot/status/web/status_json.py

Issue 13619004: Only calculate slave->build mapping once in json output. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Address nits. Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # This file is part of Buildbot. Buildbot is free software: you can 1 # This file is part of Buildbot. Buildbot is free software: you can
2 # redistribute it and/or modify it under the terms of the GNU General Public 2 # redistribute it and/or modify it under the terms of the GNU General Public
3 # License as published by the Free Software Foundation, version 2. 3 # License as published by the Free Software Foundation, version 2.
4 # 4 #
5 # This program is distributed in the hope that it will be useful, but WITHOUT 5 # This program is distributed in the hope that it will be useful, but WITHOUT
6 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 6 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
7 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 7 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
8 # details. 8 # details.
9 # 9 #
10 # You should have received a copy of the GNU General Public License along with 10 # You should have received a copy of the GNU General Public License along with
11 # this program; if not, write to the Free Software Foundation, Inc., 51 11 # this program; if not, write to the Free Software Foundation, Inc., 51
12 # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 12 # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
13 # 13 #
14 # Portions Copyright Buildbot Team Members 14 # Portions Copyright Buildbot Team Members
15 # Original Copyright (c) 2010 The Chromium Authors. 15 # Original Copyright (c) 2010 The Chromium Authors.
16 16
17 """Simple JSON exporter.""" 17 """Simple JSON exporter."""
18 18
19 import collections
19 import datetime 20 import datetime
20 import os 21 import os
21 import re 22 import re
22 23
23 from twisted.internet import defer 24 from twisted.internet import defer
24 from twisted.web import html, resource, server 25 from twisted.web import html, resource, server
25 26
26 from buildbot.status.web.base import HtmlResource 27 from buildbot.status.web.base import HtmlResource
27 from buildbot.util import json 28 from buildbot.util import json
28 29
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 BuilderJsonResource(status, 408 BuilderJsonResource(status,
408 status.getBuilder(builder_name))) 409 status.getBuilder(builder_name)))
409 410
410 411
411 class BuilderSlavesJsonResources(JsonResource): 412 class BuilderSlavesJsonResources(JsonResource):
412 help = """Describe the slaves attached to a single builder. 413 help = """Describe the slaves attached to a single builder.
413 """ 414 """
414 pageTitle = 'BuilderSlaves' 415 pageTitle = 'BuilderSlaves'
415 416
416 def __init__(self, status, builder_status): 417 def __init__(self, status, builder_status):
418 buildcache = collections.defaultdict(dict)
M-A Ruel 2013/04/06 01:23:46 Why not create a single global instance? It'd be s
Mike Stip (use stip instead) 2013/04/06 01:30:28 Because this is per-request. It's only a cache whi
417 JsonResource.__init__(self, status) 419 JsonResource.__init__(self, status)
418 self.builder_status = builder_status 420 self.builder_status = builder_status
419 for slave_name in self.builder_status.slavenames: 421 for slave_name in self.builder_status.slavenames:
420 self.putChild(slave_name, 422 self.putChild(slave_name,
421 SlaveJsonResource(status, 423 SlaveJsonResource(status,
422 self.status.getSlave(slave_name))) 424 self.status.getSlave(slave_name),
425 buildcache=buildcache))
423 426
424 427
425 class BuildJsonResource(JsonResource): 428 class BuildJsonResource(JsonResource):
426 help = """Describe a single build. 429 help = """Describe a single build.
427 """ 430 """
428 pageTitle = 'Build' 431 pageTitle = 'Build'
429 432
430 def __init__(self, status, build_status): 433 def __init__(self, status, build_status):
431 JsonResource.__init__(self, status) 434 JsonResource.__init__(self, status)
432 self.build_status = build_status 435 self.build_status = build_status
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 616
614 def asDict(self, request): 617 def asDict(self, request):
615 return self.status.asDict() 618 return self.status.asDict()
616 619
617 620
618 class SlaveJsonResource(JsonResource): 621 class SlaveJsonResource(JsonResource):
619 help = """Describe a slave. 622 help = """Describe a slave.
620 """ 623 """
621 pageTitle = 'Slave' 624 pageTitle = 'Slave'
622 625
623 def __init__(self, status, slave_status): 626 def __init__(self, status, slave_status, buildcache=None):
624 JsonResource.__init__(self, status) 627 JsonResource.__init__(self, status)
625 self.slave_status = slave_status 628 self.slave_status = slave_status
626 self.name = self.slave_status.getName() 629 self.name = self.slave_status.getName()
627 self.builders = None 630 self.builders = None
628 631
632 # buildcache is used to cache build information across multiple
633 # invocations of SlaveJsonResource. It should be set to an empty
634 # collections.defaultdict(dict). Without it, each invocation will
635 # do a full build scan.
636 self.buildcache = buildcache or collections.defaultdict(dict)
637
629 def getBuilders(self): 638 def getBuilders(self):
630 if self.builders is None: 639 if self.builders is None:
631 # Figure out all the builders to which it's attached 640 # Figure out all the builders to which it's attached
632 self.builders = [] 641 self.builders = []
633 for builderName in self.status.getBuilderNames(): 642 for builderName in self.status.getBuilderNames():
634 if self.name in self.status.getBuilder(builderName).slavenames: 643 if self.name in self.status.getBuilder(builderName).slavenames:
635 self.builders.append(builderName) 644 self.builders.append(builderName)
636 return self.builders 645 return self.builders
637 646
638 def asDict(self, request): 647 def mapSlavesToBuilds(self):
Isaac (away) 2013/04/05 23:45:01 delete this method and inline to line 662
Mike Stip (use stip instead) 2013/04/06 01:30:28 Done.
639 results = self.slave_status.asDict()
640 # Enhance it by adding more informations.
641 results['builders'] = {}
642 for builderName in self.getBuilders(): 648 for builderName in self.getBuilders():
643 builds = [] 649 builds = []
644 builder_status = self.status.getBuilder(builderName) 650 builder_status = self.status.getBuilder(builderName)
645 for i in range(1, builder_status.buildCacheSize - 1): 651 for i in range(1, builder_status.buildCacheSize - 1):
646 build_status = builder_status.getBuild(-i) 652 build_status = builder_status.getBuild(-i)
647 if not build_status or not build_status.isFinished(): 653 if not build_status or not build_status.isFinished():
648 # If not finished, it will appear in runningBuilds. 654 # If not finished, it will appear in runningBuilds.
649 break 655 break
650 if build_status.getSlavename() == self.name: 656 slave = self.buildcache[build_status.getSlavename()]
651 builds.append(build_status.getNumber()) 657 slave.setdefault(builderName, []).append(
M-A Ruel 2013/04/06 01:23:46 Note that it is effectively a memory leak, not a b
Mike Stip (use stip instead) 2013/04/06 01:30:28 buildcache gets thrown away after every request.
652 results['builders'][builderName] = builds 658 build_status.getNumber())
659
660 def getSlaveBuildMap(self):
661 if not self.buildcache:
662 self.mapSlavesToBuilds()
663 return self.buildcache[self.name]
664
665 def asDict(self, request):
666 results = self.slave_status.asDict()
667 # Enhance it by adding more informations.
668 results['builders'] = self.getSlaveBuildMap()
653 return results 669 return results
654 670
655 671
656 class SlavesJsonResource(JsonResource): 672 class SlavesJsonResource(JsonResource):
657 help = """List the registered slaves. 673 help = """List the registered slaves.
658 """ 674 """
659 pageTitle = 'Slaves' 675 pageTitle = 'Slaves'
660 676
661 def __init__(self, status): 677 def __init__(self, status):
678 buildcache = collections.defaultdict(dict)
662 JsonResource.__init__(self, status) 679 JsonResource.__init__(self, status)
663 for slave_name in status.getSlaveNames(): 680 for slave_name in status.getSlaveNames():
664 self.putChild(slave_name, 681 self.putChild(slave_name,
665 SlaveJsonResource(status, 682 SlaveJsonResource(status,
666 status.getSlave(slave_name))) 683 status.getSlave(slave_name),
684 buildcache=buildcache))
667 685
668 686
669 class SourceStampJsonResource(JsonResource): 687 class SourceStampJsonResource(JsonResource):
670 help = """Describe the sources for a SourceStamp. 688 help = """Describe the sources for a SourceStamp.
671 """ 689 """
672 pageTitle = 'SourceStamp' 690 pageTitle = 'SourceStamp'
673 691
674 def __init__(self, status, source_stamp): 692 def __init__(self, status, source_stamp):
675 # buildbot.sourcestamp.SourceStamp 693 # buildbot.sourcestamp.SourceStamp
676 JsonResource.__init__(self, status) 694 JsonResource.__init__(self, status)
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 if not builder: 756 if not builder:
739 return 757 return
740 EXAMPLES = EXAMPLES.replace('<A_BUILDER>', builder.getName()) 758 EXAMPLES = EXAMPLES.replace('<A_BUILDER>', builder.getName())
741 build = builder.getBuild(-1) 759 build = builder.getBuild(-1)
742 if build: 760 if build:
743 EXAMPLES = EXAMPLES.replace('<A_BUILD>', str(build.getNumber())) 761 EXAMPLES = EXAMPLES.replace('<A_BUILD>', str(build.getNumber()))
744 if builder.slavenames: 762 if builder.slavenames:
745 EXAMPLES = EXAMPLES.replace('<A_SLAVE>', builder.slavenames[0]) 763 EXAMPLES = EXAMPLES.replace('<A_SLAVE>', builder.slavenames[0])
746 764
747 # vim: set ts=4 sts=4 sw=4 et: 765 # vim: set ts=4 sts=4 sw=4 et:
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698