mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Feature list not refreshed when adding a new module
Update cache manager to rely on a thread static variable to keep track of nested calls to ICacheManager.Get(). This fixes this particular bug of IExtensionManager caching the list of available features: instead of storing the result of the computation in a field (which is incorrect), use the cache manager. Work Items: 16867 --HG-- branch : dev
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace Orchard.Caching {
|
||||
public class AcquireContext<TKey> {
|
||||
public interface IAcquireContext {
|
||||
Action<IVolatileToken> Monitor { get; }
|
||||
}
|
||||
|
||||
public class AcquireContext<TKey> : IAcquireContext {
|
||||
public AcquireContext(TKey key, Action<IVolatileToken> monitor) {
|
||||
Key = key;
|
||||
Monitor = monitor;
|
||||
|
@@ -17,13 +17,33 @@ namespace Orchard.Caching {
|
||||
k => CreateEntry(k, acquire),
|
||||
// "Update" lamdba
|
||||
(k, currentEntry) => (currentEntry.Tokens.All(t => t.IsCurrent) ? currentEntry : CreateEntry(k, acquire)));
|
||||
|
||||
// Bubble up volatile tokens to parent context
|
||||
if (CacheAquireContext.ThreadInstance != null) {
|
||||
foreach (var token in entry.Tokens)
|
||||
CacheAquireContext.ThreadInstance.Monitor(token);
|
||||
}
|
||||
|
||||
return entry.Result;
|
||||
}
|
||||
|
||||
|
||||
private static CacheEntry CreateEntry(TKey k, Func<AcquireContext<TKey>, TResult> acquire) {
|
||||
var entry = new CacheEntry { Tokens = new List<IVolatileToken>() };
|
||||
var context = new AcquireContext<TKey>(k, volatileItem => entry.Tokens.Add(volatileItem));
|
||||
entry.Result = acquire(context);
|
||||
|
||||
IAcquireContext parentContext = null;
|
||||
try {
|
||||
// Push context
|
||||
parentContext = CacheAquireContext.ThreadInstance;
|
||||
CacheAquireContext.ThreadInstance = context;
|
||||
|
||||
entry.Result = acquire(context);
|
||||
}
|
||||
finally {
|
||||
// Pop context
|
||||
CacheAquireContext.ThreadInstance = parentContext;
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
@@ -32,4 +52,12 @@ namespace Orchard.Caching {
|
||||
public IList<IVolatileToken> Tokens { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Keep track of nested caches contexts on a given thread
|
||||
/// </summary>
|
||||
internal static class CacheAquireContext {
|
||||
[ThreadStatic]
|
||||
public static IAcquireContext ThreadInstance;
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using Orchard.Caching;
|
||||
using Orchard.Environment.Extensions.Folders;
|
||||
using Orchard.Environment.Extensions.Loaders;
|
||||
@@ -16,7 +15,6 @@ namespace Orchard.Environment.Extensions {
|
||||
private readonly IEnumerable<IExtensionFolders> _folders;
|
||||
private readonly ICacheManager _cacheManager;
|
||||
private readonly IEnumerable<IExtensionLoader> _loaders;
|
||||
private IEnumerable<FeatureDescriptor> _featureDescriptors;
|
||||
|
||||
public Localizer T { get; set; }
|
||||
public ILogger Logger { get; set; }
|
||||
@@ -40,11 +38,8 @@ namespace Orchard.Environment.Extensions {
|
||||
}
|
||||
|
||||
public IEnumerable<FeatureDescriptor> AvailableFeatures() {
|
||||
if (_featureDescriptors == null || _featureDescriptors.Count() == 0) {
|
||||
_featureDescriptors = AvailableExtensions().SelectMany(ext => ext.Features).OrderByDependencies(HasDependency).ToReadOnlyCollection();
|
||||
return _featureDescriptors;
|
||||
}
|
||||
return _featureDescriptors;
|
||||
return _cacheManager.Get("...", ctx =>
|
||||
AvailableExtensions().SelectMany(ext => ext.Features).OrderByDependencies(HasDependency).ToReadOnlyCollection());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -47,7 +47,6 @@ namespace Orchard.Environment.Extensions.Folders {
|
||||
foreach (var subfolderPath in subfolderPaths) {
|
||||
var extensionId = Path.GetFileName(subfolderPath.TrimEnd('/', '\\'));
|
||||
var manifestPath = Path.Combine(subfolderPath, _manifestName);
|
||||
ctx.Monitor(_webSiteFolder.WhenPathChanges(manifestPath));
|
||||
try {
|
||||
var descriptor = GetExtensionDescriptor(path, extensionId, manifestPath);
|
||||
if (descriptor != null)
|
||||
|
@@ -89,6 +89,10 @@ namespace Orchard.FileSystems.VirtualPath {
|
||||
}
|
||||
public bool IsCurrent { get; set; }
|
||||
public string VirtualPath { get; private set; }
|
||||
|
||||
public override string ToString() {
|
||||
return string.Format("IsCurrent: {0}, VirtualPath: \"{1}\"", IsCurrent, VirtualPath);
|
||||
}
|
||||
}
|
||||
|
||||
class Thunk {
|
||||
|
Reference in New Issue
Block a user