mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Fixing feature enabling and adding ContextState
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using Orchard.Caching;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Environment.Extensions;
|
||||
@@ -13,6 +14,7 @@ using Orchard.Logging;
|
||||
using Orchard.Utility.Extensions;
|
||||
|
||||
namespace Orchard.Environment {
|
||||
// All the event handlers that DefaultOrchardHost implements have to be declared in OrchardStarter
|
||||
public class DefaultOrchardHost : IOrchardHost, IShellSettingsManagerEventHandler, IShellDescriptorManagerEventHandler {
|
||||
private readonly IHostLocalRestart _hostLocalRestart;
|
||||
private readonly IShellSettingsManager _shellSettingsManager;
|
||||
@@ -25,10 +27,8 @@ namespace Orchard.Environment {
|
||||
private readonly static object _syncLock = new object();
|
||||
|
||||
private IEnumerable<ShellContext> _shellContexts;
|
||||
|
||||
[ThreadStatic]
|
||||
private static IList<ShellSettings> _tenantsToRestart;
|
||||
|
||||
private readonly ContextState<IList<ShellSettings>> _tenantsToRestart;
|
||||
public DefaultOrchardHost(
|
||||
IShellSettingsManager shellSettingsManager,
|
||||
IShellContextFactory shellContextFactory,
|
||||
@@ -47,6 +47,8 @@ namespace Orchard.Environment {
|
||||
_cacheManager = cacheManager;
|
||||
_hostLocalRestart = hostLocalRestart;
|
||||
|
||||
_tenantsToRestart = new ContextState<IList<ShellSettings>>("DefaultOrchardHost.TenantsToRestart", () => new List<ShellSettings>());
|
||||
|
||||
T = NullLocalizer.Instance;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
@@ -109,9 +111,9 @@ namespace Orchard.Environment {
|
||||
}
|
||||
|
||||
void StartUpdatedShells() {
|
||||
while (_tenantsToRestart != null && _tenantsToRestart.Any()) {
|
||||
var settings = _tenantsToRestart.First();
|
||||
_tenantsToRestart.Remove(settings);
|
||||
while (_tenantsToRestart.GetState().Any()) {
|
||||
var settings = _tenantsToRestart.GetState().First();
|
||||
_tenantsToRestart.GetState().Remove(settings);
|
||||
Logger.Debug("Updating shell: " + settings.Name);
|
||||
lock (_syncLock) {
|
||||
ActivateShell(settings);
|
||||
@@ -244,11 +246,9 @@ namespace Orchard.Environment {
|
||||
|
||||
// if a tenant has been created
|
||||
if (settings.State != TenantState.Invalid) {
|
||||
_tenantsToRestart = _tenantsToRestart ?? new List<ShellSettings>();
|
||||
|
||||
if (!_tenantsToRestart.Any(t => t.Name.Equals(settings.Name))) {
|
||||
if (!_tenantsToRestart.GetState().Any(t => t.Name.Equals(settings.Name))) {
|
||||
Logger.Debug("Adding tenant to restart: " + settings.Name + " " + settings.State);
|
||||
_tenantsToRestart.Add(settings);
|
||||
_tenantsToRestart.GetState().Add(settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -291,7 +291,7 @@ namespace Orchard.Environment {
|
||||
if (_shellContexts == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Logger.Debug("Shell changed: " + tenant);
|
||||
|
||||
var context = _shellContexts.FirstOrDefault(x => x.Settings.Name == tenant);
|
||||
@@ -300,13 +300,18 @@ namespace Orchard.Environment {
|
||||
return;
|
||||
}
|
||||
|
||||
// don't restart when tenant is in setup
|
||||
if (context.Settings.State != TenantState.Running) {
|
||||
return;
|
||||
}
|
||||
|
||||
// don't flag the tenant if already listed
|
||||
if (_tenantsToRestart.Any(x => x.Name == tenant)) {
|
||||
if (_tenantsToRestart.GetState().Any(x => x.Name == tenant)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Logger.Debug("Adding tenant to restart: " + tenant);
|
||||
_tenantsToRestart.Add(context.Settings);
|
||||
_tenantsToRestart.GetState().Add(context.Settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -77,7 +77,10 @@ namespace Orchard.Environment {
|
||||
RegisterVolatileProvider<DefaultVirtualPathProvider, IVirtualPathProvider>(builder);
|
||||
|
||||
|
||||
builder.RegisterType<DefaultOrchardHost>().As<IOrchardHost>().As<IEventHandler>().Named<IEventHandler>(typeof(IShellSettingsManagerEventHandler).Name).SingleInstance();
|
||||
builder.RegisterType<DefaultOrchardHost>().As<IOrchardHost>().As<IEventHandler>()
|
||||
.Named<IEventHandler>(typeof(IShellSettingsManagerEventHandler).Name)
|
||||
.Named<IEventHandler>(typeof(IShellDescriptorManagerEventHandler).Name)
|
||||
.SingleInstance();
|
||||
{
|
||||
builder.RegisterType<ShellSettingsManager>().As<IShellSettingsManager>().SingleInstance();
|
||||
|
||||
|
56
src/Orchard/Environment/State/ContextState.cs
Normal file
56
src/Orchard/Environment/State/ContextState.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
using System.Web;
|
||||
|
||||
namespace Orchard.Environment.State {
|
||||
|
||||
/// <summary>
|
||||
/// Holds some state for the current HttpContext or thread
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data to store</typeparam>
|
||||
public class ContextState<T> where T : class {
|
||||
private readonly string _name;
|
||||
private readonly Func<T> _defaultValue;
|
||||
|
||||
public ContextState(string name) {
|
||||
_name = name;
|
||||
}
|
||||
|
||||
public ContextState(string name, Func<T> defaultValue) {
|
||||
_name = name;
|
||||
_defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public T GetState() {
|
||||
if (HttpContext.Current == null) {
|
||||
var data = CallContext.GetData(_name);
|
||||
|
||||
if (data == null) {
|
||||
if (_defaultValue != null) {
|
||||
CallContext.SetData(_name, data = _defaultValue());
|
||||
return data as T;
|
||||
}
|
||||
}
|
||||
|
||||
return data as T;
|
||||
}
|
||||
|
||||
if (HttpContext.Current.Items[_name] == null) {
|
||||
HttpContext.Current.Items[_name] = _defaultValue == null ? null : _defaultValue();
|
||||
}
|
||||
|
||||
return HttpContext.Current.Items[_name] as T;
|
||||
|
||||
}
|
||||
|
||||
public void SetState(T state) {
|
||||
if (HttpContext.Current == null) {
|
||||
CallContext.SetData(_name, state);
|
||||
}
|
||||
else {
|
||||
HttpContext.Current.Items[_name] = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -13,15 +13,16 @@ namespace Orchard.Environment.State {
|
||||
private readonly IShellContextFactory _shellContextFactory;
|
||||
private readonly Func<IOrchardHost> _orchardHost;
|
||||
|
||||
[ThreadStatic] private static IList<Entry> _entries;
|
||||
|
||||
private readonly ContextState<IList<Entry>> _entries;
|
||||
|
||||
public DefaultProcessingEngine(IShellContextFactory shellContextFactory, Func<IOrchardHost> orchardHost) {
|
||||
_shellContextFactory = shellContextFactory;
|
||||
_orchardHost = orchardHost;
|
||||
|
||||
_entries = new ContextState<IList<Entry>>("DefaultProcessingEngine.Entries", () => new List<Entry>());
|
||||
}
|
||||
|
||||
public string AddTask(ShellSettings shellSettings, ShellDescriptor shellDescriptor, string eventName, Dictionary<string, object> parameters) {
|
||||
EnsureEntries();
|
||||
|
||||
var entry = new Entry {
|
||||
ShellSettings = shellSettings,
|
||||
@@ -35,7 +36,7 @@ namespace Orchard.Environment.State {
|
||||
eventName,
|
||||
entry.ProcessId,
|
||||
shellSettings.Name);
|
||||
_entries.Add(entry);
|
||||
_entries.GetState().Add(entry);
|
||||
return entry.ProcessId;
|
||||
}
|
||||
|
||||
@@ -52,28 +53,19 @@ namespace Orchard.Environment.State {
|
||||
|
||||
|
||||
public bool AreTasksPending() {
|
||||
return EnsureEntries().Any();
|
||||
return _entries.GetState().Any();
|
||||
}
|
||||
|
||||
public void ExecuteNextTask() {
|
||||
EnsureEntries();
|
||||
|
||||
Entry entry;
|
||||
if (!_entries.Any())
|
||||
if (!_entries.GetState().Any())
|
||||
return;
|
||||
entry = _entries.First();
|
||||
_entries.Remove(entry);
|
||||
entry = _entries.GetState().First();
|
||||
_entries.GetState().Remove(entry);
|
||||
Execute(entry);
|
||||
}
|
||||
|
||||
private IList<Entry> EnsureEntries() {
|
||||
if (_entries == null) {
|
||||
_entries = new List<Entry>();
|
||||
}
|
||||
|
||||
return _entries;
|
||||
}
|
||||
|
||||
private void Execute(Entry entry) {
|
||||
// Force reloading extensions if there were extensions installed
|
||||
// See http://orchard.codeplex.com/workitem/17465
|
||||
|
@@ -238,6 +238,7 @@
|
||||
<Compile Include="Environment\Extensions\ICriticalErrorProvider.cs" />
|
||||
<Compile Include="Environment\IOrchardFrameworkAssemblies.cs" />
|
||||
<Compile Include="Environment\IWorkContextEvents.cs" />
|
||||
<Compile Include="Environment\State\ContextState.cs" />
|
||||
<Compile Include="Environment\ViewsBackgroundCompilation.cs" />
|
||||
<Compile Include="Environment\Warmup\WarmupUtility.cs" />
|
||||
<Compile Include="Environment\WorkContextImplementation.cs" />
|
||||
|
Reference in New Issue
Block a user