1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 import time
39
40 from buildbot import interfaces, util
41 from buildbot.util import collections, NotABranch
42 from buildbot.sourcestamp import SourceStamp
43 from buildbot.status.builder import SUCCESS, WARNINGS
44 from buildbot.schedulers import base
45
46 -class Scheduler(base.BaseScheduler, base.ClassifierMixin):
47 fileIsImportant = None
48 compare_attrs = ('name', 'treeStableTimer', 'builderNames',
49 'fileIsImportant', 'properties', 'change_filter')
50
51 - def __init__(self, name, shouldntBeSet=NotABranch, treeStableTimer=None,
52 builderNames=None, branch=NotABranch, fileIsImportant=None,
53 properties={}, categories=None, change_filter=None):
54 """
55 @param name: the name of this Scheduler
56 @param treeStableTimer: the duration, in seconds, for which the tree
57 must remain unchanged before a build is
58 triggered. This is intended to avoid builds
59 of partially-committed fixes. If None, then
60 a separate build will be made for each
61 Change, regardless of when they arrive.
62 @param builderNames: a list of Builder names. When this Scheduler
63 decides to start a set of builds, they will be
64 run on the Builders named by this list.
65
66 @param fileIsImportant: A callable which takes one argument (a Change
67 instance) and returns True if the change is
68 worth building, and False if it is not.
69 Unimportant Changes are accumulated until the
70 build is triggered by an important change.
71 The default value of None means that all
72 Changes are important.
73
74 @param properties: properties to apply to all builds started from
75 this scheduler
76
77 @param change_filter: a buildbot.schedulers.filter.ChangeFilter instance
78 used to filter changes for this scheduler
79
80 @param branch: The branch name that the Scheduler should pay
81 attention to. Any Change that is not in this branch
82 will be ignored. It can be set to None to only pay
83 attention to the default branch.
84 @param categories: A list of categories of changes to accept
85 """
86 assert shouldntBeSet is NotABranch, \
87 "pass arguments to Scheduler using keyword arguments"
88
89 base.BaseScheduler.__init__(self, name, builderNames, properties)
90 self.make_filter(change_filter=change_filter, branch=branch, categories=categories)
91 self.treeStableTimer = treeStableTimer
92 self.stableAt = None
93 self.branch = branch
94 if fileIsImportant:
95 assert callable(fileIsImportant)
96 self.fileIsImportant = fileIsImportant
97
99 return {"last_processed": max_changeid}
100
106
112
114 """Look at the changes that need to be processed and decide whether
115 to queue a BuildRequest or sleep until something changes.
116
117 If I decide that a build should be performed, I will add the
118 appropriate BuildRequest to the database queue, and remove the
119 (retired) changes that went into it from the scheduler_changes table.
120
121 Returns wakeup_delay: either None, or a float indicating when this
122 scheduler wants to be woken up next. The Scheduler is responsible for
123 padding its desired wakeup time by about a second to avoid frenetic
124 must-wake-up-at-exactly-8AM behavior. The Loop may silently impose a
125 minimum delay request of a couple seconds to prevent this sort of
126 thing, but Schedulers must still add their own padding to avoid at
127 least a double wakeup.
128 """
129
130 if not important:
131 return None
132 all_changes = important + unimportant
133 most_recent = max([c.when for c in all_changes])
134 if self.treeStableTimer is not None:
135 now = time.time()
136 self.stableAt = most_recent + self.treeStableTimer
137 if self.stableAt > now:
138
139
140 return self.stableAt + 1.0
141
142
143 self.stableAt = None
144 self._add_build_and_remove_changes(t, all_changes)
145 return None
146
163
164
166 if self.stableAt and self.stableAt > util.now():
167 return [ self.stableAt ]
168 return []
169
171 compare_attrs = ('name', 'treeStableTimer', 'builderNames',
172 'fileIsImportant', 'properties', 'change_filter')
173 - def __init__(self, name, treeStableTimer, builderNames,
174 fileIsImportant=None, properties={}, categories=None,
175 branches=NotABranch, change_filter=None):
176 """
177 Same parameters as the scheduler, but without 'branch', and adding:
178
179 @param branches: (deprecated)
180 """
181
182 Scheduler.__init__(self, name, builderNames=builderNames, properties=properties,
183 categories=categories, treeStableTimer=treeStableTimer,
184 fileIsImportant=fileIsImportant, change_filter=change_filter,
185
186 branch=branches)
187
189 db = self.parent.db
190 res = db.scheduler_get_classified_changes(self.schedulerid, t)
191 (important, unimportant) = res
192 def _twolists(): return [], []
193 branch_changes = collections.defaultdict(_twolists)
194 for c in important:
195 branch_changes[c.branch][0].append(c)
196 for c in unimportant:
197 branch_changes[c.branch][1].append(c)
198 delays = []
199 for branch in branch_changes:
200 (b_important, b_unimportant) = branch_changes[branch]
201 delay = self.decide_and_remove_changes(t, b_important,
202 b_unimportant)
203 if delay is not None:
204 delays.append(delay)
205 if delays:
206 return min(delays)
207 return None
208
210
211
212 compare_attrs = ('name', 'upstream_name', 'builderNames', 'properties')
213
214 - def __init__(self, name, upstream, builderNames, properties={}):
221
225
241
242
243
244
245
246
247
248
249
250
251
252
253
254