1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16  from twisted.internet import defer, reactor 
 17  from twisted.python import log 
 18  from buildbot import util 
 19  from buildbot.util import bbcollections, NotABranch 
 20  from buildbot.changes import filter, changes 
 21  from buildbot.schedulers import base, dependent 
 24      """ 
 25      @param onlyImportant: If True, only important changes will be added to the 
 26                            buildset. 
 27      @type onlyImportant: boolean 
 28   
 29      """ 
 30   
 31      compare_attrs = (base.BaseScheduler.compare_attrs + 
 32                       ('treeStableTimer', 'change_filter', 'fileIsImportant', 
 33                        'onlyImportant') ) 
 34   
 35      _reactor = reactor  
 36   
 38 -    def __init__(self, name, shouldntBeSet=NotSet, treeStableTimer=None, 
 39                  builderNames=None, branch=NotABranch, branches=NotABranch, 
 40                  fileIsImportant=None, properties={}, categories=None, 
 41                  change_filter=None, onlyImportant=False): 
  42          assert shouldntBeSet is self.NotSet, \ 
 43                  "pass arguments to schedulers using keyword arguments" 
 44          if fileIsImportant: 
 45              assert callable(fileIsImportant) 
 46   
 47           
 48          base.BaseScheduler.__init__(self, name, builderNames, properties) 
 49   
 50          self.treeStableTimer = treeStableTimer 
 51          self.fileIsImportant = fileIsImportant 
 52          self.onlyImportant = onlyImportant 
 53          self.change_filter = self.getChangeFilter(branch=branch, 
 54                  branches=branches, change_filter=change_filter, 
 55                  categories=categories) 
 56   
 57           
 58           
 59          self._stable_timers = bbcollections.defaultdict(lambda : None) 
 60          self._stable_timers_lock = defer.DeferredLock() 
  61   
 63          raise NotImplementedError 
  64   
 92   
 94           
 95          d = base.BaseScheduler.stopService(self) 
 96          d.addCallback(lambda _ : 
 97                  self._stable_timers_lock.acquire()) 
 98          def cancel_timers(_): 
 99              for timer in self._stable_timers.values(): 
100                  if timer: 
101                      timer.cancel() 
102              self._stable_timers = {} 
103              self._stable_timers_lock.release() 
 104          d.addCallback(cancel_timers) 
105          return d 
 106   
107      @util.deferredLocked('_stable_timers_lock') 
109          if not self.treeStableTimer: 
110               
111               
112              if not important: 
113                  return defer.succeed(None) 
114   
115               
116              return self.addBuildsetForChanges(reason='scheduler', 
117                              changeids=[ change.number ]) 
118   
119          timer_name = self.getTimerNameForChange(change) 
120   
121           
122           
123           
124           
125          d = self.master.db.schedulers.classifyChanges( 
126                  self.schedulerid, { change.number : important }) 
127          def fix_timer(_): 
128              if not important and not self._stable_timers[timer_name]: 
129                  return 
130              if self._stable_timers[timer_name]: 
131                  self._stable_timers[timer_name].cancel() 
132              self._stable_timers[timer_name] = self._reactor.callLater( 
133                      self.treeStableTimer, self.stableTimerFired, timer_name) 
 134          d.addCallback(fix_timer) 
135          return d 
136   
137      @defer.deferredGenerator 
139           
140           
141           
142   
143           
144           
145          wfd = defer.waitForDeferred( 
146              self.master.db.schedulers.getChangeClassifications( 
147                                                          self.schedulerid)) 
148          yield wfd 
149          classifications = wfd.getResult() 
150   
151           
152          for changeid, important in classifications.iteritems(): 
153              wfd = defer.waitForDeferred( 
154                  self.master.db.changes.getChange(changeid)) 
155              yield wfd 
156              chdict = wfd.getResult() 
157   
158              if not chdict: 
159                  continue 
160   
161              wfd = defer.waitForDeferred( 
162                  changes.Change.fromChdict(self.master, chdict)) 
163              yield wfd 
164              change = wfd.getResult() 
165   
166              wfd = defer.waitForDeferred( 
167                  self.gotChange(change, important)) 
168              yield wfd 
169              wfd.getResult() 
 170   
172          raise NotImplementedError  
 173   
175          """similar to db.schedulers.getChangeClassifications, but given timer 
176          name""" 
177          raise NotImplementedError  
 178   
179      @util.deferredLocked('_stable_timers_lock') 
180      @defer.deferredGenerator 
182           
183          if not self._stable_timers[timer_name]: 
184              return 
185   
186           
187          del self._stable_timers[timer_name] 
188   
189          wfd = defer.waitForDeferred( 
190                  self.getChangeClassificationsForTimer(self.schedulerid, 
191                                                        timer_name)) 
192          yield wfd 
193          classifications = wfd.getResult() 
194   
195           
196          if not classifications:  
197              return 
198   
199          changeids = sorted(classifications.keys()) 
200          wfd = defer.waitForDeferred( 
201                  self.addBuildsetForChanges(reason='scheduler', 
202                                             changeids=changeids)) 
203          yield wfd 
204          wfd.getResult() 
205   
206          max_changeid = changeids[-1]  
207          wfd = defer.waitForDeferred( 
208                  self.master.db.schedulers.flushChangeClassifications( 
209                              self.schedulerid, less_than=max_changeid+1)) 
210          yield wfd 
211          wfd.getResult() 
 212   
231   
234      "alias for SingleBranchScheduler" 
236          log.msg("WARNING: the name 'Scheduler' is deprecated; use " + 
237                  "buildbot.schedulers.basic.SingleBranchScheduler instead " + 
238                  "(note that this may require you to change your import " + 
239                  "statement)") 
240          SingleBranchScheduler.__init__(self, *args, **kwargs) 
  241   
257   
258   
259  Dependent = dependent.Dependent 
260