mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Add a configuration flag to disable cache files
The cache files cache.dat and mappings.bin can have concurrency issues in case multiple instances try to access them concurrently (see Azure Web Sites)
This commit is contained in:
@@ -74,12 +74,27 @@
|
||||
</Properties>
|
||||
</Component>
|
||||
|
||||
<Component Type="Orchard.Caching.DefaultParallelCacheContext">
|
||||
<Properties>
|
||||
<!-- Set Value="true" to disable parallel cache resolution -->
|
||||
<Property Name="Disabled" Value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component Type="Orchard.Caching.DefaultParallelCacheContext">
|
||||
<Properties>
|
||||
<!-- Set Value="true" to disable parallel cache resolution -->
|
||||
<Property Name="Disabled" Value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
|
||||
<Component Type="Orchard.Data.SessionConfigurationCache">
|
||||
<Properties>
|
||||
<!-- Set Value="true" to disable session configuration cache (mappings.bin). Recommended when using multiple instances. -->
|
||||
<Property Name="Disabled" Value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
|
||||
<Component Type="Orchard.Environment.Descriptor.ShellDescriptorCache">
|
||||
<Properties>
|
||||
<!-- Set Value="true" to disable shell descriptors cache (cache.dat). Recommended when using multiple instances. -->
|
||||
<Property Name="Disabled" Value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
|
||||
</Components>
|
||||
|
||||
</Components>
|
||||
</HostComponents>
|
||||
|
@@ -2,7 +2,7 @@ using System;
|
||||
using NHibernate.Cfg;
|
||||
|
||||
namespace Orchard.Data {
|
||||
public interface ISessionConfigurationCache : ISingletonDependency {
|
||||
public interface ISessionConfigurationCache {
|
||||
Configuration GetConfiguration(Func<Configuration> builder);
|
||||
}
|
||||
}
|
@@ -33,8 +33,13 @@ namespace Orchard.Data {
|
||||
}
|
||||
|
||||
public ILogger Logger { get; set; }
|
||||
public bool Disabled { get; set; }
|
||||
|
||||
public Configuration GetConfiguration(Func<Configuration> builder) {
|
||||
if (Disabled) {
|
||||
return builder();
|
||||
}
|
||||
|
||||
var hash = ComputeHash().Value;
|
||||
|
||||
// if the current configuration is unchanged, return it
|
||||
|
@@ -42,11 +42,13 @@ namespace Orchard.Environment.Descriptor {
|
||||
|
||||
public ILogger Logger { get; set; }
|
||||
public Localizer T { get; set; }
|
||||
public bool Disabled { get; set; }
|
||||
|
||||
#region Implementation of IShellDescriptorCache
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "StringReader closed by XmlReader.")]
|
||||
public ShellDescriptor Fetch(string name) {
|
||||
if (Disabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
lock (_synLock) {
|
||||
VerifyCacheFile();
|
||||
var text = _appDataFolder.ReadFile(DescriptorCacheFileName);
|
||||
@@ -67,8 +69,11 @@ namespace Orchard.Environment.Descriptor {
|
||||
|
||||
}
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "writer closed by xmlWriter.")]
|
||||
public void Store(string name, ShellDescriptor descriptor) {
|
||||
if (Disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
lock (_synLock) {
|
||||
VerifyCacheFile();
|
||||
var text = _appDataFolder.ReadFile(DescriptorCacheFileName);
|
||||
@@ -97,8 +102,6 @@ namespace Orchard.Environment.Descriptor {
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private static string GetCacheTextForShellDescriptor(ShellDescriptor descriptor) {
|
||||
var sb = new StringBuilder();
|
||||
sb.Append(descriptor.SerialNumber + "|");
|
||||
@@ -125,19 +128,19 @@ namespace Orchard.Environment.Descriptor {
|
||||
return shellDescriptor;
|
||||
}
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
|
||||
/// <summary>
|
||||
/// Creates an empty cache file if it doesn't exist already
|
||||
/// </summary>
|
||||
private void VerifyCacheFile() {
|
||||
if (!_appDataFolder.FileExists(DescriptorCacheFileName)) {
|
||||
var writer = new StringWriter();
|
||||
using (XmlWriter xmlWriter = XmlWriter.Create(writer)) {
|
||||
if (xmlWriter != null) {
|
||||
xmlWriter.WriteStartDocument();
|
||||
xmlWriter.WriteStartElement("Tenants");
|
||||
xmlWriter.WriteEndElement();
|
||||
xmlWriter.WriteEndDocument();
|
||||
}
|
||||
using (var xmlWriter = XmlWriter.Create(writer)) {
|
||||
xmlWriter.WriteStartDocument();
|
||||
xmlWriter.WriteStartElement("Tenants");
|
||||
xmlWriter.WriteEndElement();
|
||||
xmlWriter.WriteEndDocument();
|
||||
}
|
||||
_appDataFolder.CreateFile(DescriptorCacheFileName, writer.ToString());
|
||||
_appDataFolder.CreateFile(DescriptorCacheFileName, writer.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -94,10 +94,10 @@ namespace Orchard.Environment {
|
||||
PropertyInfo = p,
|
||||
IndexParameters = p.GetIndexParameters(),
|
||||
Accessors = p.GetAccessors(false),
|
||||
PropertyEntry = properties.Where(t => t.Name == p.Name).FirstOrDefault()
|
||||
PropertyEntry = properties.FirstOrDefault(t => t.Name == p.Name)
|
||||
})
|
||||
.Where(x => x.PropertyEntry != null) // Must be present in "properties"
|
||||
.Where(x => x.IndexParameters.Count() == 0) // must not be an indexer
|
||||
.Where(x => !x.IndexParameters.Any()) // must not be an indexer
|
||||
.Where(x => x.Accessors.Length != 1 || x.Accessors[0].ReturnType == typeof(void)); //must have get/set, or only set
|
||||
|
||||
// Return an array of actions that assign the property value
|
||||
|
@@ -9,6 +9,7 @@ using System.Web.Mvc;
|
||||
using Autofac;
|
||||
using Autofac.Configuration;
|
||||
using Orchard.Caching;
|
||||
using Orchard.Data;
|
||||
using Orchard.Environment.AutofacUtil;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.Extensions;
|
||||
@@ -119,10 +120,10 @@ namespace Orchard.Environment {
|
||||
|
||||
builder.RegisterType<RunningShellTable>().As<IRunningShellTable>().SingleInstance();
|
||||
builder.RegisterType<DefaultOrchardShell>().As<IOrchardShell>().InstancePerMatchingLifetimeScope("shell");
|
||||
builder.RegisterType<SessionConfigurationCache>().As<ISessionConfigurationCache>().InstancePerMatchingLifetimeScope("shell");
|
||||
|
||||
registrations(builder);
|
||||
|
||||
|
||||
var autofacSection = ConfigurationManager.GetSection(ConfigurationSettingsReaderConstants.DefaultSectionName);
|
||||
if (autofacSection != null)
|
||||
builder.RegisterModule(new ConfigurationSettingsReader());
|
||||
@@ -135,7 +136,6 @@ namespace Orchard.Environment {
|
||||
if (File.Exists(optionalComponentsConfig))
|
||||
builder.RegisterModule(new HostComponentsConfigModule(optionalComponentsConfig));
|
||||
|
||||
|
||||
var container = builder.Build();
|
||||
|
||||
//
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Threading;
|
||||
using Orchard.FileSystems.AppData;
|
||||
using Orchard.Services;
|
||||
@@ -26,7 +27,7 @@ namespace Orchard.FileSystems.LockFile {
|
||||
return false;
|
||||
}
|
||||
|
||||
lockFile = new LockFile(_appDataFolder, path, _clock.UtcNow.ToString(), _rwLock);
|
||||
lockFile = new LockFile(_appDataFolder, path, _clock.UtcNow.ToString(CultureInfo.InvariantCulture), _rwLock);
|
||||
return true;
|
||||
}
|
||||
catch {
|
||||
|
Reference in New Issue
Block a user