From 3bcbcb4f048585be149865630ccae44b93b897c5 Mon Sep 17 00:00:00 2001 From: Renaud Paquay Date: Thu, 9 Jun 2011 08:38:16 -0700 Subject: [PATCH 1/3] #17920: Fix multi-threading issue Work Item: 17920 --HG-- branch : 1.x --- .../Orchard/HostContext/CommandHostContextProvider.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Tools/Orchard/HostContext/CommandHostContextProvider.cs b/src/Tools/Orchard/HostContext/CommandHostContextProvider.cs index 082bc3c84..12505b9db 100644 --- a/src/Tools/Orchard/HostContext/CommandHostContextProvider.cs +++ b/src/Tools/Orchard/HostContext/CommandHostContextProvider.cs @@ -113,7 +113,12 @@ namespace Orchard.HostContext { } private static CommandHost CreateWorkerAppDomainWithHost(string virtualPath, string physicalPath, Type hostType) { - ClientBuildManager clientBuildManager = new ClientBuildManager(virtualPath, physicalPath); + var clientBuildManager = new ClientBuildManager(virtualPath, physicalPath); + // Fix for http://orchard.codeplex.com/workitem/17920 + // By forcing the CBM to build App_Code, etc, we ensure that the ASP.NET BuildManager + // is in a state where it can safely (i.e. in a multi-threaded safe way) process + // multiple concurrent calls to "GetCompiledAssembly". + clientBuildManager.CompileApplicationDependencies(); return (CommandHost)clientBuildManager.CreateObject(hostType, false); } } From 340c2bdbc2adba12783fb21dc86c71cd9c9811b6 Mon Sep 17 00:00:00 2001 From: Renaud Paquay Date: Thu, 9 Jun 2011 09:07:41 -0700 Subject: [PATCH 2/3] #17728: Workaround asp.net bug loading incorrect version of System. Some of our assemblies in "~/bin" reference "System, Version=2.0.0.0". During the first time site compilation in the command line scenario, asp.net will sometimes decide to load that version of the assembly from disk (from the GAC), even though the application is configured to run on .NET 4.0. The workaround is to remove a couple of web.config elements, so that ASP.NET will load the correct version of those assemblies at startup. Work Item: 17728 --HG-- branch : 1.x --- src/Orchard.Web/Web.config | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Orchard.Web/Web.config b/src/Orchard.Web/Web.config index c337ae4ce..e89891961 100644 --- a/src/Orchard.Web/Web.config +++ b/src/Orchard.Web/Web.config @@ -63,8 +63,6 @@ - - From e4e359e5c1906fcccef31ec1d3adc5165107dc8f Mon Sep 17 00:00:00 2001 From: Renaud Paquay Date: Thu, 9 Jun 2011 12:53:33 -0700 Subject: [PATCH 3/3] #17923: Modules from ~/Bin and ~/Core have higher priority Because of the way ASP.NET BuildManager works(*), we can't enable dynamic compilation of a module if the module is already present in ~/bin. (*) When invoking the compiler, BuildManager automatically adds references to all assemblies present in ~/bin. So, if you have module "X" in "~/bin", there is no way to enable dynamic compilation of module "X" by compiling "X.csproj", as there will be tons of compilation errors with equivalent types defined in multiple assemblies. --HG-- branch : 1.x --- .../Extensions/ExtensionLoaderCoordinator.cs | 15 ++++++++++++++- .../Extensions/Loaders/CoreExtensionLoader.cs | 1 + .../Extensions/Loaders/IExtensionLoader.cs | 1 + .../Loaders/ReferencedExtensionLoader.cs | 4 +++- 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/Orchard/Environment/Extensions/ExtensionLoaderCoordinator.cs b/src/Orchard/Environment/Extensions/ExtensionLoaderCoordinator.cs index ad1c42f8b..298e9d5b3 100644 --- a/src/Orchard/Environment/Extensions/ExtensionLoaderCoordinator.cs +++ b/src/Orchard/Environment/Extensions/ExtensionLoaderCoordinator.cs @@ -247,7 +247,20 @@ namespace Orchard.Environment.Extensions { } private IEnumerable SortExtensionProbeEntries(IEnumerable entries, ConcurrentDictionary virtualPathModficationDates) { - return entries + // All "entries" are for the same extension ID, so we just need to filter/sort them by priority+ modification dates. + var groupByPriority = entries + .GroupBy(entry => entry.Priority) + .OrderByDescending(g => g.Key); + + // Select highest priority group with at least one item + var firstNonEmptyGroup = groupByPriority.FirstOrDefault(g => g.Count() >= 1) ?? Enumerable.Empty(); + + // No need for further sorting if only 1 item found + if (firstNonEmptyGroup.Count() <= 1) + return firstNonEmptyGroup; + + // Sort by last modification date/loader order + return firstNonEmptyGroup .OrderByDescending(probe => GetVirtualPathDepedenciesModificationTimeUtc(virtualPathModficationDates, probe)) .ThenBy(probe => probe.Loader.Order) .ToList(); diff --git a/src/Orchard/Environment/Extensions/Loaders/CoreExtensionLoader.cs b/src/Orchard/Environment/Extensions/Loaders/CoreExtensionLoader.cs index 9e6621ddb..f30b9b351 100644 --- a/src/Orchard/Environment/Extensions/Loaders/CoreExtensionLoader.cs +++ b/src/Orchard/Environment/Extensions/Loaders/CoreExtensionLoader.cs @@ -32,6 +32,7 @@ namespace Orchard.Environment.Extensions.Loaders { return new ExtensionProbeEntry { Descriptor = descriptor, Loader = this, + Priority = 100, // Higher priority because assemblies in ~/bin always take precedence VirtualPath = "~/Core/" + descriptor.Id, VirtualPathDependencies = Enumerable.Empty(), }; diff --git a/src/Orchard/Environment/Extensions/Loaders/IExtensionLoader.cs b/src/Orchard/Environment/Extensions/Loaders/IExtensionLoader.cs index eb904148a..d3890d616 100644 --- a/src/Orchard/Environment/Extensions/Loaders/IExtensionLoader.cs +++ b/src/Orchard/Environment/Extensions/Loaders/IExtensionLoader.cs @@ -9,6 +9,7 @@ namespace Orchard.Environment.Extensions.Loaders { public class ExtensionProbeEntry { public ExtensionDescriptor Descriptor { get; set; } public IExtensionLoader Loader { get; set; } + public int Priority { get; set; } public string VirtualPath { get; set; } public IEnumerable VirtualPathDependencies { get; set; } } diff --git a/src/Orchard/Environment/Extensions/Loaders/ReferencedExtensionLoader.cs b/src/Orchard/Environment/Extensions/Loaders/ReferencedExtensionLoader.cs index 9bee57fd7..c3d4581b1 100644 --- a/src/Orchard/Environment/Extensions/Loaders/ReferencedExtensionLoader.cs +++ b/src/Orchard/Environment/Extensions/Loaders/ReferencedExtensionLoader.cs @@ -1,4 +1,5 @@ -using System.IO; +using System.Collections.Generic; +using System.IO; using System.Linq; using Orchard.Environment.Extensions.Models; using Orchard.FileSystems.Dependencies; @@ -59,6 +60,7 @@ namespace Orchard.Environment.Extensions.Loaders { return new ExtensionProbeEntry { Descriptor = descriptor, Loader = this, + Priority = 100, // Higher priority because assemblies in ~/bin always take precedence VirtualPath = assemblyPath, VirtualPathDependencies = new[] { assemblyPath }, };