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.Linq;
using System.Collections.Generic;
using Orchard.Caching;
using Orchard.Environment.Configuration;
using Orchard.Environment.Extensions;
@@ -26,7 +25,9 @@ namespace Orchard.Environment {
private readonly static object _syncLock = new object();
private IEnumerable<ShellContext> _shellContexts;
private IEnumerable<ShellSettings> _tenantsToRestart;
[ThreadStatic]
private static IList<ShellSettings> _tenantsToRestart;
public DefaultOrchardHost(
IShellSettingsManager shellSettingsManager,
@@ -45,7 +46,6 @@ namespace Orchard.Environment {
_extensionMonitoringCoordinator = extensionMonitoringCoordinator;
_cacheManager = cacheManager;
_hostLocalRestart = hostLocalRestart;
_tenantsToRestart = Enumerable.Empty<ShellSettings>();
T = NullLocalizer.Instance;
Logger = NullLogger.Instance;
@@ -109,13 +109,12 @@ namespace Orchard.Environment {
}
void StartUpdatedShells() {
lock (_syncLock) {
if (_tenantsToRestart.Any()) {
foreach (var settings in _tenantsToRestart.ToList()) {
ActivateShell(settings);
}
_tenantsToRestart = Enumerable.Empty<ShellSettings>();
while (_tenantsToRestart != null && _tenantsToRestart.Any()) {
var settings = _tenantsToRestart.First();
_tenantsToRestart.Remove(settings);
Logger.Debug("Updating shell: " + settings.Name);
lock (_syncLock) {
ActivateShell(settings);
}
}
}
@@ -148,7 +147,7 @@ namespace Orchard.Environment {
}
/// <summary>
/// Start a Shell and register its settings in RunningShellTable
/// Starts a Shell and registers its settings in RunningShellTable
/// </summary>
private void ActivateShell(ShellContext context) {
Logger.Debug("Activating context for tenant {0}", context.Settings.Name);
@@ -161,13 +160,19 @@ namespace Orchard.Environment {
_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");
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) {
Logger.Debug("Creating shell context for tenant {0} setup", settings.Name);
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
// environment and transaction for these tasks will behave as expected.)
while (_processingEngine.AreTasksPending()) {
Logger.Debug("Processing pending task");
_processingEngine.ExecuteNextTask();
}
StartUpdatedShells();
}
/// <summary>
/// Register and activate a new Shell when a tenant is created
/// </summary>
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 (settings.State != TenantState.Invalid) {
_tenantsToRestart = _tenantsToRestart
.Where(x => x.Name != settings.Name)
.Concat(new[] { settings });
if (!_tenantsToRestart.Any(t => t.Name.Equals(settings.Name))) {
Logger.Debug("Adding tenant to restart: " + settings.Name + " " + settings.State);
_tenantsToRestart.Add(settings);
}
}
}
void ActivateShell(ShellSettings settings) {
public void ActivateShell(ShellSettings settings) {
Logger.Debug("Activating shell: " + settings.Name);
// look for the associated shell context
var shellContext = _shellContexts.FirstOrDefault(c => c.Settings.Name == settings.Name);
@@ -276,32 +285,28 @@ namespace Orchard.Environment {
}
/// <summary>
/// A feature is enabled/disabled
/// A feature is enabled/disabled, the tenant needs to be restarted
/// </summary>
void IShellDescriptorManagerEventHandler.Changed(ShellDescriptor descriptor, string tenant) {
lock (_syncLock) {
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();
if (_shellContexts == null) {
return;
}
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) {
TouchFile();
//TouchFile();
}
void IShellDescriptorManagerEventHandler.Changed(ShellDescriptor descriptor, string tenant) {
TouchFile();
//TouchFile();
}
private void TouchFile() {