Preventing app to restart when a tenant is created

This commit is contained in:
Sebastien Ros
2013-11-18 21:17:22 -08:00
parent 889cbdc853
commit b751ef7216
2 changed files with 54 additions and 49 deletions

View File

@@ -1,7 +1,6 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using Orchard.Caching; using Orchard.Caching;
using Orchard.Environment.Configuration; using Orchard.Environment.Configuration;
using Orchard.Environment.Extensions; using Orchard.Environment.Extensions;
@@ -26,7 +25,9 @@ namespace Orchard.Environment {
private readonly static object _syncLock = new object(); private readonly static object _syncLock = new object();
private IEnumerable<ShellContext> _shellContexts; private IEnumerable<ShellContext> _shellContexts;
private IEnumerable<ShellSettings> _tenantsToRestart;
[ThreadStatic]
private static IList<ShellSettings> _tenantsToRestart;
public DefaultOrchardHost( public DefaultOrchardHost(
IShellSettingsManager shellSettingsManager, IShellSettingsManager shellSettingsManager,
@@ -45,7 +46,6 @@ namespace Orchard.Environment {
_extensionMonitoringCoordinator = extensionMonitoringCoordinator; _extensionMonitoringCoordinator = extensionMonitoringCoordinator;
_cacheManager = cacheManager; _cacheManager = cacheManager;
_hostLocalRestart = hostLocalRestart; _hostLocalRestart = hostLocalRestart;
_tenantsToRestart = Enumerable.Empty<ShellSettings>();
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
Logger = NullLogger.Instance; Logger = NullLogger.Instance;
@@ -109,13 +109,12 @@ namespace Orchard.Environment {
} }
void StartUpdatedShells() { void StartUpdatedShells() {
lock (_syncLock) { while (_tenantsToRestart != null && _tenantsToRestart.Any()) {
if (_tenantsToRestart.Any()) { var settings = _tenantsToRestart.First();
foreach (var settings in _tenantsToRestart.ToList()) { _tenantsToRestart.Remove(settings);
ActivateShell(settings); Logger.Debug("Updating shell: " + settings.Name);
} lock (_syncLock) {
ActivateShell(settings);
_tenantsToRestart = Enumerable.Empty<ShellSettings>();
} }
} }
} }
@@ -148,7 +147,7 @@ namespace Orchard.Environment {
} }
/// <summary> /// <summary>
/// Start a Shell and register its settings in RunningShellTable /// Starts a Shell and registers its settings in RunningShellTable
/// </summary> /// </summary>
private void ActivateShell(ShellContext context) { private void ActivateShell(ShellContext context) {
Logger.Debug("Activating context for tenant {0}", context.Settings.Name); Logger.Debug("Activating context for tenant {0}", context.Settings.Name);
@@ -161,13 +160,19 @@ namespace Orchard.Environment {
_runningShellTable.Add(context.Settings); _runningShellTable.Add(context.Settings);
} }
ShellContext CreateSetupContext() { /// <summary>
/// Creates a transient shell for the default tenant's setup
/// </summary>
private ShellContext CreateSetupContext() {
Logger.Debug("Creating shell context for root setup"); Logger.Debug("Creating shell context for root setup");
return _shellContextFactory.CreateSetupContext(new ShellSettings { Name = ShellSettings.DefaultName }); return _shellContextFactory.CreateSetupContext(new ShellSettings { Name = ShellSettings.DefaultName });
} }
ShellContext CreateShellContext(ShellSettings settings) { /// <summary>
/// Creates a shell context based on shell settings
/// </summary>
private ShellContext CreateShellContext(ShellSettings settings) {
if (settings.State == TenantState.Uninitialized) { if (settings.State == TenantState.Uninitialized) {
Logger.Debug("Creating shell context for tenant {0} setup", settings.Name); Logger.Debug("Creating shell context for tenant {0} setup", settings.Name);
return _shellContextFactory.CreateSetupContext(settings); return _shellContextFactory.CreateSetupContext(settings);
@@ -227,26 +232,30 @@ namespace Orchard.Environment {
// of the pipeline, as the request transaction has been closed, so creating a new // of the pipeline, as the request transaction has been closed, so creating a new
// environment and transaction for these tasks will behave as expected.) // environment and transaction for these tasks will behave as expected.)
while (_processingEngine.AreTasksPending()) { while (_processingEngine.AreTasksPending()) {
Logger.Debug("Processing pending task");
_processingEngine.ExecuteNextTask(); _processingEngine.ExecuteNextTask();
} }
StartUpdatedShells();
} }
/// <summary>
/// Register and activate a new Shell when a tenant is created
/// </summary>
void IShellSettingsManagerEventHandler.Saved(ShellSettings settings) { void IShellSettingsManagerEventHandler.Saved(ShellSettings settings) {
lock (_syncLock) { Logger.Debug("Shell saved: " + settings.Name);
// if a tenant has been created
if (settings.State != TenantState.Invalid) {
_tenantsToRestart = _tenantsToRestart ?? new List<ShellSettings>();
// if a tenant has been altered, and is not invalid, reload it if (!_tenantsToRestart.Any(t => t.Name.Equals(settings.Name))) {
if (settings.State != TenantState.Invalid) { Logger.Debug("Adding tenant to restart: " + settings.Name + " " + settings.State);
_tenantsToRestart = _tenantsToRestart _tenantsToRestart.Add(settings);
.Where(x => x.Name != settings.Name)
.Concat(new[] { settings });
} }
} }
} }
void ActivateShell(ShellSettings settings) { public void ActivateShell(ShellSettings settings) {
Logger.Debug("Activating shell: " + settings.Name);
// look for the associated shell context // look for the associated shell context
var shellContext = _shellContexts.FirstOrDefault(c => c.Settings.Name == settings.Name); var shellContext = _shellContexts.FirstOrDefault(c => c.Settings.Name == settings.Name);
@@ -276,32 +285,28 @@ namespace Orchard.Environment {
} }
/// <summary> /// <summary>
/// A feature is enabled/disabled /// A feature is enabled/disabled, the tenant needs to be restarted
/// </summary> /// </summary>
void IShellDescriptorManagerEventHandler.Changed(ShellDescriptor descriptor, string tenant) { void IShellDescriptorManagerEventHandler.Changed(ShellDescriptor descriptor, string tenant) {
lock (_syncLock) { if (_shellContexts == null) {
return;
if (_shellContexts == null) {
return;
}
var context =_shellContexts.FirstOrDefault(x => x.Settings.Name == tenant);
// some shells might need to be started, e.g. created by command line
if(context == null) {
StartUpdatedShells();
context = _shellContexts.First(x => x.Settings.Name == tenant);
}
// don't flag the tenant if already listed
if(_tenantsToRestart.Any(x => x.Name == tenant)) {
return;
}
_tenantsToRestart = _tenantsToRestart
.Concat(new[] { context.Settings })
.ToArray();
} }
Logger.Debug("Shell changed: " + tenant);
var context = _shellContexts.FirstOrDefault(x => x.Settings.Name == tenant);
if (context == null) {
return;
}
// don't flag the tenant if already listed
if (_tenantsToRestart.Any(x => x.Name == tenant)) {
return;
}
Logger.Debug("Adding tenant to restart: " + tenant);
_tenantsToRestart.Add(context.Settings);
} }
} }
} }

View File

@@ -34,11 +34,11 @@ namespace Orchard.Environment {
} }
void IShellSettingsManagerEventHandler.Saved(ShellSettings settings) { void IShellSettingsManagerEventHandler.Saved(ShellSettings settings) {
TouchFile(); //TouchFile();
} }
void IShellDescriptorManagerEventHandler.Changed(ShellDescriptor descriptor, string tenant) { void IShellDescriptorManagerEventHandler.Changed(ShellDescriptor descriptor, string tenant) {
TouchFile(); //TouchFile();
} }
private void TouchFile() { private void TouchFile() {