Package buildbot :: Package schedulers :: Module dependent
[frames] | no frames]

Source Code for Module buildbot.schedulers.dependent

  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 
  3  # License as published by the Free Software Foundation, version 2. 
  4  # 
  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 
  7  # FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  8  # details. 
  9  # 
 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 
 12  # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
 13  # 
 14  # Copyright Buildbot Team Members 
 15   
 16  from twisted.internet import defer 
 17  from twisted.python import log 
 18  from buildbot import util, interfaces, config 
 19  from buildbot.status.results import SUCCESS, WARNINGS 
 20  from buildbot.schedulers import base 
21 22 -class Dependent(base.BaseScheduler):
23 24 compare_attrs = base.BaseScheduler.compare_attrs + ('upstream_name',) 25
26 - def __init__(self, name, upstream, builderNames, properties={}, **kwargs):
27 base.BaseScheduler.__init__(self, name, builderNames, properties, 28 **kwargs) 29 if not interfaces.IScheduler.providedBy(upstream): 30 config.error( 31 "upstream must be another Scheduler instance") 32 self.upstream_name = upstream.name 33 self._buildset_addition_subscr = None 34 self._buildset_completion_subscr = None 35 self._cached_upstream_bsids = None 36 37 # the subscription lock makes sure that we're done inserting a 38 # subcription into the DB before registering that the buildset is 39 # complete. 40 self._subscription_lock = defer.DeferredLock()
41
42 - def startService(self):
43 self._buildset_addition_subscr = \ 44 self.master.subscribeToBuildsets(self._buildsetAdded) 45 self._buildset_completion_subscr = \ 46 self.master.subscribeToBuildsetCompletions(self._buildsetCompleted) 47 48 # check for any buildsets completed before we started 49 d = self._checkCompletedBuildsets(None, None) 50 d.addErrback(log.err, 'while checking for completed buildsets in start')
51
52 - def stopService(self):
53 if self._buildset_addition_subscr: 54 self._buildset_addition_subscr.unsubscribe() 55 if self._buildset_completion_subscr: 56 self._buildset_completion_subscr.unsubscribe() 57 self._cached_upstream_bsids = None 58 return defer.succeed(None)
59 60 @util.deferredLocked('_subscription_lock')
61 - def _buildsetAdded(self, bsid=None, properties=None, **kwargs):
62 # check if this was submitetted by our upstream by checking the 63 # scheduler property 64 submitter = properties.get('scheduler', (None, None))[0] 65 if submitter != self.upstream_name: 66 return 67 68 # record our interest in this buildset 69 d = self._addUpstreamBuildset(bsid) 70 d.addErrback(log.err, 'while subscribing to buildset %d' % bsid)
71
72 - def _buildsetCompleted(self, bsid, result):
73 d = self._checkCompletedBuildsets(bsid, result) 74 d.addErrback(log.err, 'while checking for completed buildsets')
75 76 @util.deferredLocked('_subscription_lock') 77 @defer.inlineCallbacks
78 - def _checkCompletedBuildsets(self, bsid, result):
79 subs = yield self._getUpstreamBuildsets() 80 81 sub_bsids = [] 82 for (sub_bsid, sub_sssetid, sub_complete, sub_results) in subs: 83 # skip incomplete builds, handling the case where the 'complete' 84 # column has not been updated yet 85 if not sub_complete and sub_bsid != bsid: 86 continue 87 88 # build a dependent build if the status is appropriate 89 if sub_results in (SUCCESS, WARNINGS): 90 yield self.addBuildsetForSourceStamp(setid=sub_sssetid, 91 reason='downstream') 92 93 sub_bsids.append(sub_bsid) 94 95 # and regardless of status, remove the subscriptions 96 yield self._removeUpstreamBuildsets(sub_bsids)
97 98 @defer.inlineCallbacks
100 if self._cached_upstream_bsids is None: 101 bsids = yield self.master.db.state.getState(self.objectid, 102 'upstream_bsids', []) 103 self._cached_upstream_bsids = bsids
104 105 @defer.inlineCallbacks
106 - def _getUpstreamBuildsets(self):
107 # get a list of (bsid, sssid, complete, results) for all 108 # upstream buildsets 109 yield self._updateCachedUpstreamBuilds() 110 111 changed = False 112 rv = [] 113 for bsid in self._cached_upstream_bsids[:]: 114 bsdict = yield self.master.db.buildsets.getBuildset(bsid) 115 if not bsdict: 116 self._cached_upstream_bsids.remove(bsid) 117 changed = True 118 continue 119 120 rv.append((bsid, bsdict['sourcestampsetid'], bsdict['complete'], 121 bsdict['results'])) 122 123 if changed: 124 yield self.master.db.state.setState(self.objectid, 125 'upstream_bsids', self._cached_upstream_bsids) 126 127 defer.returnValue(rv)
128 129 @defer.inlineCallbacks
130 - def _addUpstreamBuildset(self, bsid):
131 yield self._updateCachedUpstreamBuilds() 132 133 if bsid not in self._cached_upstream_bsids: 134 self._cached_upstream_bsids.append(bsid) 135 136 yield self.master.db.state.setState(self.objectid, 137 'upstream_bsids', self._cached_upstream_bsids)
138 139 @defer.inlineCallbacks
140 - def _removeUpstreamBuildsets(self, bsids):
141 yield self._updateCachedUpstreamBuilds() 142 143 old = set(self._cached_upstream_bsids) 144 self._cached_upstream_bsids = list(old - set(bsids)) 145 146 yield self.master.db.state.setState(self.objectid, 147 'upstream_bsids', self._cached_upstream_bsids)
148