public override async Task <Tuple <bool, INuGetResource> > TryCreate( SourceRepository source, CancellationToken token) { ListResource resource = null; var serviceIndex = await source.GetResourceAsync <ServiceIndexResourceV3>(token); if (serviceIndex != null) { var baseUrl = serviceIndex.GetServiceEntryUri(ServiceTypes.LegacyGallery); if (baseUrl != null) { var httpSource = await source.GetResourceAsync <HttpSourceResource>(token); var serviceDocument = await ODataServiceDocumentUtils.CreateODataServiceDocumentResourceV2( baseUrl.AbsoluteUri, httpSource.HttpSource, DateTime.UtcNow, NullLogger.Instance, token); var parser = new V2FeedParser(httpSource.HttpSource, serviceDocument.BaseAddress, source.PackageSource.Source); var feedCapabilityResource = new LegacyFeedCapabilityResourceV2Feed(parser, serviceDocument.BaseAddress); resource = new V2FeedListResource(parser, feedCapabilityResource, serviceDocument.BaseAddress); } } var result = new Tuple <bool, INuGetResource>(resource != null, resource); return(result); }
public override async Task <Tuple <bool, INuGetResource> > TryCreate(SourceRepository source, CancellationToken token) { ODataServiceDocumentResourceV2 serviceDocument = null; ODataServiceDocumentCacheInfo cacheInfo = null; var url = source.PackageSource.Source; var utcNow = DateTime.UtcNow; var entryValidCutoff = utcNow.Subtract(MaxCacheDuration); // check the cache before downloading the file if (!_cache.TryGetValue(url, out cacheInfo) || entryValidCutoff > cacheInfo.CachedTime) { // Track if the semaphore needs to be released var release = false; try { await _semaphore.WaitAsync(token); release = true; token.ThrowIfCancellationRequested(); // check the cache again, another thread may have finished this one waited for the lock if (!_cache.TryGetValue(url, out cacheInfo) || entryValidCutoff > cacheInfo.CachedTime) { var client = (await source.GetResourceAsync <HttpSourceResource>(token)).HttpSource; serviceDocument = await ODataServiceDocumentUtils.CreateODataServiceDocumentResourceV2(url, client, utcNow, NullLogger.Instance, token); // cache the value even if it is null to avoid checking it again later var cacheEntry = new ODataServiceDocumentCacheInfo { CachedTime = utcNow, ServiceDocument = serviceDocument }; // If the cache entry has expired it will already exist _cache.AddOrUpdate(url, cacheEntry, (key, value) => cacheEntry); } } finally { if (release) { _semaphore.Release(); } } } if (serviceDocument == null && cacheInfo != null) { serviceDocument = cacheInfo.ServiceDocument; } return(new Tuple <bool, INuGetResource>(serviceDocument != null, serviceDocument)); }