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

Side by Side Diff: chrome/common/extensions/docs/server2/cron_servlet.py

Issue 26418002: Docserver: Pull knowledge of host file systems into a single (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: correct similarity Created 7 years, 2 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 2013 The Chromium Authors. All rights reserved. 1 # Copyright 2013 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 logging 5 import logging
6 import time 6 import time
7 import traceback 7 import traceback
8 8
9 from app_yaml_helper import AppYamlHelper 9 from app_yaml_helper import AppYamlHelper
10 from appengine_wrappers import ( 10 from appengine_wrappers import (
11 GetAppVersion, IsDeadlineExceededError, IsDevServer, logservice) 11 GetAppVersion, IsDeadlineExceededError, IsDevServer, logservice)
12 from branch_utility import BranchUtility 12 from branch_utility import BranchUtility
13 from compiled_file_system import CompiledFileSystem 13 from compiled_file_system import CompiledFileSystem
14 from data_source_registry import CreateDataSources 14 from data_source_registry import CreateDataSources
15 from empty_dir_file_system import EmptyDirFileSystem 15 from empty_dir_file_system import EmptyDirFileSystem
16 from file_system_util import CreateURLsFromPaths 16 from file_system_util import CreateURLsFromPaths
17 from github_file_system import GithubFileSystem 17 from github_file_system import GithubFileSystem
18 from host_file_system_creator import HostFileSystemCreator 18 from host_file_system_provider import HostFileSystemProvider
19 from object_store_creator import ObjectStoreCreator 19 from object_store_creator import ObjectStoreCreator
20 from render_servlet import RenderServlet 20 from render_servlet import RenderServlet
21 from server_instance import ServerInstance 21 from server_instance import ServerInstance
22 from servlet import Servlet, Request, Response 22 from servlet import Servlet, Request, Response
23 import svn_constants 23 import svn_constants
24 24
25 class _SingletonRenderServletDelegate(RenderServlet.Delegate): 25 class _SingletonRenderServletDelegate(RenderServlet.Delegate):
26 def __init__(self, server_instance): 26 def __init__(self, server_instance):
27 self._server_instance = server_instance 27 self._server_instance = server_instance
28 28
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 def __init__(self, request, delegate_for_test=None): 83 def __init__(self, request, delegate_for_test=None):
84 Servlet.__init__(self, request) 84 Servlet.__init__(self, request)
85 self._delegate = delegate_for_test or CronServlet.Delegate() 85 self._delegate = delegate_for_test or CronServlet.Delegate()
86 86
87 class Delegate(object): 87 class Delegate(object):
88 '''CronServlet's runtime dependencies. Override for testing. 88 '''CronServlet's runtime dependencies. Override for testing.
89 ''' 89 '''
90 def CreateBranchUtility(self, object_store_creator): 90 def CreateBranchUtility(self, object_store_creator):
91 return BranchUtility.Create(object_store_creator) 91 return BranchUtility.Create(object_store_creator)
92 92
93 def CreateHostFileSystemCreator(self, object_store_creator): 93 def CreateHostFileSystemProvider(self,
94 return HostFileSystemCreator(object_store_creator) 94 object_store_creator,
95 max_trunk_revision=None):
96 return HostFileSystemProvider(object_store_creator,
97 max_trunk_revision=max_trunk_revision)
95 98
96 def CreateAppSamplesFileSystem(self, object_store_creator): 99 def CreateAppSamplesFileSystem(self, object_store_creator):
97 # TODO(kalman): CachingFileSystem wrapper for GithubFileSystem, but it's 100 # TODO(kalman): CachingFileSystem wrapper for GithubFileSystem, but it's
98 # not supported yet (see comment there). 101 # not supported yet (see comment there).
99 return (EmptyDirFileSystem() if IsDevServer() else 102 return (EmptyDirFileSystem() if IsDevServer() else
100 GithubFileSystem.Create(object_store_creator)) 103 GithubFileSystem.Create(object_store_creator))
101 104
102 def GetAppVersion(self): 105 def GetAppVersion(self):
103 return GetAppVersion() 106 return GetAppVersion()
104 107
(...skipping 21 matching lines...) Expand all
126 # little wasteful, but hopefully rendering is really fast (if it isn't we 129 # little wasteful, but hopefully rendering is really fast (if it isn't we
127 # have a problem). 130 # have a problem).
128 _cronlog.info('starting') 131 _cronlog.info('starting')
129 132
130 # This is returned every time RenderServlet wants to create a new 133 # This is returned every time RenderServlet wants to create a new
131 # ServerInstance. 134 # ServerInstance.
132 # 135 #
133 # TODO(kalman): IMPORTANT. This sometimes throws an exception, breaking 136 # TODO(kalman): IMPORTANT. This sometimes throws an exception, breaking
134 # everything. Need retry logic at the fetcher level. 137 # everything. Need retry logic at the fetcher level.
135 server_instance = self._GetSafeServerInstance() 138 server_instance = self._GetSafeServerInstance()
139 trunk_fs = server_instance.host_file_system_provider.GetTrunk()
136 140
137 def render(path): 141 def render(path):
138 request = Request(path, self._request.host, self._request.headers) 142 request = Request(path, self._request.host, self._request.headers)
139 delegate = _SingletonRenderServletDelegate(server_instance) 143 delegate = _SingletonRenderServletDelegate(server_instance)
140 return RenderServlet(request, delegate).Get() 144 return RenderServlet(request, delegate).Get()
141 145
142 def request_files_in_dir(path, prefix=''): 146 def request_files_in_dir(path, prefix=''):
143 '''Requests every file found under |path| in this host file system, with 147 '''Requests every file found under |path| in this host file system, with
144 a request prefix of |prefix|. 148 a request prefix of |prefix|.
145 ''' 149 '''
146 files = [name for name, _ in 150 files = [name for name, _ in CreateURLsFromPaths(trunk_fs, path, prefix)]
147 CreateURLsFromPaths(server_instance.host_file_system, path, prefix)]
148 return _RequestEachItem(path, files, render) 151 return _RequestEachItem(path, files, render)
149 152
150 results = [] 153 results = []
151 154
152 try: 155 try:
153 # Rendering the public templates will also pull in all of the private 156 # Rendering the public templates will also pull in all of the private
154 # templates. 157 # templates.
155 results.append(request_files_in_dir(svn_constants.PUBLIC_TEMPLATE_PATH)) 158 results.append(request_files_in_dir(svn_constants.PUBLIC_TEMPLATE_PATH))
156 159
157 # Rendering the public templates will have pulled in the .js and 160 # Rendering the public templates will have pulled in the .js and
158 # manifest.json files (for listing examples on the API reference pages), 161 # manifest.json files (for listing examples on the API reference pages),
159 # but there are still images, CSS, etc. 162 # but there are still images, CSS, etc.
160 results.append(request_files_in_dir(svn_constants.STATIC_PATH, 163 results.append(request_files_in_dir(svn_constants.STATIC_PATH,
161 prefix='static/')) 164 prefix='static/'))
162 165
163 # Samples are too expensive to run on the dev server, where there is no 166 # Samples are too expensive to run on the dev server, where there is no
164 # parallel fetch. 167 # parallel fetch.
165 if not IsDevServer(): 168 if not IsDevServer():
166 # Fetch each individual sample file. 169 # Fetch each individual sample file.
167 results.append(request_files_in_dir(svn_constants.EXAMPLES_PATH, 170 results.append(request_files_in_dir(svn_constants.EXAMPLES_PATH,
168 prefix='extensions/examples/')) 171 prefix='extensions/examples/'))
169 172
170 # Fetch the zip file of each example (contains all the individual 173 # Fetch the zip file of each example (contains all the individual
171 # files). 174 # files).
172 example_zips = [] 175 example_zips = []
173 for root, _, files in server_instance.host_file_system.Walk( 176 for root, _, files in trunk_fs.Walk(svn_constants.EXAMPLES_PATH):
174 svn_constants.EXAMPLES_PATH):
175 example_zips.extend( 177 example_zips.extend(
176 root + '.zip' for name in files if name == 'manifest.json') 178 root + '.zip' for name in files if name == 'manifest.json')
177 results.append(_RequestEachItem( 179 results.append(_RequestEachItem(
178 'example zips', 180 'example zips',
179 example_zips, 181 example_zips,
180 lambda path: render('extensions/examples/' + path))) 182 lambda path: render('extensions/examples/' + path)))
181 183
182 def run_cron(data_source): 184 def run_cron(data_source):
183 title = data_source.__class__.__name__ 185 title = data_source.__class__.__name__
184 _cronlog.info('%s: starting' % title) 186 _cronlog.info('%s: starting' % title)
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 # IMPORTANT: Get a ServerInstance pinned to the most recent revision, not 222 # IMPORTANT: Get a ServerInstance pinned to the most recent revision, not
221 # HEAD. These cron jobs take a while and run very frequently such that 223 # HEAD. These cron jobs take a while and run very frequently such that
222 # there is usually one running at any given time, and eventually a file 224 # there is usually one running at any given time, and eventually a file
223 # that we're dealing with will change underneath it, putting the server in 225 # that we're dealing with will change underneath it, putting the server in
224 # an undefined state. 226 # an undefined state.
225 server_instance_near_head = self._CreateServerInstance( 227 server_instance_near_head = self._CreateServerInstance(
226 self._GetMostRecentRevision()) 228 self._GetMostRecentRevision())
227 229
228 app_yaml_handler = AppYamlHelper( 230 app_yaml_handler = AppYamlHelper(
229 svn_constants.APP_YAML_PATH, 231 svn_constants.APP_YAML_PATH,
230 server_instance_near_head.host_file_system,
231 server_instance_near_head.object_store_creator, 232 server_instance_near_head.object_store_creator,
232 server_instance_near_head.host_file_system_creator) 233 server_instance_near_head.host_file_system_provider)
233 234
234 if app_yaml_handler.IsUpToDate(delegate.GetAppVersion()): 235 if app_yaml_handler.IsUpToDate(delegate.GetAppVersion()):
235 return server_instance_near_head 236 return server_instance_near_head
236 237
237 # The version in app.yaml is greater than the currently running app's. 238 # The version in app.yaml is greater than the currently running app's.
238 # The safe version is the one before it changed. 239 # The safe version is the one before it changed.
239 safe_revision = app_yaml_handler.GetFirstRevisionGreaterThan( 240 safe_revision = app_yaml_handler.GetFirstRevisionGreaterThan(
240 delegate.GetAppVersion()) - 1 241 delegate.GetAppVersion()) - 1
241 242
242 _cronlog.info('app version %s is out of date, safe is %s', 243 _cronlog.info('app version %s is out of date, safe is %s',
243 delegate.GetAppVersion(), safe_revision) 244 delegate.GetAppVersion(), safe_revision)
244 245
245 return self._CreateServerInstance(safe_revision) 246 return self._CreateServerInstance(safe_revision)
246 247
247 def _GetMostRecentRevision(self): 248 def _GetMostRecentRevision(self):
248 '''Gets the revision of the most recent patch submitted to the host file 249 '''Gets the revision of the most recent patch submitted to the host file
249 system. This is similar to HEAD but it's a concrete revision so won't 250 system. This is similar to HEAD but it's a concrete revision so won't
250 change as the cron runs. 251 change as the cron runs.
251 ''' 252 '''
252 return self._CreateServerInstance(None).host_file_system.Stat('/').version 253 head_fs = (
254 self._CreateServerInstance(None).host_file_system_provider.GetTrunk())
255 return head_fs.Stat('/').version
253 256
254 def _CreateServerInstance(self, revision): 257 def _CreateServerInstance(self, revision):
255 '''Creates a ServerInstance pinned to |revision|, or HEAD if None. 258 '''Creates a ServerInstance pinned to |revision|, or HEAD if None.
256 NOTE: If passed None it's likely that during the cron run patches will be 259 NOTE: If passed None it's likely that during the cron run patches will be
257 submitted at HEAD, which may change data underneath the cron run. 260 submitted at HEAD, which may change data underneath the cron run.
258 ''' 261 '''
259 object_store_creator = ObjectStoreCreator(start_empty=True) 262 object_store_creator = ObjectStoreCreator(start_empty=True)
260 branch_utility = self._delegate.CreateBranchUtility(object_store_creator) 263 branch_utility = self._delegate.CreateBranchUtility(object_store_creator)
261 host_file_system_creator = self._delegate.CreateHostFileSystemCreator( 264 host_file_system_provider = self._delegate.CreateHostFileSystemProvider(
262 object_store_creator) 265 object_store_creator, max_trunk_revision=revision)
263 host_file_system = host_file_system_creator.Create(revision=revision)
264 app_samples_file_system = self._delegate.CreateAppSamplesFileSystem( 266 app_samples_file_system = self._delegate.CreateAppSamplesFileSystem(
265 object_store_creator) 267 object_store_creator)
266 compiled_host_fs_factory = CompiledFileSystem.Factory( 268 compiled_host_fs_factory = CompiledFileSystem.Factory(
267 host_file_system, 269 host_file_system_provider.GetTrunk(),
268 object_store_creator) 270 object_store_creator)
269 return ServerInstance(object_store_creator, 271 return ServerInstance(object_store_creator,
270 host_file_system,
271 app_samples_file_system, 272 app_samples_file_system,
272 compiled_host_fs_factory, 273 compiled_host_fs_factory,
273 branch_utility, 274 branch_utility,
274 host_file_system_creator) 275 host_file_system_provider)
OLDNEW
« no previous file with comments | « chrome/common/extensions/docs/server2/cron.yaml ('k') | chrome/common/extensions/docs/server2/cron_servlet_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698