@@ -341,6 +341,15 @@ class BoundHostedSource extends CachedSource {
341
341
return result;
342
342
}
343
343
344
+ /// An in-memory cache to store the cached version listing loaded from
345
+ /// [_versionListingCachePath] .
346
+ ///
347
+ /// Invariant: Entries in this cache are the parsed version of the exact same
348
+ /// information cached on disk. I.e. if the entry is present in this cache,
349
+ /// there will not be a newer version on disk.
350
+ final Map <PackageRef , Pair <DateTime , Map <PackageId , _VersionInfo >>>
351
+ _responseCache = {};
352
+
344
353
/// If a cached version listing response for [ref] exists on disk and is less
345
354
/// than [maxAge] old it is parsed and returned.
346
355
///
@@ -351,26 +360,35 @@ class BoundHostedSource extends CachedSource {
351
360
Future <Map <PackageId , _VersionInfo >> _cachedVersionListingResponse (
352
361
PackageRef ref,
353
362
{Duration maxAge}) async {
363
+ if (_responseCache.containsKey (ref)) {
364
+ final cacheAge = DateTime .now ().difference (_responseCache[ref].first);
365
+ if (maxAge == null || maxAge > cacheAge) {
366
+ // The cached value is not too old.
367
+ return _responseCache[ref].last;
368
+ }
369
+ }
354
370
final cachePath = _versionListingCachePath (ref);
355
371
final stat = io.File (cachePath).statSync ();
356
372
final now = DateTime .now ();
357
373
if (stat.type == io.FileSystemEntityType .file) {
358
374
if (maxAge == null || now.difference (stat.modified) < maxAge) {
359
375
try {
360
- final cachedDoc = jsonDecode (await readTextFileAsync (cachePath));
376
+ final cachedDoc = jsonDecode (readTextFile (cachePath));
361
377
final timestamp = cachedDoc['_fetchedAt' ];
362
378
if (timestamp is String ) {
363
- final cacheAge =
364
- DateTime .now ().difference (DateTime . parse (timestamp) );
379
+ final parsedTimestamp = DateTime . parse (timestamp);
380
+ final cacheAge = DateTime .now ().difference (parsedTimestamp );
365
381
if (maxAge != null && cacheAge > maxAge) {
366
382
// Too old according to internal timestamp - delete.
367
383
tryDeleteEntry (cachePath);
368
384
} else {
369
- return _versionInfoFromPackageListing (
385
+ var res = _versionInfoFromPackageListing (
370
386
cachedDoc,
371
387
ref,
372
388
Uri .file (cachePath),
373
389
);
390
+ _responseCache[ref] = Pair (parsedTimestamp, res);
391
+ return res;
374
392
}
375
393
}
376
394
} on io.IOException {
@@ -402,6 +420,9 @@ class BoundHostedSource extends CachedSource {
402
420
},
403
421
),
404
422
);
423
+ // Delete the entry in the in-memory cache to maintain the invariant that
424
+ // cached information in memory is the same as that on the disk.
425
+ _responseCache.remove (ref);
405
426
} on io.IOException catch (e) {
406
427
// Not being able to write this cache is not fatal. Just move on...
407
428
log.fine ('Failed writing cache file. $e ' );
0 commit comments