Example #1
0
 public AutoCompleteResourceV3(HttpSource client, ServiceIndexResourceV3 serviceIndex, RegistrationResourceV3 regResource)
     : base()
 {
     _regResource  = regResource;
     _serviceIndex = serviceIndex;
     _client       = client;
 }
        public override async Task <Tuple <bool, INuGetResource> > TryCreate(SourceRepository source, CancellationToken token)
        {
            ServiceIndexResourceV3 index     = null;
            ServiceIndexCacheInfo  cacheInfo = null;
            var url = source.PackageSource.Source;

            // the file type can easily rule out if we need to request the url
            if (source.PackageSource.ProtocolVersion == 3 ||
                (source.PackageSource.IsHttp &&
                 url.EndsWith(".json", StringComparison.OrdinalIgnoreCase)))
            {
                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)
                        {
                            index = await GetServiceIndexResourceV3(source, utcNow, NullLogger.Instance, token);

                            // cache the value even if it is null to avoid checking it again later
                            var cacheEntry = new ServiceIndexCacheInfo
                            {
                                CachedTime = utcNow,
                                Index      = index
                            };

                            // If the cache entry has expired it will already exist
                            _cache.AddOrUpdate(url, cacheEntry, (key, value) => cacheEntry);
                        }
                    }
                    finally
                    {
                        if (release)
                        {
                            _semaphore.Release();
                        }
                    }
                }
            }

            if (index == null && cacheInfo != null)
            {
                index = cacheInfo.Index;
            }

            return(new Tuple <bool, INuGetResource>(index != null, index));
        }