private async Task ProcessWithDiskCache(HttpContext context, string cacheKey, ImageJobInfo info) { var cacheResult = await diskCache.GetOrCreate(cacheKey, info.EstimatedFileExtension, async (stream) => { if (info.HasParams) { logger?.LogInformation("DiskCache Miss: Processing image {VirtualPath}{QueryString}", info.FinalVirtualPath, info); var result = await info.ProcessUncached(); if (result.ResultBytes.Array == null) { throw new InvalidOperationException("Image job returned zero bytes."); } await stream.WriteAsync(result.ResultBytes.Array, result.ResultBytes.Offset, result.ResultBytes.Count, CancellationToken.None); await stream.FlushAsync(); } else { logger?.LogInformation("DiskCache Miss: Proxying image {VirtualPath}", info.FinalVirtualPath); await info.CopyPrimaryBlobToAsync(stream); } }); if (cacheResult.Result == CacheQueryResult.Miss) { GlobalPerf.Singleton.IncrementCounter("diskcache_miss"); } else if (cacheResult.Result == CacheQueryResult.Hit) { GlobalPerf.Singleton.IncrementCounter("diskcache_hit"); } else if (cacheResult.Result == CacheQueryResult.Failed) { GlobalPerf.Singleton.IncrementCounter("diskcache_timeout"); } // Note that using estimated file extension instead of parsing magic bytes will lead to incorrect content-type // values when the source file has a mismatched extension. if (cacheResult.Data != null) { if (cacheResult.Data.Length < 1) { throw new InvalidOperationException("DiskCache returned cache entry with zero bytes"); } SetCachingHeaders(context, cacheKey); await MagicBytes.ProxyToStream(cacheResult.Data, context.Response); } else { logger?.LogInformation("Serving {0}?{1} from disk cache {2}", info.FinalVirtualPath, info.CommandString, cacheResult.RelativePath); await ServeFileFromDisk(context, cacheResult.PhysicalPath, cacheKey); } }
private async Task ProcessWithDiskCache(HttpContext context, string cacheKey, ImageJobInfo info) { var cacheResult = await diskCache.GetOrCreate(cacheKey, info.EstimatedFileExtension, async (stream) => { if (info.HasParams) { logger?.LogInformation($"DiskCache Miss: Processing image {info.FinalVirtualPath}?{info}"); var result = await info.ProcessUncached(); await stream.WriteAsync(result.ResultBytes.Array, result.ResultBytes.Offset, result.ResultBytes.Count, CancellationToken.None); await stream.FlushAsync(); } else { logger?.LogInformation($"DiskCache Miss: Proxying image {info.FinalVirtualPath}"); await info.CopyPrimaryBlobToAsync(stream); } }); // Note that using estimated file extension instead of parsing magic bytes will lead to incorrect content-type // values when the source file has a mismatched extension. if (cacheResult.Data != null) { if (cacheResult.Data.Length < 1) { throw new InvalidOperationException("DiskCache returned cache entry with zero bytes"); } context.Response.ContentType = PathHelpers.ContentTypeForImageExtension(info.EstimatedFileExtension); context.Response.ContentLength = cacheResult.Data.Length; //ReadOnlyMemoryStream, so it supports seeking SetCachingHeaders(context, cacheKey); await cacheResult.Data.CopyToAsync(context.Response.Body); } else { logger?.LogInformation("Serving {0}?{1} from disk cache {2}", info.FinalVirtualPath, info.CommandString, cacheResult.RelativePath); await ServeFileFromDisk(context, cacheResult.PhysicalPath, cacheKey, PathHelpers.ContentTypeForImageExtension(info.EstimatedFileExtension)); } }