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 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
117 | 117 |
118 def reload_seconds(self): | 118 def reload_seconds(self): |
119 """ Returns the result reload period in seconds, or 0 if we don't reload | 119 """ Returns the result reload period in seconds, or 0 if we don't reload |
120 results. """ | 120 results. """ |
121 return self._reload_seconds | 121 return self._reload_seconds |
122 | 122 |
123 def update_results(self): | 123 def update_results(self): |
124 """ Create or update self.results, based on the expectations in | 124 """ Create or update self.results, based on the expectations in |
125 self._expectations_dir and the latest actuals from skia-autogen. | 125 self._expectations_dir and the latest actuals from skia-autogen. |
126 """ | 126 """ |
127 with self.results_lock: | 127 with self._svn_update_lock: |
128 # self.results_lock prevents us from updating the actual GM results | 128 # self._svn_update_lock prevents us from updating the actual GM results |
jcgregorio
2013/11/08 17:33:21
Comment seems wrong, doesn't this just prevent you
| |
129 # in multiple threads simultaneously | 129 # in multiple threads simultaneously |
130 logging.info('Updating actual GM results in %s from SVN repo %s ...' % ( | 130 logging.info('Updating actual GM results in %s from SVN repo %s ...' % ( |
131 self._actuals_dir, ACTUALS_SVN_REPO)) | 131 self._actuals_dir, ACTUALS_SVN_REPO)) |
132 actuals_repo = svn.Svn(self._actuals_dir) | 132 actuals_repo = svn.Svn(self._actuals_dir) |
133 if not os.path.isdir(self._actuals_dir): | 133 if not os.path.isdir(self._actuals_dir): |
134 os.makedirs(self._actuals_dir) | 134 os.makedirs(self._actuals_dir) |
135 actuals_repo.Checkout(ACTUALS_SVN_REPO, '.') | 135 actuals_repo.Checkout(ACTUALS_SVN_REPO, '.') |
136 else: | 136 else: |
137 actuals_repo.Update('.') | 137 actuals_repo.Update('.') |
138 | |
139 # We only update the expectations dir if the server was run with a | 138 # We only update the expectations dir if the server was run with a |
140 # nonzero --reload argument; otherwise, we expect the user to maintain | 139 # nonzero --reload argument; otherwise, we expect the user to maintain |
141 # her own expectations as she sees fit. | 140 # her own expectations as she sees fit. |
142 # | 141 # |
143 # self.results_lock prevents us from updating the expected GM results | 142 # self._svn_update_lock prevents us from updating the expected GM results |
144 # in multiple threads simultaneously | 143 # in multiple threads simultaneously |
145 # | 144 # |
146 # TODO(epoger): Use git instead of svn to check out expectations, since | 145 # TODO(epoger): Use git instead of svn to check out expectations, since |
147 # the Skia repo is moving to git. | 146 # the Skia repo is moving to git. |
148 if self._reload_seconds: | 147 if self._reload_seconds: |
149 logging.info( | 148 logging.info( |
150 'Updating expected GM results in %s from SVN repo %s ...' % ( | 149 'Updating expected GM results in %s from SVN repo %s ...' % ( |
151 self._expectations_dir, EXPECTATIONS_SVN_REPO)) | 150 self._expectations_dir, EXPECTATIONS_SVN_REPO)) |
152 expectations_repo = svn.Svn(self._expectations_dir) | 151 expectations_repo = svn.Svn(self._expectations_dir) |
153 if not os.path.isdir(self._expectations_dir): | 152 if not os.path.isdir(self._expectations_dir): |
154 os.makedirs(self._expectations_dir) | 153 os.makedirs(self._expectations_dir) |
155 expectations_repo.Checkout(EXPECTATIONS_SVN_REPO, '.') | 154 expectations_repo.Checkout(EXPECTATIONS_SVN_REPO, '.') |
156 else: | 155 else: |
157 expectations_repo.Update('.') | 156 expectations_repo.Update('.') |
157 # end of "with self._svn_update_lock:" | |
158 | 158 |
159 logging.info( | 159 logging.info( |
160 ('Parsing results from actuals in %s and expectations in %s, ' | 160 ('Parsing results from actuals in %s and expectations in %s, ' |
161 + 'and generating pixel diffs (may take a while) ...') % ( | 161 + 'and generating pixel diffs (may take a while) ...') % ( |
162 self._actuals_dir, self._expectations_dir)) | 162 self._actuals_dir, self._expectations_dir)) |
163 self.results = results.Results( | 163 new_results = results.Results( |
164 actuals_root=self._actuals_dir, | 164 actuals_root=self._actuals_dir, |
165 expected_root=self._expectations_dir, | 165 expected_root=self._expectations_dir, |
166 generated_images_root=GENERATED_IMAGES_ROOT) | 166 generated_images_root=GENERATED_IMAGES_ROOT) |
167 | 167 |
168 # Make sure we don't update self.results while a client is in the middle | |
169 # of reading from it. | |
170 with self.results_lock: | |
171 self.results = new_results | |
172 | |
168 def _result_reloader(self): | 173 def _result_reloader(self): |
169 """ If --reload argument was specified, reload results at the appropriate | 174 """ If --reload argument was specified, reload results at the appropriate |
170 interval. | 175 interval. |
171 """ | 176 """ |
172 while self._reload_seconds: | 177 while self._reload_seconds: |
173 time.sleep(self._reload_seconds) | 178 time.sleep(self._reload_seconds) |
174 self.update_results() | 179 self.update_results() |
175 | 180 |
176 def run(self): | 181 def run(self): |
177 self.results_lock = thread.allocate_lock() | 182 self.results_lock = thread.allocate_lock() |
jcgregorio
2013/11/08 17:33:21
Add docs here for what each lock is used for.
| |
183 self._svn_update_lock = thread.allocate_lock() | |
178 self.update_results() | 184 self.update_results() |
179 thread.start_new_thread(self._result_reloader, ()) | 185 thread.start_new_thread(self._result_reloader, ()) |
180 | 186 |
181 if self._export: | 187 if self._export: |
182 server_address = ('', self._port) | 188 server_address = ('', self._port) |
183 host = get_routable_ip_address() | 189 host = get_routable_ip_address() |
184 if self._editable: | 190 if self._editable: |
185 logging.warning('Running with combination of "export" and "editable" ' | 191 logging.warning('Running with combination of "export" and "editable" ' |
186 'flags. Users on other machines will ' | 192 'flags. Users on other machines will ' |
187 'be able to modify your GM expectations!') | 193 'be able to modify your GM expectations!') |
188 else: | 194 else: |
189 host = '127.0.0.1' | 195 host = '127.0.0.1' |
190 server_address = (host, self._port) | 196 server_address = (host, self._port) |
191 http_server = BaseHTTPServer.HTTPServer(server_address, HTTPRequestHandler) | 197 http_server = BaseHTTPServer.HTTPServer(server_address, HTTPRequestHandler) |
192 logging.info('Ready for requests on http://%s:%d' % (host, http_server.serve r_port)) | 198 logging.info('Ready for requests on http://%s:%d' % ( |
199 host, http_server.server_port)) | |
193 http_server.serve_forever() | 200 http_server.serve_forever() |
194 | 201 |
195 | 202 |
196 class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): | 203 class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
197 """ HTTP request handlers for various types of queries this server knows | 204 """ HTTP request handlers for various types of queries this server knows |
198 how to handle (static HTML and Javascript, expected/actual results, etc.) | 205 how to handle (static HTML and Javascript, expected/actual results, etc.) |
199 """ | 206 """ |
200 def do_GET(self): | 207 def do_GET(self): |
201 """ Handles all GET requests, forwarding them to the appropriate | 208 """ Handles all GET requests, forwarding them to the appropriate |
202 do_GET_* dispatcher. """ | 209 do_GET_* dispatcher. """ |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
442 args = parser.parse_args() | 449 args = parser.parse_args() |
443 global _SERVER | 450 global _SERVER |
444 _SERVER = Server(actuals_dir=args.actuals_dir, | 451 _SERVER = Server(actuals_dir=args.actuals_dir, |
445 expectations_dir=args.expectations_dir, | 452 expectations_dir=args.expectations_dir, |
446 port=args.port, export=args.export, editable=args.editable, | 453 port=args.port, export=args.export, editable=args.editable, |
447 reload_seconds=args.reload) | 454 reload_seconds=args.reload) |
448 _SERVER.run() | 455 _SERVER.run() |
449 | 456 |
450 if __name__ == '__main__': | 457 if __name__ == '__main__': |
451 main() | 458 main() |
OLD | NEW |