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

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

Issue 660383002: Docserver: Persist stat cache for versioned file systems (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: change caching strategy, better refresh cycle synchronization Created 6 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
OLDNEW
1 # Copyright 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 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 traceback 5 import traceback
6 6
7 from app_yaml_helper import AppYamlHelper 7 from app_yaml_helper import AppYamlHelper
8 from appengine_wrappers import IsDeadlineExceededError, logservice 8 from appengine_wrappers import IsDeadlineExceededError, logservice, taskqueue
9 from branch_utility import BranchUtility 9 from branch_utility import BranchUtility
10 from commit_tracker import CommitTracker
10 from compiled_file_system import CompiledFileSystem 11 from compiled_file_system import CompiledFileSystem
11 from custom_logger import CustomLogger 12 from custom_logger import CustomLogger
12 from data_source_registry import CreateDataSource 13 from data_source_registry import CreateDataSource
13 from environment import GetAppVersion 14 from environment import GetAppVersion
14 from file_system import IsFileSystemThrottledError 15 from file_system import IsFileSystemThrottledError
15 from future import Future 16 from future import Future
16 from gcs_file_system_provider import CloudStorageFileSystemProvider 17 from gcs_file_system_provider import CloudStorageFileSystemProvider
17 from github_file_system_provider import GithubFileSystemProvider 18 from github_file_system_provider import GithubFileSystemProvider
18 from host_file_system_provider import HostFileSystemProvider 19 from host_file_system_provider import HostFileSystemProvider
19 from object_store_creator import ObjectStoreCreator 20 from object_store_creator import ObjectStoreCreator
21 from refresh_tracker import RefreshTracker
20 from server_instance import ServerInstance 22 from server_instance import ServerInstance
21 from servlet import Servlet, Request, Response 23 from servlet import Servlet, Request, Response
22 from timer import Timer, TimerClosure 24 from timer import Timer, TimerClosure
23 25
24 26
27 _log = CustomLogger('refresh')
25 28
26 _log = CustomLogger('refresh') 29
30 def _UpdateMasterCommit(object_store_creator, commit):
31 commit_tracker = CommitTracker(object_store_creator)
32 return commit_tracker.Set('master', commit)
27 33
28 34
29 class RefreshServlet(Servlet): 35 class RefreshServlet(Servlet):
30 '''Servlet which refreshes a single data source. 36 '''Servlet which refreshes a single data source.
31 ''' 37 '''
32 def __init__(self, request, delegate_for_test=None): 38 def __init__(self, request, delegate_for_test=None):
33 Servlet.__init__(self, request) 39 Servlet.__init__(self, request)
34 self._delegate = delegate_for_test or RefreshServlet.Delegate() 40 self._delegate = delegate_for_test or RefreshServlet.Delegate()
35 41
36 class Delegate(object): 42 class Delegate(object):
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 (source_name, '' if source_path is None else '[%s]' % source_path)) 85 (source_name, '' if source_path is None else '[%s]' % source_path))
80 86
81 if 'commit' in self._request.arguments: 87 if 'commit' in self._request.arguments:
82 commit = self._request.arguments['commit'] 88 commit = self._request.arguments['commit']
83 else: 89 else:
84 _log.warning('No commit given; refreshing from master. ' 90 _log.warning('No commit given; refreshing from master. '
85 'This is probably NOT what you want.') 91 'This is probably NOT what you want.')
86 commit = None 92 commit = None
87 93
88 server_instance = self._CreateServerInstance(commit) 94 server_instance = self._CreateServerInstance(commit)
95 refresh_tracker = RefreshTracker(server_instance.object_store_creator)
96
89 success = True 97 success = True
98 success_message = 'Success'
90 try: 99 try:
91 if source_name == 'platform_bundle': 100 if source_name == 'platform_bundle':
92 data_source = server_instance.platform_bundle 101 data_source = server_instance.platform_bundle
93 elif source_name == 'content_providers': 102 elif source_name == 'content_providers':
94 data_source = server_instance.content_providers 103 data_source = server_instance.content_providers
104 elif source_name == 'instance_master':
105 data_source = _InstanceMasterCommitUpdater(commit)
95 else: 106 else:
96 data_source = CreateDataSource(source_name, server_instance) 107 data_source = CreateDataSource(source_name, server_instance)
97 108
109 # If the data source defines subtasks and none was provided, do the nice
110 # thing and queue up the defined subtasks instead of just failing.
111 if source_path is None:
112 refresh_paths = data_source.GetRefreshPaths()
113 if len(refresh_paths) > 1:
114 queue = taskqueue.Queue()
115 tasks = ['/_refresh/%s/%s' % (source_name, path)
116 for path in refresh_paths]
117 for task in tasks:
118 queue.add(taskqueue.Task(url=task, params={'commit': commit}))
119 success_message = 'Enqueued tasks: %s' % tasks
120 # The finally clause really handles the return.
121 return
122
98 class_name = data_source.__class__.__name__ 123 class_name = data_source.__class__.__name__
99 refresh_future = data_source.Refresh(source_path) 124 refresh_future = data_source.Refresh(source_path)
100 assert isinstance(refresh_future, Future), ( 125 assert isinstance(refresh_future, Future), (
101 '%s.Refresh() did not return a Future' % class_name) 126 '%s.Refresh() did not return a Future' % class_name)
102 timer = Timer() 127 timer = Timer()
103 try: 128 try:
104 refresh_future.Get() 129 refresh_future.Get()
130
131 def resolve(refresh_complete):
132 if refresh_complete:
133 return _UpdateMasterCommit(
134 server_instance.object_store_creator, commit)
135 return None
136 refresh_tracker.MarkTaskComplete(commit, '_refresh/%s/%s' % (
137 source_name, path)).Get()
138 refresh_tracker.GetRefreshComplete(commit).Then(resolve).Get()
105 except Exception as e: 139 except Exception as e:
106 _log.error('%s: error %s' % (class_name, traceback.format_exc())) 140 _log.error('%s: error %s' % (class_name, traceback.format_exc()))
107 success = False 141 success = False
108 if IsFileSystemThrottledError(e): 142 if IsFileSystemThrottledError(e):
109 return Response.ThrottledError('Throttled') 143 return Response.ThrottledError('Throttled')
110 raise 144 raise
111 finally: 145 finally:
112 _log.info('Refreshing %s took %s' % 146 _log.info('Refreshing %s took %s' %
113 (class_name, timer.Stop().FormatElapsed())) 147 (class_name, timer.Stop().FormatElapsed()))
114 148
115 except: 149 except:
116 success = False 150 success = False
117 # This should never actually happen. 151 # This should never actually happen.
118 _log.error('uncaught error: %s' % traceback.format_exc()) 152 _log.error('uncaught error: %s' % traceback.format_exc())
119 raise 153 raise
120 finally: 154 finally:
121 _log.info('finished (%s)', 'success' if success else 'FAILED') 155 _log.info('finished (%s)', 'success' if success else 'FAILED')
122 return (Response.Ok('Success') if success else 156 return (Response.Ok(success_message) if success else
123 Response.InternalError('Failure')) 157 Response.InternalError('Failure'))
124 158
125 def _CreateServerInstance(self, commit): 159 def _CreateServerInstance(self, commit):
126 '''Creates a ServerInstance pinned to |commit|, or HEAD if None. 160 '''Creates a ServerInstance pinned to |commit|, or HEAD if None.
127 NOTE: If passed None it's likely that during the cron run patches will be 161 NOTE: If passed None it's likely that during the cron run patches will be
128 submitted at HEAD, which may change data underneath the cron run. 162 submitted at HEAD, which may change data underneath the cron run.
129 ''' 163 '''
130 object_store_creator = ObjectStoreCreator(start_empty=True) 164 object_store_creator = ObjectStoreCreator(start_empty=True)
131 branch_utility = self._delegate.CreateBranchUtility(object_store_creator) 165 branch_utility = self._delegate.CreateBranchUtility(object_store_creator)
132 host_file_system_provider = self._delegate.CreateHostFileSystemProvider( 166 host_file_system_provider = self._delegate.CreateHostFileSystemProvider(
133 object_store_creator, pinned_commit=commit) 167 object_store_creator, pinned_commit=commit)
134 github_file_system_provider = self._delegate.CreateGithubFileSystemProvider( 168 github_file_system_provider = self._delegate.CreateGithubFileSystemProvider(
135 object_store_creator) 169 object_store_creator)
136 gcs_file_system_provider = self._delegate.CreateGCSFileSystemProvider( 170 gcs_file_system_provider = self._delegate.CreateGCSFileSystemProvider(
137 object_store_creator) 171 object_store_creator)
138 return ServerInstance(object_store_creator, 172 return ServerInstance(object_store_creator,
139 CompiledFileSystem.Factory(object_store_creator), 173 CompiledFileSystem.Factory(object_store_creator),
140 branch_utility, 174 branch_utility,
141 host_file_system_provider, 175 host_file_system_provider,
142 github_file_system_provider, 176 github_file_system_provider,
143 gcs_file_system_provider) 177 gcs_file_system_provider)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698