public virtual void CacheSearchResult(string folderPath, string pattern, IEnumerable <string> result)
 {
     _searchCache[new SearchQuery(folderPath, pattern)] = new CachedSearchResult()
     {
         Result   = result,
         CachedAt = DateTime.Now
     };
 }
        public virtual bool GetCachedSearchResult(string folderPath, string pattern, out CachedSearchResult result)
        {
            var key = new SearchQuery(folderPath, pattern);

            if (_searchCache.ContainsKey(key))
            {
                result = _searchCache[key];
                return(true);
            }
            result = new CachedSearchResult();
            return(false);
        }
Example #3
0
        public IQueryable <V2FeedPackage> Search(string searchTerm, string targetFramework, bool includePrerelease)
        {
            var packages = PackageRepo.GetAll()
                           .Include(p => p.Authors)
                           .Include(p => p.PackageRegistration)
                           .Include(p => p.PackageRegistration.Owners)
                           .Where(p => p.Listed);

            // Check if the caller is requesting packages or calling the count operation.
            bool requestingCount = HttpContext.Request.RawUrl.Contains("$count");

            var isEmptySearchTerm = string.IsNullOrEmpty(searchTerm);

            if ((requestingCount && isEmptySearchTerm) || isEmptySearchTerm)
            {
                // Fetch the cache key for the empty search query.
                string cacheKey = GetCacheKeyForEmptySearchQuery(includePrerelease);

                IQueryable <V2FeedPackage> searchResults;
                DateTime lastModified;

                var cachedObject    = HttpContext.Cache.Get(cacheKey);
                var currentDateTime = DateTime.UtcNow;
                if (cachedObject == null && !requestingCount)
                {
                    searchResults = SearchV2FeedCore(packages, searchTerm, targetFramework, includePrerelease, useCache: false);

                    lastModified = currentDateTime;

                    // cache the most common search query
                    // note: this is per instance cache
                    var cachedPackages = searchResults.ToList();

                    // don't cache empty results in case we missed any potential ODATA expressions
                    if (!cachedPackages.Any())
                    {
                        var cachedSearchResult = new CachedSearchResult();
                        cachedSearchResult.LastModified = currentDateTime;
                        cachedSearchResult.Packages     = cachedPackages;

                        HttpContext.Cache.Add(
                            cacheKey,
                            cachedSearchResult,
                            null,
                            currentDateTime.AddSeconds(DEFAULT_CACHE_TIME_SECONDS_V2FEED),
                            Cache.NoSlidingExpiration,
                            CacheItemPriority.Default,
                            null);
                    }
                }
                else if (cachedObject == null)
                {
                    // first hit on $count and nothing in cache yet;
                    // we can't cache due to the $count hijack in SearchV2FeedCore...
                    return(SearchV2FeedCore(packages, searchTerm, targetFramework, includePrerelease, useCache: false));
                }
                else
                {
                    var cachedSearchResult = (CachedSearchResult)cachedObject;
                    searchResults = cachedSearchResult.Packages.AsQueryable();
                    lastModified  = cachedSearchResult.LastModified;
                }
                // Clients should cache twice as long.
                // This way, they won't notice differences in the short-lived per instance cache.
                HttpContext.Response.Cache.SetCacheability(HttpCacheability.Public);
                HttpContext.Response.Cache.SetMaxAge(TimeSpan.FromSeconds(60));
                HttpContext.Response.Cache.SetExpires(currentDateTime.AddSeconds(DEFAULT_CACHE_TIME_SECONDS_V2FEED * 2));
                HttpContext.Response.Cache.SetLastModified(lastModified);
                HttpContext.Response.Cache.SetValidUntilExpires(true);

                return(searchResults);
            }

            return(SearchV2FeedCore(packages, searchTerm, targetFramework, includePrerelease, useCache: true));
        }
Example #4
0
        public IQueryable <V2FeedPackage> Search(string searchTerm, string targetFramework, bool includePrerelease)
        {
            // Handle OData-style |-separated list of frameworks.
            string[] targetFrameworkList = (targetFramework ?? "").Split(new[] { '\'', '|' }, StringSplitOptions.RemoveEmptyEntries);

            // For now, we'll just filter on the first one.
            if (targetFrameworkList.Length > 0)
            {
                // Until we support multiple frameworks, we need to prefer aspnet50 over aspnetcore50.
                if (targetFrameworkList.Contains("aspnet50"))
                {
                    targetFramework = "aspnet50";
                }
                else
                {
                    targetFramework = targetFrameworkList[0];
                }
            }

            // Check if the caller is requesting packages or calling the count operation.
            bool requestingCount = HttpContext.Request.RawUrl.Contains("$count");

            var isEmptySearchTerm = string.IsNullOrEmpty(searchTerm);

            if ((requestingCount && isEmptySearchTerm) || isEmptySearchTerm)
            {
                // Fetch the cache key for the empty search query.
                string cacheKey = GetCacheKeyForEmptySearchQuery(targetFramework, includePrerelease);

                IQueryable <V2FeedPackage> searchResults;
                DateTime lastModified;

                var cachedObject    = HttpContext.Cache.Get(cacheKey);
                var currentDateTime = DateTime.UtcNow;
                if (cachedObject == null && !requestingCount)
                {
                    searchResults = SearchV2FeedCore(searchTerm, targetFramework, includePrerelease);

                    lastModified = currentDateTime;

                    // cache the most common search query
                    // note: this is per instance cache
                    var cachedPackages = searchResults.ToList();

                    // don't cache empty resulsets in case we missed any potential ODATA expressions
                    if (!cachedPackages.Any())
                    {
                        var cachedSearchResult = new CachedSearchResult();
                        cachedSearchResult.LastModified = currentDateTime;
                        cachedSearchResult.Packages     = cachedPackages;

                        HttpContext.Cache.Add(cacheKey, cachedSearchResult, null,
                                              currentDateTime.AddSeconds(ServerCacheExpirationInSeconds),
                                              Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
                    }
                }
                else if (cachedObject == null)
                {
                    // first hit on $count and nothing in cache yet;
                    // we can't cache due to the $count hijack in SearchV2FeedCore...
                    return(SearchV2FeedCore(searchTerm, targetFramework, includePrerelease));
                }
                else
                {
                    var cachedSearchResult = (CachedSearchResult)cachedObject;
                    searchResults = cachedSearchResult.Packages.AsQueryable();
                    lastModified  = cachedSearchResult.LastModified;
                }

                // Clients should cache twice as long.
                // This way, they won't notice differences in the short-lived per instance cache.
                HttpContext.Response.Cache.SetCacheability(HttpCacheability.Public);
                HttpContext.Response.Cache.SetMaxAge(TimeSpan.FromSeconds(60));
                HttpContext.Response.Cache.SetExpires(currentDateTime.AddSeconds(ServerCacheExpirationInSeconds * 2));
                HttpContext.Response.Cache.SetLastModified(lastModified);
                HttpContext.Response.Cache.SetValidUntilExpires(true);

                return(searchResults);
            }

            return(SearchV2FeedCore(searchTerm, targetFramework, includePrerelease));
        }