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
3 # found in the LICENSE file.
5 from branch_utility
import BranchUtility
6 from commit_tracker
import CommitTracker
7 from compiled_file_system
import CompiledFileSystem
8 from environment
import IsDevServer
, IsReleaseServer
9 from github_file_system_provider
import GithubFileSystemProvider
10 from host_file_system_provider
import HostFileSystemProvider
11 from third_party
.json_schema_compiler
.memoize
import memoize
12 from render_servlet
import RenderServlet
13 from object_store_creator
import ObjectStoreCreator
14 from server_instance
import ServerInstance
15 from gcs_file_system_provider
import CloudStorageFileSystemProvider
18 class InstanceServletRenderServletDelegate(RenderServlet
.Delegate
):
19 '''AppEngine instances should never need to call out to Gitiles. That should
20 only ever be done by the cronjobs, which then write the result into
21 DataStore, which is as far as instances look. To enable this, crons can pass
22 a custom (presumably online) ServerInstance into Get().
24 Why? Gitiles is slow and a bit flaky. Refresh jobs failing is annoying but
25 temporary. Instances failing affects users, and is really bad.
27 Anyway - to enforce this, we actually don't give instances access to
28 Gitiles. If anything is missing from datastore, it'll be a 404. If the
29 cronjobs don't manage to catch everything - uhoh. On the other hand, we'll
30 figure it out pretty soon, and it also means that legitimate 404s are caught
31 before a round trip to Gitiles.
33 def __init__(self
, delegate
):
34 self
._delegate
= delegate
37 def CreateServerInstance(self
):
38 object_store_creator
= ObjectStoreCreator(start_empty
=False)
39 branch_utility
= self
._delegate
.CreateBranchUtility(object_store_creator
)
40 commit_tracker
= CommitTracker(object_store_creator
)
41 # In production have offline=True so that we can catch cron errors. In
42 # development it's annoying to have to run the cron job, so offline=False.
43 # Note that offline=True if running on any appengine server due to
44 # http://crbug.com/345361.
45 host_file_system_provider
= self
._delegate
.CreateHostFileSystemProvider(
47 offline
=not (IsDevServer() or IsReleaseServer()),
48 pinned_commit
=commit_tracker
.Get('master').Get(),
50 github_file_system_provider
= self
._delegate
.CreateGithubFileSystemProvider(
52 return ServerInstance(object_store_creator
,
53 CompiledFileSystem
.Factory(object_store_creator
),
55 host_file_system_provider
,
56 github_file_system_provider
,
57 CloudStorageFileSystemProvider(object_store_creator
))
59 class InstanceServlet(object):
60 '''Servlet for running on normal AppEngine instances.
61 Create this via GetConstructor() so that cache state can be shared amongst
62 them via the memoizing Delegate.
64 class Delegate(object):
65 '''Allow runtime dependencies to be overriden for testing.
67 def CreateBranchUtility(self
, object_store_creator
):
68 return BranchUtility
.Create(object_store_creator
)
70 def CreateHostFileSystemProvider(self
, object_store_creator
, **optargs
):
71 return HostFileSystemProvider(object_store_creator
, **optargs
)
73 def CreateGithubFileSystemProvider(self
, object_store_creator
):
74 return GithubFileSystemProvider(object_store_creator
)
77 def GetConstructor(delegate_for_test
=None):
78 render_servlet_delegate
= InstanceServletRenderServletDelegate(
79 delegate_for_test
or InstanceServlet
.Delegate())
80 return lambda request
: RenderServlet(request
, render_servlet_delegate
)
82 # NOTE: if this were a real Servlet it would implement a Get() method, but
83 # GetConstructor returns an appropriate lambda function (Request -> Servlet).