private Task <IBundleCacheItem> GetBundleCacheItem(BundleCacheKey cacheKey, IBundleModel bundle, QueryString query, IDictionary <string, StringValues> @params, HttpContext httpContext, bool lockFile) { return(_cache.GetOrAddAsync( cacheKey, async _ => { long startTicks = Stopwatch.GetTimestamp(); BundleCacheData cacheItem; try { cacheItem = await BuildBundleAsync(bundle, query, @params, httpContext); } catch (OperationCanceledException) { _logger.LogInformation("Bundle [{MANAGER_ID}]:{PATH}{QUERY} was not built. Build was cancelled.", _id, bundle.Path, query); throw; } catch { _logger.LogInformation("Bundle [{MANAGER_ID}]:{PATH}{QUERY} was not built. Build failed.", _id, bundle.Path, query); throw; } long endTicks = Stopwatch.GetTimestamp(); if (_logger.IsEnabled(LogLevel.Information)) { long elapsedMs = (endTicks - startTicks) / (Stopwatch.Frequency / 1000); _logger.LogInformation("Bundle [{MANAGER_ID}]:{PATH}{QUERY} was built in {ELAPSED}ms.", _id, bundle.Path, query, elapsedMs); } return cacheItem; }, httpContext.RequestAborted, bundle.CacheOptions, lockFile)); }
public async Task <bool> TryEnsureUrlAsync(HttpContext httpContext) { var branchPath = httpContext.Request.Path; if (!branchPath.StartsWithSegments(_bundlingContext.BundlesPathPrefix, out PathString bundlePath)) { return(false); } var query = httpContext.Request.QueryString; _urlHelper.RemoveVersion(ref bundlePath, ref query); if (!_bundles.TryGetValue(bundlePath, out IBundleModel bundle)) { return(false); } var disposer = httpContext.RequestServices.GetRequiredService <IScopedDisposer>(); query = UrlUtils.NormalizeQuery(query, out IDictionary <string, StringValues> @params); if (!bundle.DependsOnParams) { query = QueryString.Empty; } var cacheKey = new BundleCacheKey(_id, bundlePath, query); var cacheItem = await _cache.GetOrAddAsync(cacheKey, ct => BuildBundleAsync(bundle, query, @params, httpContext), httpContext.RequestAborted, bundle.CacheOptions, lockFile : true); try { // scheduling release of the lock for the end of the scope (request), // so that the file remain unchanged until it's served disposer.Register(cacheItem.FileReleaser); } catch (Exception ex) { cacheItem.FileReleaser.Dispose(); ExceptionDispatchInfo.Capture(ex).Throw(); throw; } // passing file info to GetFileInfo(), which is called later in the request (see BundlingMiddleware and BundleFileProvider) httpContext.Items.Add(httpContextItemKey, cacheItem.FileInfo); return(true); }
public async Task <bool> TryEnsureUrlAsync(HttpContext httpContext) { PathString branchPath = httpContext.Request.Path; if (!branchPath.StartsWithSegments(_bundlingContext.BundlesPathPrefix, out PathString bundlePath)) { return(false); } QueryString query = httpContext.Request.QueryString; _urlHelper.RemoveVersion(ref bundlePath, ref query); if (!_bundles.TryGetValue(bundlePath, out IBundleModel bundle)) { return(false); } query = UrlUtils.NormalizeQuery(query, out IDictionary <string, StringValues> @params); if (!bundle.DependsOnParams) { query = QueryString.Empty; } var cacheKey = new BundleCacheKey(_id, bundlePath, query); IBundleCacheItem cacheItem = await GetBundleCacheItem(cacheKey, bundle, query, @params, httpContext, lockFile : true); try { // scheduling release of the lock for the end of the request so that the file remain unchanged until it's served httpContext.ScheduleDisposeForRequestEnd(cacheItem.FileReleaser); } catch { cacheItem.FileReleaser.Dispose(); throw; } // passing file info to GetFileInfo(), which is called later in the request (see BundlingMiddleware and BundleFileProvider) httpContext.Items.Add(s_httpContextItemKey, cacheItem.FileInfo); return(true); }
public async Task <string> TryGenerateUrlAsync(PathString path, QueryString query, HttpContext httpContext) { PathString pathPrefix = httpContext.Request.PathBase + _bundlingContext.BundlesPathPrefix; if (!path.StartsWithSegments(pathPrefix, out PathString bundlePath) || !_bundles.TryGetValue(bundlePath, out IBundleModel bundle)) { return(null); } query = UrlUtils.NormalizeQuery(query, out IDictionary <string, StringValues> @params); if (!bundle.DependsOnParams) { query = QueryString.Empty; } var cacheKey = new BundleCacheKey(_id, bundlePath, query); IBundleCacheItem cacheItem = await GetBundleCacheItem(cacheKey, bundle, query, @params, httpContext, lockFile : false); _urlHelper.AddVersion(cacheItem.Version, ref bundlePath, ref query); return(pathPrefix + bundlePath + query); }