OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library source.caching_pub_package_map_provider; | 5 library source.caching_pub_package_map_provider; |
6 | 6 |
7 import 'dart:convert'; | 7 import 'dart:convert'; |
8 import 'dart:io' as io; | 8 import 'dart:io' as io; |
9 | 9 |
10 import 'package:analyzer/file_system/file_system.dart'; | 10 import 'package:analyzer/file_system/file_system.dart'; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 | 68 |
69 /** | 69 /** |
70 * The function used to write the cache file. | 70 * The function used to write the cache file. |
71 */ | 71 */ |
72 WriteFile _writeFile; | 72 WriteFile _writeFile; |
73 | 73 |
74 /** | 74 /** |
75 * Construct a new instance. | 75 * Construct a new instance. |
76 * [RunPubList] and [WriteFile] implementations may be injected for testing | 76 * [RunPubList] and [WriteFile] implementations may be injected for testing |
77 */ | 77 */ |
78 CachingPubPackageMapProvider(ResourceProvider resourceProvider, | 78 CachingPubPackageMapProvider( |
79 DirectoryBasedDartSdk sdk, [RunPubList runPubList, this._writeFile]) | 79 ResourceProvider resourceProvider, DirectoryBasedDartSdk sdk, |
| 80 [RunPubList runPubList, this._writeFile]) |
80 : super(resourceProvider, sdk, runPubList) { | 81 : super(resourceProvider, sdk, runPubList) { |
81 if (_writeFile == null) { | 82 if (_writeFile == null) { |
82 _writeFile = _writeFileDefault; | 83 _writeFile = _writeFileDefault; |
83 } | 84 } |
84 } | 85 } |
85 | 86 |
86 File get cacheFile => _cacheDir.getChild('cache'); | 87 File get cacheFile => _cacheDir.getChild('cache'); |
87 Folder get _cacheDir => resourceProvider.getStateLocation('.pub-list'); | 88 Folder get _cacheDir => resourceProvider.getStateLocation('.pub-list'); |
88 File get _touchFile => _cacheDir.getChild('touch'); | 89 File get _touchFile => _cacheDir.getChild('touch'); |
89 | 90 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 } | 131 } |
131 // computePackageMap calls parsePackageMap which caches the result | 132 // computePackageMap calls parsePackageMap which caches the result |
132 info = super.computePackageMap(folder); | 133 info = super.computePackageMap(folder); |
133 ++runCount; | 134 ++runCount; |
134 if (!_haveDependenciesChangedSince(info, startStamp)) { | 135 if (!_haveDependenciesChangedSince(info, startStamp)) { |
135 // If no dependencies have changed while running pub then finished | 136 // If no dependencies have changed while running pub then finished |
136 break; | 137 break; |
137 } | 138 } |
138 if (runCount == 4) { | 139 if (runCount == 4) { |
139 // Don't run forever | 140 // Don't run forever |
140 AnalysisEngine.instance.logger.logInformation( | 141 AnalysisEngine.instance.logger |
141 'pub list called $runCount times: $folder'); | 142 .logInformation('pub list called $runCount times: $folder'); |
142 break; | 143 break; |
143 } | 144 } |
144 } | 145 } |
145 _writeCache(); | 146 _writeCache(); |
146 return info; | 147 return info; |
147 } | 148 } |
148 | 149 |
149 @override | 150 @override |
150 PackageMapInfo parsePackageMap(Map obj, Folder folder) { | 151 PackageMapInfo parsePackageMap(Map obj, Folder folder) { |
151 PackageMapInfo info = super.parsePackageMap(obj, folder); | 152 PackageMapInfo info = super.parsePackageMap(obj, folder); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 } | 200 } |
200 | 201 |
201 /** | 202 /** |
202 * Read the cache from disk if it has not been read before. | 203 * Read the cache from disk if it has not been read before. |
203 */ | 204 */ |
204 void _readCache() { | 205 void _readCache() { |
205 // TODO(danrubel) This implementation assumes that | 206 // TODO(danrubel) This implementation assumes that |
206 // two separate processes are not accessing the cache file at the same time | 207 // two separate processes are not accessing the cache file at the same time |
207 Source source = cacheFile.createSource(); | 208 Source source = cacheFile.createSource(); |
208 if (source.exists() && | 209 if (source.exists() && |
209 (_cache == null || _cacheModificationTime != source.modificationStamp))
{ | 210 (_cache == null || |
| 211 _cacheModificationTime != source.modificationStamp)) { |
210 try { | 212 try { |
211 TimestampedData<String> data = source.contents; | 213 TimestampedData<String> data = source.contents; |
212 Map map = JSON.decode(data.data); | 214 Map map = JSON.decode(data.data); |
213 if (map[cacheVersionKey] == cacheVersion) { | 215 if (map[cacheVersionKey] == cacheVersion) { |
214 _cache = map[cacheKey]; | 216 _cache = map[cacheKey]; |
215 _cacheModificationTime = data.modificationTime; | 217 _cacheModificationTime = data.modificationTime; |
216 } | 218 } |
217 } catch (exception, stackTrace) { | 219 } catch (exception, stackTrace) { |
218 AnalysisEngine.instance.logger.logInformation( | 220 AnalysisEngine.instance.logger.logInformation( |
219 'Exception reading $cacheFile\n$exception\n$stackTrace'); | 221 'Exception reading $cacheFile\n$exception\n$stackTrace'); |
220 } | 222 } |
221 } | 223 } |
222 if (_cache == null) { | 224 if (_cache == null) { |
223 _cache = new Map<String, Map>(); | 225 _cache = new Map<String, Map>(); |
224 } | 226 } |
225 } | 227 } |
226 | 228 |
227 /** | 229 /** |
228 * Write the cache to disk. | 230 * Write the cache to disk. |
229 */ | 231 */ |
230 void _writeCache() { | 232 void _writeCache() { |
231 try { | 233 try { |
232 _cacheModificationTime = _writeFile(cacheFile, JSON.encode({ | 234 _cacheModificationTime = _writeFile(cacheFile, |
233 cacheVersionKey: cacheVersion, | 235 JSON.encode({cacheVersionKey: cacheVersion, cacheKey: _cache})); |
234 cacheKey: _cache | |
235 })); | |
236 } catch (exception, stackTrace) { | 236 } catch (exception, stackTrace) { |
237 AnalysisEngine.instance.logger.logInformation( | 237 AnalysisEngine.instance.logger.logInformation( |
238 'Exception writing $cacheFile\n$exception\n$stackTrace'); | 238 'Exception writing $cacheFile\n$exception\n$stackTrace'); |
239 } | 239 } |
240 } | 240 } |
241 | 241 |
242 /** | 242 /** |
243 * Update the given file with the specified content. | 243 * Update the given file with the specified content. |
244 */ | 244 */ |
245 int _writeFileDefault(File cacheFile, String content) { | 245 int _writeFileDefault(File cacheFile, String content) { |
246 // TODO(danrubel) This implementation assumes that | 246 // TODO(danrubel) This implementation assumes that |
247 // two separate processes are not accessing the cache file at the same time | 247 // two separate processes are not accessing the cache file at the same time |
248 io.File file = new io.File(cacheFile.path); | 248 io.File file = new io.File(cacheFile.path); |
249 if (!file.parent.existsSync()) { | 249 if (!file.parent.existsSync()) { |
250 file.parent.createSync(recursive: true); | 250 file.parent.createSync(recursive: true); |
251 } | 251 } |
252 file.writeAsStringSync(content, flush: true); | 252 file.writeAsStringSync(content, flush: true); |
253 return file.lastModifiedSync().millisecondsSinceEpoch; | 253 return file.lastModifiedSync().millisecondsSinceEpoch; |
254 } | 254 } |
255 } | 255 } |
OLD | NEW |