OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 | 2 |
3 """ | 3 """ |
4 Copyright 2013 Google Inc. | 4 Copyright 2013 Google Inc. |
5 | 5 |
6 Use of this source code is governed by a BSD-style license that can be | 6 Use of this source code is governed by a BSD-style license that can be |
7 found in the LICENSE file. | 7 found in the LICENSE file. |
8 | 8 |
9 HTTP server for our HTML rebaseline viewer. | 9 HTTP server for our HTML rebaseline viewer. |
10 """ | 10 """ |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 | 150 |
151 # Reentrant lock that must be held whenever updating EITHER of: | 151 # Reentrant lock that must be held whenever updating EITHER of: |
152 # 1. self._results | 152 # 1. self._results |
153 # 2. the expected or actual results on local disk | 153 # 2. the expected or actual results on local disk |
154 self.results_rlock = threading.RLock() | 154 self.results_rlock = threading.RLock() |
155 # self._results will be filled in by calls to update_results() | 155 # self._results will be filled in by calls to update_results() |
156 self._results = None | 156 self._results = None |
157 | 157 |
158 @property | 158 @property |
159 def results(self): | 159 def results(self): |
160 """ Returns the most recently generated results, or None if update_results() | 160 """ Returns the most recently generated results, or None if we don't have |
161 has not been called yet. """ | 161 any valid results (update_results() has not completed yet). """ |
162 return self._results | 162 return self._results |
163 | 163 |
164 @property | 164 @property |
165 def is_exported(self): | 165 def is_exported(self): |
166 """ Returns true iff HTTP clients on other hosts are allowed to access | 166 """ Returns true iff HTTP clients on other hosts are allowed to access |
167 this server. """ | 167 this server. """ |
168 return self._export | 168 return self._export |
169 | 169 |
170 @property | 170 @property |
171 def is_editable(self): | 171 def is_editable(self): |
172 """ Returns true iff HTTP clients are allowed to submit new baselines. """ | 172 """ Returns true iff HTTP clients are allowed to submit new baselines. """ |
173 return self._editable | 173 return self._editable |
174 | 174 |
175 @property | 175 @property |
176 def reload_seconds(self): | 176 def reload_seconds(self): |
177 """ Returns the result reload period in seconds, or 0 if we don't reload | 177 """ Returns the result reload period in seconds, or 0 if we don't reload |
178 results. """ | 178 results. """ |
179 return self._reload_seconds | 179 return self._reload_seconds |
180 | 180 |
181 def update_results(self): | 181 def update_results(self, invalidate=False): |
182 """ Create or update self._results, based on the expectations in | 182 """ Create or update self._results, based on the expectations in |
183 EXPECTATIONS_DIR and the latest actuals from skia-autogen. | 183 EXPECTATIONS_DIR and the latest actuals from skia-autogen. |
184 | 184 |
185 We hold self.results_rlock while we do this, to guarantee that no other | 185 We hold self.results_rlock while we do this, to guarantee that no other |
186 thread attempts to update either self._results or the underlying files at | 186 thread attempts to update either self._results or the underlying files at |
187 the same time. | 187 the same time. |
| 188 |
| 189 Args: |
| 190 invalidate: if True, invalidate self._results immediately upon entry; |
| 191 otherwise, we will let readers see those results until we |
| 192 replace them |
188 """ | 193 """ |
189 with self.results_rlock: | 194 with self.results_rlock: |
| 195 if invalidate: |
| 196 self._results = None |
190 logging.info('Updating actual GM results in %s from SVN repo %s ...' % ( | 197 logging.info('Updating actual GM results in %s from SVN repo %s ...' % ( |
191 self._actuals_dir, ACTUALS_SVN_REPO)) | 198 self._actuals_dir, ACTUALS_SVN_REPO)) |
192 self._actuals_repo.Update('.') | 199 self._actuals_repo.Update('.') |
193 | 200 |
194 # We only update the expectations dir if the server was run with a | 201 # We only update the expectations dir if the server was run with a |
195 # nonzero --reload argument; otherwise, we expect the user to maintain | 202 # nonzero --reload argument; otherwise, we expect the user to maintain |
196 # her own expectations as she sees fit. | 203 # her own expectations as she sees fit. |
197 # | 204 # |
198 # Because the Skia repo is moving from SVN to git, and git does not | 205 # Because the Skia repo is moving from SVN to git, and git does not |
199 # support updating a single directory tree, we have to update the entire | 206 # support updating a single directory tree, we have to update the entire |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 with _SERVER.results_rlock: | 445 with _SERVER.results_rlock: |
439 oldResultsType = data['oldResultsType'] | 446 oldResultsType = data['oldResultsType'] |
440 oldResults = _SERVER.results.get_results_of_type(oldResultsType) | 447 oldResults = _SERVER.results.get_results_of_type(oldResultsType) |
441 oldResultsHash = str(hash(repr(oldResults['testData']))) | 448 oldResultsHash = str(hash(repr(oldResults['testData']))) |
442 if oldResultsHash != data['oldResultsHash']: | 449 if oldResultsHash != data['oldResultsHash']: |
443 raise Exception('results of type "%s" changed while the client was ' | 450 raise Exception('results of type "%s" changed while the client was ' |
444 'making modifications. The client should reload the ' | 451 'making modifications. The client should reload the ' |
445 'results and submit the modifications again.' % | 452 'results and submit the modifications again.' % |
446 oldResultsType) | 453 oldResultsType) |
447 _SERVER.results.edit_expectations(data['modifications']) | 454 _SERVER.results.edit_expectations(data['modifications']) |
448 # Read the updated results back from disk. | 455 |
449 _SERVER.update_results() | 456 # Read the updated results back from disk. |
| 457 # We can do this in a separate thread; we should return our success message |
| 458 # to the UI as soon as possible. |
| 459 thread.start_new_thread(_SERVER.update_results, (True,)) |
450 | 460 |
451 def redirect_to(self, url): | 461 def redirect_to(self, url): |
452 """ Redirect the HTTP client to a different url. | 462 """ Redirect the HTTP client to a different url. |
453 | 463 |
454 Args: | 464 Args: |
455 url: URL to redirect the HTTP client to | 465 url: URL to redirect the HTTP client to |
456 """ | 466 """ |
457 self.send_response(301) | 467 self.send_response(301) |
458 self.send_header('Location', url) | 468 self.send_header('Location', url) |
459 self.end_headers() | 469 self.end_headers() |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 args = parser.parse_args() | 537 args = parser.parse_args() |
528 global _SERVER | 538 global _SERVER |
529 _SERVER = Server(actuals_dir=args.actuals_dir, | 539 _SERVER = Server(actuals_dir=args.actuals_dir, |
530 port=args.port, export=args.export, editable=args.editable, | 540 port=args.port, export=args.export, editable=args.editable, |
531 reload_seconds=args.reload) | 541 reload_seconds=args.reload) |
532 _SERVER.run() | 542 _SERVER.run() |
533 | 543 |
534 | 544 |
535 if __name__ == '__main__': | 545 if __name__ == '__main__': |
536 main() | 546 main() |
OLD | NEW |