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

Side by Side Diff: scripts/master/try_job_rietveld.py

Issue 330283006: New RietveldPollerWithCache is working stable. Removed old RietveldPoller and the flag to choose be… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 6 years, 6 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
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import datetime 5 import datetime
6 import hashlib 6 import hashlib
7 import json 7 import json
8 import os 8 import os
9 import pytz 9 import pytz
10 import time 10 import time
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 postdata=urllib.urlencode(params)) 97 postdata=urllib.urlencode(params))
98 98
99 def _MakeSet(self, data): 99 def _MakeSet(self, data):
100 """Converts the input data string into a set of email addresses. 100 """Converts the input data string into a set of email addresses.
101 """ 101 """
102 emails = (email.strip() for email in data.splitlines()) 102 emails = (email.strip() for email in data.splitlines())
103 self._users = frozenset(email for email in emails if email) 103 self._users = frozenset(email for email in emails if email)
104 log.msg('Found %d users' % len(self._users)) 104 log.msg('Found %d users' % len(self._users))
105 105
106 106
107 class _RietveldPoller(base.PollingChangeSource):
108 """Polls Rietveld for any pending patch sets to build.
109
110 Periodically polls Rietveld to see if any patch sets have been marked by
111 users to be tried. If so, send them to the trybots.
112 """
113
114 def __init__(self, get_pending_endpoint, interval, cachepath=None):
115 """
116 Args:
117 get_pending_endpoint: Rietveld URL string used to retrieve jobs to try.
118 interval: Interval used to poll Rietveld, in seconds.
119 cachepath: Path to file where state to persist between master restarts
120 will be stored.
121 """
122 # Set interval time in base class.
123 self.pollInterval = interval
124
125 # A string URL for the Rietveld endpoint to query for pending try jobs.
126 self._get_pending_endpoint = get_pending_endpoint
127
128 # Cursor used to keep track of next patchset(s) to try. If the cursor
129 # is None, then try from the beginning.
130 self._cursor = None
131
132 # Try job parent of this poller.
133 self._try_job_rietveld = None
134
135 self._cachepath = cachepath
136
137 if self._cachepath:
138 if os.path.exists(self._cachepath):
139 with open(self._cachepath) as f:
140 # Using JSON allows us to be flexible and extend the format
141 # in a compatible way.
142 data = json.load(f)
143 self._cursor = data.get('cursor').encode('utf-8')
144
145 # base.PollingChangeSource overrides:
146 def poll(self):
147 """Polls Rietveld for any pending try jobs and submit them.
148
149 Returns:
150 A deferred objects to be called once the operation completes.
151 """
152 log.msg('RietveldPoller.poll')
153 d = defer.succeed(None)
154 d.addCallback(self._OpenUrl)
155 d.addCallback(self._ParseJson)
156 d.addErrback(log.err, 'error in RietveldPoller') # eat errors
157 return d
158
159 def setServiceParent(self, parent):
160 base.PollingChangeSource.setServiceParent(self, parent)
161 self._try_job_rietveld = parent
162
163 def _OpenUrl(self, _):
164 """Downloads pending patch sets from Rietveld.
165
166 Returns: A string containing the pending patchsets from Rietveld
167 encoded as JSON.
168 """
169 endpoint = self._get_pending_endpoint
170 if self._cursor:
171 sep = '&' if '?' in endpoint else '?'
172 endpoint = endpoint + '%scursor=%s' % (sep, self._cursor)
173
174 log.msg('RietveldPoller._OpenUrl: %s' % endpoint)
175 return client.getPage(endpoint, agent='buildbot', timeout=2*60)
176
177 def _ParseJson(self, json_string):
178 """Parses the JSON pending patch set information.
179
180 Args:
181 json_string: A string containing the serialized JSON jobs.
182
183 Returns: A list of pending try jobs. This is the list of all jobs returned
184 by Rietveld, not simply the ones we tried this time.
185 """
186 data = json.loads(json_string)
187 d = self._try_job_rietveld.SubmitJobs(data['jobs'])
188 def success_callback(value):
189 self._cursor = str(data['cursor'])
190 self._try_job_rietveld.processed_keys.clear()
191
192 if self._cachepath:
193 with open(self._cachepath, 'w') as f:
194 json.dump({'cursor': self._cursor}, f)
195
196 return value
197 d.addCallback(success_callback)
198 return d
199
200
201 class _RietveldPollerWithCache(base.PollingChangeSource): 107 class _RietveldPollerWithCache(base.PollingChangeSource):
202 """Polls Rietveld for any pending patch sets to build. 108 """Polls Rietveld for any pending patch sets to build.
203 109
204 Periodically polls Rietveld to see if any patch sets have been marked by 110 Periodically polls Rietveld to see if any patch sets have been marked by
205 users to be tried. If so, send them to the trybots. Uses cursor to download 111 users to be tried. If so, send them to the trybots. Uses cursor to download
206 all pages within a single poll. To avoid sending same jobs, keeps a cache of 112 all pages within a single poll. To avoid sending same jobs, keeps a cache of
207 the jobs that were already processed thus reducing chances of a duplicate job 113 the jobs that were already processed thus reducing chances of a duplicate job
208 submission and increasing robustness to bugs in Rietveld. On the first poll 114 submission and increasing robustness to bugs in Rietveld. On the first poll
209 this cache is initialized with jobs currently pending on the Buildbot. 115 this cache is initialized with jobs currently pending on the Buildbot.
210 """ 116 """
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 num_removed += 1 250 num_removed += 1
345 log.msg('[RPWC] Removed %d old jobs from the cache.' % num_removed) 251 log.msg('[RPWC] Removed %d old jobs from the cache.' % num_removed)
346 self._processed_keys = new_processed_keys 252 self._processed_keys = new_processed_keys
347 253
348 254
349 class TryJobRietveld(TryJobBase): 255 class TryJobRietveld(TryJobBase):
350 """A try job source that gets jobs from pending Rietveld patch sets.""" 256 """A try job source that gets jobs from pending Rietveld patch sets."""
351 257
352 def __init__(self, name, pools, properties=None, last_good_urls=None, 258 def __init__(self, name, pools, properties=None, last_good_urls=None,
353 code_review_sites=None, project=None, filter_master=False, 259 code_review_sites=None, project=None, filter_master=False,
354 cachepath=None, cache_processed_jobs=False): 260 cachepath=None):
355 """Creates a try job source for Rietveld patch sets. 261 """Creates a try job source for Rietveld patch sets.
356 262
357 Args: 263 Args:
358 name: Name of this scheduler. 264 name: Name of this scheduler.
359 pools: No idea. 265 pools: No idea.
360 properties: Extra build properties specific to this scheduler. 266 properties: Extra build properties specific to this scheduler.
361 last_good_urls: Dictionary of project to last known good build URL. 267 last_good_urls: Dictionary of project to last known good build URL.
362 code_review_sites: Dictionary of project to code review site. This 268 code_review_sites: Dictionary of project to code review site. This
363 class care only about the 'chrome' project. 269 class care only about the 'chrome' project.
364 project: The name of the project whose review site URL to extract. 270 project: The name of the project whose review site URL to extract.
365 If the project is not found in the dictionary, an exception is 271 If the project is not found in the dictionary, an exception is
366 raised. 272 raised.
367 filter_master: Filter try jobs by master name. Necessary if several try 273 filter_master: Filter try jobs by master name. Necessary if several try
368 masters share the same rietveld instance. 274 masters share the same rietveld instance.
369 """ 275 """
370 TryJobBase.__init__(self, name, pools, properties, 276 TryJobBase.__init__(self, name, pools, properties,
371 last_good_urls, code_review_sites) 277 last_good_urls, code_review_sites)
372 endpoint = self._GetRietveldEndPointForProject( 278 endpoint = self._GetRietveldEndPointForProject(
373 code_review_sites, project, filter_master) 279 code_review_sites, project, filter_master)
374 280
375 if cache_processed_jobs: 281 self._poller = _RietveldPollerWithCache(endpoint, interval=10)
376 self._poller = _RietveldPollerWithCache(endpoint, interval=10)
377 else:
378 self._poller = _RietveldPoller(endpoint, interval=10, cachepath=cachepath)
379 self._valid_users = _ValidUserPoller(interval=12 * 60 * 60) 282 self._valid_users = _ValidUserPoller(interval=12 * 60 * 60)
380 self._project = project 283 self._project = project
381 284
382 # Cleared by _RietveldPoller._ParseJson's success callback. 285 # Cleared by _RietveldPoller._ParseJson's success callback.
383 self.processed_keys = set() 286 self.processed_keys = set()
384 287
385 log.msg('TryJobRietveld created, get_pending_endpoint=%s ' 288 log.msg('TryJobRietveld created, get_pending_endpoint=%s '
386 'project=%s' % (endpoint, project)) 289 'project=%s' % (endpoint, project))
387 290
388 @staticmethod 291 @staticmethod
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 else: 402 else:
500 self.processed_keys.add(job['key']) 403 self.processed_keys.add(job['key'])
501 log.err('Rietveld not updated: no corresponding service found.') 404 log.err('Rietveld not updated: no corresponding service found.')
502 405
503 # TryJobBase overrides: 406 # TryJobBase overrides:
504 def setServiceParent(self, parent): 407 def setServiceParent(self, parent):
505 TryJobBase.setServiceParent(self, parent) 408 TryJobBase.setServiceParent(self, parent)
506 self._poller.setServiceParent(self) 409 self._poller.setServiceParent(self)
507 self._poller.master = self.master 410 self._poller.master = self.master
508 self._valid_users.setServiceParent(self) 411 self._valid_users.setServiceParent(self)
OLDNEW
« masters/master.tryserver.blink/master.cfg ('K') | « masters/master.tryserver.webrtc/master.cfg ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698