Chromium Code Reviews| Index: third_party/buildbot_8_4p1/buildbot/status/builder.py |
| diff --git a/third_party/buildbot_8_4p1/buildbot/status/builder.py b/third_party/buildbot_8_4p1/buildbot/status/builder.py |
| index 3f42eb6f7e445be7020d9cd79108f854d7abc97c..0af0f2ddcd245cfc0dbe0b1296417c6e57860923 100644 |
| --- a/third_party/buildbot_8_4p1/buildbot/status/builder.py |
| +++ b/third_party/buildbot_8_4p1/buildbot/status/builder.py |
| @@ -17,6 +17,7 @@ |
| import weakref |
| import gc |
| import os, re, itertools |
| +import random |
| from cPickle import load, dump |
| from zope.interface import implements |
| @@ -323,17 +324,58 @@ class BuilderStatus(styles.Versioned): |
| def getCategory(self): |
| return self.category |
| - def getBuild(self, number): |
| - if number < 0: |
| - number = self.nextBuildNumber + number |
| - if number < 0 or number >= self.nextBuildNumber: |
| + def _resolveBuildNumber(self, build_number): |
|
Isaac (away)
2013/07/02 06:01:42
and this one should be number.
|
| + if build_number < 0: |
| + build_number = self.nextBuildNumber + build_number |
| + if build_number < 0 or build_number >= self.nextBuildNumber: |
| return None |
| + return build_number |
| + def _safeGetBuild(self, number): |
|
Isaac (away)
2013/07/02 06:01:42
this variable should be build_number
|
| try: |
| return self.getBuildByNumber(number) |
| except IndexError: |
| return None |
| + def getBuild(self, number): |
| + number = self._resolveBuildNumber(number) |
| + |
| + if number is None: |
| + return None |
| + |
| + return self._safeGetBuild(number) |
| + |
| + def getBuilds(self, numbers): |
| + """Cache-aware method to get multiple builds. |
| + |
| + Prevents cascading evict/load when multiple builds are requested in |
| + succession: requesting build 1 evicts build 2, requesting build 2 evicts |
| + build 3, etc. |
| + |
| + We query the buildCache and load hits first, then misses. When loading, |
| + we randomize the load order to alleviate the problem when external web |
| + requests load builds sequentially (they don't have access to this |
| + function). |
| + """ |
| + |
| + numbers = list(enumerate(self._resolveBuildNumber(x) for x in numbers)) |
| + random.shuffle(numbers) |
| + |
| + builds = [None] * len(numbers) |
| + misses = [] |
| + for idx, build_number in numbers: |
| + if build_number is None: |
| + continue |
| + if build_number in self.buildCache.cache: |
| + builds[idx] = self._safeGetBuild(build_number) |
| + else: |
| + misses.append((idx, build_number)) |
| + |
| + for idx, build_number in misses: |
| + builds[idx] = self._safeGetBuild(build_number) |
| + |
| + return builds |
| + |
| def getEvent(self, number): |
| try: |
| return self.events[number] |
| @@ -616,6 +658,11 @@ class BuilderStatus(styles.Versioned): |
| # Collect build numbers. |
| # Important: Only grab the *cached* builds numbers to reduce I/O. |
| current_builds = [b.getNumber() for b in self.currentBuilds] |
| + |
| + # Populates buildCache with last N builds. |
| + buildnums = range(-1, -(self.buildCacheSize - 1), -1) |
| + self.getBuilds(buildnums) |
| + |
| cached_builds = list(set(self.buildCache.cache.keys() + current_builds)) |
| cached_builds.sort() |
| result['cachedBuilds'] = cached_builds |