Modify RazorPreCompileModule to use an instance of memory cache specific

to the application's target framework and configuration.
This commit is contained in:
Pranav K 2015-08-25 14:33:39 -07:00
parent 44b45f3b1f
commit 3041dee86d
2 changed files with 50 additions and 7 deletions

View File

@ -2,11 +2,14 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Runtime.Versioning;
using Microsoft.AspNet.FileProviders;
using Microsoft.Dnx.Compilation.CSharp;
using Microsoft.Dnx.Runtime;
using Microsoft.Framework.Caching.Memory;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Mvc.Razor.Precompilation
{
@ -16,7 +19,9 @@ namespace Microsoft.AspNet.Mvc.Razor.Precompilation
public abstract class RazorPreCompileModule : ICompileModule
{
private readonly IAssemblyLoadContext _loadContext;
private readonly IMemoryCache _memoryCache;
private readonly object _memoryCacheLookupLock = new object();
private readonly Dictionary<PrecompilationCacheKey, MemoryCache> _memoryCacheLookup =
new Dictionary<PrecompilationCacheKey, MemoryCache>();
/// <summary>
/// Instantiates a new <see cref="RazorPreCompileModule"/> instance.
@ -25,11 +30,6 @@ namespace Microsoft.AspNet.Mvc.Razor.Precompilation
public RazorPreCompileModule(IServiceProvider services)
{
_loadContext = services.GetRequiredService<IAssemblyLoadContext>();
// When CompactOnMemoryPressure is true, the MemoryCache evicts items at every gen2 collection.
// In DTH, gen2 happens frequently enough to make it undesirable for caching precompilation results. We'll
// disable listening for memory pressure for the MemoryCache instance used by precompilation.
_memoryCache = new MemoryCache(new MemoryCacheOptions { CompactOnMemoryPressure = false });
}
/// <summary>
@ -43,11 +43,31 @@ namespace Microsoft.AspNet.Mvc.Razor.Precompilation
{
var fileProvider = new PhysicalFileProvider(context.ProjectContext.ProjectDirectory);
MemoryCache memoryCache;
lock (_memoryCacheLookupLock)
{
var cacheKey = new PrecompilationCacheKey
{
Configuration = context.ProjectContext.Configuration,
TargetFramework = context.ProjectContext.TargetFramework
};
if (!_memoryCacheLookup.TryGetValue(cacheKey, out memoryCache))
{
// When CompactOnMemoryPressure is true, the MemoryCache evicts items at every gen2 collection.
// In DTH, gen2 happens frequently enough to make it undesirable for caching precompilation results. We'll
// disable listening for memory pressure for the MemoryCache instance used by precompilation.
memoryCache = new MemoryCache(new MemoryCacheOptions { CompactOnMemoryPressure = false });
_memoryCacheLookup[cacheKey] = memoryCache;
}
}
var viewCompiler = new RazorPreCompiler(
context,
_loadContext,
fileProvider,
_memoryCache)
memoryCache)
{
GenerateSymbols = GenerateSymbols
};
@ -59,5 +79,27 @@ namespace Microsoft.AspNet.Mvc.Razor.Precompilation
public void AfterCompile(AfterCompileContext context)
{
}
private class PrecompilationCacheKey : IEquatable<PrecompilationCacheKey>
{
public string Configuration { get; set; }
public FrameworkName TargetFramework { get; set; }
public bool Equals(PrecompilationCacheKey other)
{
return
other.TargetFramework == TargetFramework &&
string.Equals(other.Configuration, Configuration, StringComparison.Ordinal);
}
public override int GetHashCode()
{
return HashCodeCombiner
.Start()
.Add(Configuration)
.Add(TargetFramework);
}
}
}
}

View File

@ -12,6 +12,7 @@
"Microsoft.AspNet.Mvc.Razor.Host": "6.0.0-*",
"Microsoft.AspNet.Mvc.ViewFeatures": "6.0.0-*",
"Microsoft.AspNet.PageExecutionInstrumentation.Interfaces": "1.0.0-*",
"Microsoft.Framework.HashCodeCombiner.Sources": { "version": "1.0.0-*", "type": "build" },
"Microsoft.Framework.NotNullAttribute.Sources": { "version": "1.0.0-*", "type": "build" },
"Microsoft.Framework.PropertyActivator.Sources": { "version": "1.0.0-*", "type": "build" },
"Microsoft.Framework.PropertyHelper.Sources": { "version": "1.0.0-*", "type": "build" },