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

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

Issue 13470005: Refactor the devserver to make it easier to control caching (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: cduvall, rebase Created 7 years, 8 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 (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 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 os 5 from object_store_creator import ObjectStoreCreator
6
7 import object_store
8
9 APPS = 'Apps'
10 APPS_FS = 'AppsFileSystem'
11 CRON = 'Cron'
12 EXTENSIONS = 'Extensions'
13 EXTENSIONS_FS = 'ExtensionsFileSystem'
14 CRON_FILE_LISTING = 'Cron.FileListing'
15 CRON_GITHUB_INVALIDATION = 'Cron.GithubInvalidation'
16 CRON_INVALIDATION = 'Cron.Invalidation'
17 HANDLEBAR = 'Handlebar'
18 IDL = 'IDL'
19 IDL_NO_REFS = 'IDLNoRefs'
20 IDL_NAMES = 'IDLNames'
21 INTRO = 'Intro'
22 JSON = 'JSON'
23 JSON_NO_REFS = 'JSONNoRefs'
24 LIST = 'List'
25 NAMES = 'Names'
26 PERMS = 'Perms'
27 SIDENAV = 'Sidenav'
28 STATIC = 'Static'
29 ZIP = 'Zip'
30 6
31 class _CacheEntry(object): 7 class _CacheEntry(object):
32 def __init__(self, cache_data, version): 8 def __init__(self, cache_data, version):
33 self._cache_data = cache_data 9 self._cache_data = cache_data
34 self.version = version 10 self.version = version
35 11
36 class CompiledFileSystem(object): 12 class CompiledFileSystem(object):
37 """This class caches FileSystem data that has been processed. 13 """This class caches FileSystem data that has been processed.
38 """ 14 """
39 class Factory(object): 15 class Factory(object):
40 """A class to build a CompiledFileSystem. 16 """A class to build a CompiledFileSystem backed by |file_system|.
17 Set an explicit |store_type| for tests.
41 """ 18 """
42 def __init__(self, file_system, object_store): 19 def __init__(self, file_system, store_type=None):
43 self._file_system = file_system 20 self._file_system = file_system
44 self._object_store = object_store 21 self._store_type = store_type
22 self._identity_instance = None
45 23
46 def Create(self, populate_function, namespace, version=None): 24 def Create(self, populate_function, cls, category=None, version=None):
47 """Create a CompiledFileSystem that populates the cache by calling 25 """Create a CompiledFileSystem that populates the cache by calling
48 |populate_function| with (path, data), where |data| is the data that was 26 |populate_function| with (path, data), where |data| is the data that was
49 fetched from |path|. The keys to the cache are put in the namespace 27 fetched from |path|.
50 specified by |namespace|, and optionally adding |version|. """ 28 The namespace for the file system is derived like ObjectStoreCreator: from
51 return CompiledFileSystem(self._file_system, 29 |cls| along with an optional |category| and |version|.
52 populate_function, 30 """
53 self._object_store, 31 assert isinstance(cls, type)
54 namespace, 32 assert not cls.__name__[0].islower() # guard against non-class types
55 version=version) 33 full_name = cls.__name__
34 if category is not None:
35 full_name = '%s/%s' % (full_name, category)
36 return self._Create(populate_function, full_name, version=version)
37
38 def GetOrCreateIdentity(self):
39 '''Handy helper to get or create the identity compiled file system.
40 GetFromFile will return the file's contents.
41 GetFromFileListing will return the directory list.
42 '''
43 if self._identity_instance is None:
44 self._identity_instance = self._Create(lambda _, x: x, 'id')
45 return self._identity_instance
46
47 def _Create(self, populate_function, full_name, version=None):
48 object_store_creator = ObjectStoreCreator(CompiledFileSystem,
49 store_type=self._store_type)
50 return CompiledFileSystem(
51 self._file_system,
52 populate_function,
53 object_store_creator.Create(category='%s/file' % full_name,
54 version=version),
55 object_store_creator.Create(category='%s/list' % full_name,
56 version=version))
56 57
57 def __init__(self, 58 def __init__(self,
58 file_system, 59 file_system,
59 populate_function, 60 populate_function,
60 object_store, 61 file_object_store,
61 namespace, 62 list_object_store):
62 version=None):
63 self._file_system = file_system 63 self._file_system = file_system
64 self._populate_function = populate_function 64 self._populate_function = populate_function
65 self._object_store = object_store 65 self._file_object_store = file_object_store
66 self._namespace = 'CompiledFileSystem.' + namespace 66 self._list_object_store = list_object_store
67 if version is not None:
68 self._namespace = '%s.%s' % (self._namespace, version)
69 67
70 def _MakeKey(self, key): 68 def _RecursiveList(self, path):
71 return self._namespace + '.' + key 69 files = []
72 70 for filename in self._file_system.ReadSingle(path):
73 def _RecursiveList(self, files):
74 all_files = files[:]
75 dirs = {}
76 for filename in files:
77 if filename.endswith('/'): 71 if filename.endswith('/'):
78 all_files.remove(filename) 72 files.extend(['%s%s' % (filename, f)
79 dirs.update(self._file_system.Read([filename]).Get()) 73 for f in self._RecursiveList('%s%s' % (path, filename))])
80 for dir_, files in dirs.iteritems(): 74 else:
81 all_files.extend(self._RecursiveList([dir_ + f for f in files])) 75 files.append(filename)
82 return all_files 76 return files
83 77
84 def GetFromFile(self, path, binary=False): 78 def GetFromFile(self, path, binary=False):
85 """Calls |populate_function| on the contents of the file at |path|. If 79 """Calls |populate_function| on the contents of the file at |path|. If
86 |binary| is True then the file will be read as binary - but this will only 80 |binary| is True then the file will be read as binary - but this will only
87 apply for the first time the file is fetched; if already cached, |binary| 81 apply for the first time the file is fetched; if already cached, |binary|
88 will be ignored. 82 will be ignored.
89 """ 83 """
90 version = self._file_system.Stat(path).version 84 version = self._file_system.Stat(path).version
91 cache_entry = self._object_store.Get(self._MakeKey(path), 85 cache_entry = self._file_object_store.Get(path, time=0).Get()
92 object_store.FILE_SYSTEM_CACHE,
93 time=0).Get()
94 if (cache_entry is not None) and (version == cache_entry.version): 86 if (cache_entry is not None) and (version == cache_entry.version):
95 return cache_entry._cache_data 87 return cache_entry._cache_data
96 cache_data = self._populate_function( 88 cache_data = self._populate_function(
97 path, 89 path,
98 self._file_system.ReadSingle(path, binary=binary)) 90 self._file_system.ReadSingle(path, binary=binary))
99 self._object_store.Set(self._MakeKey(path), 91 self._file_object_store.Set(path, _CacheEntry(cache_data, version), time=0)
100 _CacheEntry(cache_data, version),
101 object_store.FILE_SYSTEM_CACHE,
102 time=0)
103 return cache_data 92 return cache_data
104 93
105 def GetFromFileListing(self, path): 94 def GetFromFileListing(self, path):
106 """Calls |populate_function| on the listing of the files at |path|. 95 """Calls |populate_function| on the listing of the files at |path|.
107 Assumes that the path given is to a directory. 96 Assumes that the path given is to a directory.
108 """ 97 """
109 if not path.endswith('/'): 98 if not path.endswith('/'):
110 path += '/' 99 path += '/'
111 version = self._file_system.Stat(path).version 100 version = self._file_system.Stat(path).version
112 cache_entry = self._object_store.Get( 101 cache_entry = self._list_object_store.Get(path, time=0).Get()
113 self._MakeKey(path),
114 object_store.FILE_SYSTEM_CACHE_LISTING,
115 time=0).Get()
116 if (cache_entry is not None) and (version == cache_entry.version): 102 if (cache_entry is not None) and (version == cache_entry.version):
117 return cache_entry._cache_data 103 return cache_entry._cache_data
118 cache_data = self._populate_function( 104 cache_data = self._populate_function(path, self._RecursiveList(path))
119 path, 105 self._list_object_store.Set(path, _CacheEntry(cache_data, version), time=0)
120 self._RecursiveList(
121 [path + f for f in self._file_system.ReadSingle(path)]))
122 self._object_store.Set(self._MakeKey(path),
123 _CacheEntry(cache_data, version),
124 object_store.FILE_SYSTEM_CACHE_LISTING,
125 time=0)
126 return cache_data 106 return cache_data
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698