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

Side by Side Diff: gm/rebaseline_server/server.py

Issue 66803004: rebaseline_server: improve thread locks to allow read access during updates (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: linewrap Created 7 years, 1 month 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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()
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698