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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
using System.Collections.Generic;
using System.Runtime.Versioning;
using Microsoft.AspNet.FileProviders; using Microsoft.AspNet.FileProviders;
using Microsoft.Dnx.Compilation.CSharp; using Microsoft.Dnx.Compilation.CSharp;
using Microsoft.Dnx.Runtime; using Microsoft.Dnx.Runtime;
using Microsoft.Framework.Caching.Memory; using Microsoft.Framework.Caching.Memory;
using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Mvc.Razor.Precompilation namespace Microsoft.AspNet.Mvc.Razor.Precompilation
{ {
@ -16,7 +19,9 @@ namespace Microsoft.AspNet.Mvc.Razor.Precompilation
public abstract class RazorPreCompileModule : ICompileModule public abstract class RazorPreCompileModule : ICompileModule
{ {
private readonly IAssemblyLoadContext _loadContext; 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> /// <summary>
/// Instantiates a new <see cref="RazorPreCompileModule"/> instance. /// Instantiates a new <see cref="RazorPreCompileModule"/> instance.
@ -25,11 +30,6 @@ namespace Microsoft.AspNet.Mvc.Razor.Precompilation
public RazorPreCompileModule(IServiceProvider services) public RazorPreCompileModule(IServiceProvider services)
{ {
_loadContext = services.GetRequiredService<IAssemblyLoadContext>(); _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> /// <summary>
@ -43,11 +43,31 @@ namespace Microsoft.AspNet.Mvc.Razor.Precompilation
{ {
var fileProvider = new PhysicalFileProvider(context.ProjectContext.ProjectDirectory); 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( var viewCompiler = new RazorPreCompiler(
context, context,
_loadContext, _loadContext,
fileProvider, fileProvider,
_memoryCache) memoryCache)
{ {
GenerateSymbols = GenerateSymbols GenerateSymbols = GenerateSymbols
}; };
@ -59,5 +79,27 @@ namespace Microsoft.AspNet.Mvc.Razor.Precompilation
public void AfterCompile(AfterCompileContext context) 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.Razor.Host": "6.0.0-*",
"Microsoft.AspNet.Mvc.ViewFeatures": "6.0.0-*", "Microsoft.AspNet.Mvc.ViewFeatures": "6.0.0-*",
"Microsoft.AspNet.PageExecutionInstrumentation.Interfaces": "1.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.NotNullAttribute.Sources": { "version": "1.0.0-*", "type": "build" },
"Microsoft.Framework.PropertyActivator.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" }, "Microsoft.Framework.PropertyHelper.Sources": { "version": "1.0.0-*", "type": "build" },