From 7084ecbbbc728eb1f91c9f9f9c8ac0c78f27ee76 Mon Sep 17 00:00:00 2001 From: Renaud Paquay Date: Thu, 26 May 2011 18:11:51 -0700 Subject: [PATCH] #17804: Ensure views are recompiled more aggressively When a module changes, it's loader can change, which means the list of dependencies can change to. Instead of trying to track the list of dependencies, we now simply add a dependency on a file on disk which describe the module compilation state. As an aside, this also improves startup performance when there were no changes to a site, since asp.net now only has to check a single file instead of the list of dependencies. --HG-- branch : 1.x --- .../DefaultModuleDependenciesManager.cs | 49 +++++++++++++------ .../WebFormsExtensionsVirtualPathProvider.cs | 8 ++- .../Razor/IRazorCompilationEvents.cs | 5 +- 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/src/Orchard/FileSystems/Dependencies/DefaultModuleDependenciesManager.cs b/src/Orchard/FileSystems/Dependencies/DefaultModuleDependenciesManager.cs index 8d80b99fa..99a1566cf 100644 --- a/src/Orchard/FileSystems/Dependencies/DefaultModuleDependenciesManager.cs +++ b/src/Orchard/FileSystems/Dependencies/DefaultModuleDependenciesManager.cs @@ -43,10 +43,12 @@ namespace Orchard.FileSystems.Dependencies { } public IEnumerable GetVirtualPathDependencies(DependencyDescriptor descriptor) { - // Currently, we return the same file for every module. An improvement would be to return - // a specific file per module (this would decrease the number of recompilations needed - // when modules change on disk). - yield return _appDataFolder.GetVirtualPath(PersistencePath); + if (IsSupportedLoader(descriptor.LoaderName)) { + // Currently, we return the same file for every module. An improvement would be to return + // a specific file per module (this would decrease the number of recompilations needed + // when modules change on disk). + yield return _appDataFolder.GetVirtualPath(PersistencePath); + } } private XDocument CreateDocument(IEnumerable dependencies) { @@ -54,22 +56,39 @@ namespace Orchard.FileSystems.Dependencies { var document = new XDocument(); document.Add(new XElement(ns("Dependencies"))); - var elements = dependencies.Select(d => new XElement("Dependency", - new XElement(ns("ModuleName"), d.Name), - new XElement(ns("LoaderName"), d.LoaderName), - new XElement(ns("VirtualPath"), d.VirtualPath), - new XElement(ns("FileHash"), _virtualPathProvider.GetFileHash(d.VirtualPath)), - new XElement(ns("References"), d.References - .Select(r => new XElement(ns("Reference"), - new XElement(ns("Name"), r.Name), - new XElement(ns("LoaderName"), r.LoaderName), - new XElement(ns("VirtualPath"), r.VirtualPath), - new XElement(ns("FileHash"), _virtualPathProvider.GetFileHash(r.VirtualPath)))).ToArray()))); + var elements = FilterDependencies(dependencies).Select( + d => new XElement("Dependency", + new XElement(ns("ModuleName"), d.Name), + new XElement(ns("LoaderName"), d.LoaderName), + new XElement(ns("VirtualPath"), d.VirtualPath), + new XElement(ns("FileHash"), _virtualPathProvider.GetFileHash(d.VirtualPath)), + new XElement(ns("References"), FilterReferences(d.References) + .Select(r => new XElement(ns("Reference"), + new XElement(ns("Name"), r.Name), + new XElement(ns("LoaderName"), r.LoaderName), + new XElement(ns("VirtualPath"), r.VirtualPath), + new XElement(ns("FileHash"), _virtualPathProvider.GetFileHash(r.VirtualPath)))).ToArray()))); document.Root.Add(elements); return document; } + private IEnumerable FilterDependencies(IEnumerable dependencies) { + return dependencies.Where(dep => IsSupportedLoader(dep.LoaderName)); + } + + private IEnumerable FilterReferences(IEnumerable references) { + return references.Where(dep => IsSupportedLoader(dep.LoaderName)); + } + + private bool IsSupportedLoader(string loaderName) { + //Note: this is hard-coded for now, to avoid adding more responsibilities to the IExtensionLoader + // implementations. + return + loaderName == "DynamicExtensionLoader" || + loaderName == "PrecompiledExtensionLoader"; + } + private void WriteDocument(string persistancePath, XDocument document) { using (var stream = _appDataFolder.CreateFile(persistancePath)) { document.Save(stream, SaveOptions.None); diff --git a/src/Orchard/FileSystems/Dependencies/WebFormsExtensionsVirtualPathProvider.cs b/src/Orchard/FileSystems/Dependencies/WebFormsExtensionsVirtualPathProvider.cs index b39381713..a02a3cf5d 100644 --- a/src/Orchard/FileSystems/Dependencies/WebFormsExtensionsVirtualPathProvider.cs +++ b/src/Orchard/FileSystems/Dependencies/WebFormsExtensionsVirtualPathProvider.cs @@ -21,13 +21,15 @@ namespace Orchard.FileSystems.Dependencies { /// public class WebFormVirtualPathProvider : VirtualPathProvider, ICustomVirtualPathProvider { private readonly IDependenciesFolder _dependenciesFolder; + private readonly IModuleDependenciesManager _moduleDependenciesManager; private readonly IEnumerable _loaders; private readonly string[] _modulesPrefixes = { "~/Modules/" }; private readonly string[] _themesPrefixes = { "~/Themes/" }; private readonly string[] _extensions = { ".ascx", ".aspx", ".master" }; - public WebFormVirtualPathProvider(IDependenciesFolder dependenciesFolder, IEnumerable loaders) { + public WebFormVirtualPathProvider(IDependenciesFolder dependenciesFolder, IModuleDependenciesManager moduleDependenciesManager, IEnumerable loaders) { _dependenciesFolder = dependenciesFolder; + _moduleDependenciesManager = moduleDependenciesManager; _loaders = loaders; Logger = NullLogger.Instance; } @@ -60,7 +62,9 @@ namespace Orchard.FileSystems.Dependencies { var dependencies = virtualPathDependencies .OfType() - .Concat(file.Loaders.SelectMany(dl => dl.Loader.GetVirtualPathDependencies(dl.Descriptor))); + .Concat(file.Loaders.SelectMany(dl => _moduleDependenciesManager.GetVirtualPathDependencies(dl.Descriptor))) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToList(); if (Logger.IsEnabled(LogLevel.Debug)) { Logger.Debug("GetFileHash(\"{0}\") - virtual path dependencies:", virtualPath); diff --git a/src/Orchard/Mvc/ViewEngines/Razor/IRazorCompilationEvents.cs b/src/Orchard/Mvc/ViewEngines/Razor/IRazorCompilationEvents.cs index 6e6b861c5..79fd2cf79 100644 --- a/src/Orchard/Mvc/ViewEngines/Razor/IRazorCompilationEvents.cs +++ b/src/Orchard/Mvc/ViewEngines/Razor/IRazorCompilationEvents.cs @@ -25,17 +25,20 @@ namespace Orchard.Mvc.ViewEngines.Razor { /// public class DefaultRazorCompilationEvents : IRazorCompilationEvents { private readonly IDependenciesFolder _dependenciesFolder; + private readonly IModuleDependenciesManager _moduleDependenciesManager; private readonly IBuildManager _buildManager; private readonly IEnumerable _loaders; private readonly IAssemblyLoader _assemblyLoader; public DefaultRazorCompilationEvents( IDependenciesFolder dependenciesFolder, + IModuleDependenciesManager moduleDependenciesManager, IBuildManager buildManager, IEnumerable loaders, IAssemblyLoader assemblyLoader) { _dependenciesFolder = dependenciesFolder; + _moduleDependenciesManager = moduleDependenciesManager; _buildManager = buildManager; _loaders = loaders; _assemblyLoader = assemblyLoader; @@ -67,7 +70,7 @@ namespace Orchard.Mvc.ViewEngines.Razor { loader, descriptor, references = loader.GetCompilationReferences(descriptor), - dependencies = loader.GetVirtualPathDependencies(descriptor) + dependencies = _moduleDependenciesManager.GetVirtualPathDependencies(descriptor) })); foreach (var entry in entries) {