Added control over standalone environment creation without affecting shell state.

Setting the shell state to "Running" just to create the correct work context scope works, but in theory, requests could come in and be served from a "running" shell while the setup recipe is still being executed.
This commit is contained in:
Sipke Schoorstra
2015-09-10 22:45:29 +01:00
parent 91b0dd5369
commit 256b1313b2
6 changed files with 32 additions and 32 deletions

View File

@@ -164,10 +164,7 @@ namespace Orchard.Setup.Services {
// Creating a standalone environment.
// in theory this environment can be used to resolve any normal components by interface, and those
// components will exist entirely in isolation - no crossover between the safemode container currently in effect.
// Set shell state to "Running" so that the proper shell context is created.
shellSettings.State = TenantState.Running;
using (var environment = _orchardHost.CreateStandaloneEnvironment(shellSettings)) {
using (var environment = _orchardHost.CreateStandaloneEnvironment(shellSettings, StandaloneEnvironmentOptions.RunningEnvironment)) {
try {
executionId = CreateTenantData(context, environment);
}
@@ -176,9 +173,7 @@ namespace Orchard.Setup.Services {
throw;
}
}
// Reset shell state to "Initializing" so that subsequent HTTP requests are responded to with "Service Unavailable" while Orchard is setting up.
shellSettings.State = _shellSettings.State = TenantState.Initializing;
_shellSettingsManager.SaveSettings(shellSettings);
return executionId;

View File

@@ -184,13 +184,12 @@ namespace Orchard.Commands {
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
private IContainer CreateHostContainer() {
var hostContainer = OrchardStarter.CreateHostContainer(ContainerRegistrations);
var host = hostContainer.Resolve<IOrchardHost>();
host.Initialize();
return hostContainer;
}
private IWorkContextScope CreateStandaloneEnvironment(string tenant) {
var host = _hostContainer.Resolve<IOrchardHost>();
var tenantManager = _hostContainer.Resolve<IShellSettingsManager>();
@@ -207,13 +206,12 @@ namespace Orchard.Commands {
return env;
}
else {
// In case of an unitiliazed site (no default settings yet), we create a default settings instance.
// In case of an uninitialized site (no default settings yet), we create a default settings instance.
var settings = new ShellSettings { Name = ShellSettings.DefaultName, State = TenantState.Uninitialized };
return host.CreateStandaloneEnvironment(settings);
}
}
protected void ContainerRegistrations(ContainerBuilder builder) {
MvcSingletons(builder);
@@ -225,14 +223,14 @@ namespace Orchard.Commands {
private CommandHostShellContainerRegistrations CreateShellRegistrations() {
return new CommandHostShellContainerRegistrations {
Registrations = shellBuilder => {
shellBuilder.RegisterType<CommandHostVirtualPathMonitor>()
.As<IVirtualPathMonitor>()
.As<IVolatileProvider>()
.InstancePerMatchingLifetimeScope("shell");
shellBuilder.RegisterType<CommandBackgroundService>()
.As<IBackgroundService>()
.InstancePerLifetimeScope();
}
shellBuilder.RegisterType<CommandHostVirtualPathMonitor>()
.As<IVirtualPathMonitor>()
.As<IVolatileProvider>()
.InstancePerMatchingLifetimeScope("shell");
shellBuilder.RegisterType<CommandBackgroundService>()
.As<IBackgroundService>()
.InstancePerLifetimeScope();
}
};
}

View File

@@ -90,13 +90,13 @@ namespace Orchard.Environment {
EndRequest();
}
IWorkContextScope IOrchardHost.CreateStandaloneEnvironment(ShellSettings shellSettings) {
IWorkContextScope IOrchardHost.CreateStandaloneEnvironment(ShellSettings shellSettings, StandaloneEnvironmentOptions options) {
Logger.Debug("Creating standalone environment for tenant {0}", shellSettings.Name);
MonitorExtensions();
BuildCurrent();
var shellContext = CreateShellContext(shellSettings);
var shellContext = CreateShellContext(shellSettings, options);
var workContext = shellContext.LifetimeScope.CreateWorkContextScope();
return new StandaloneEnvironmentWorkContextScopeWrapper(workContext, shellContext);
}
@@ -141,7 +141,7 @@ namespace Orchard.Environment {
if (allSettings.Any()) {
Parallel.ForEach(allSettings, settings => {
try {
var context = CreateShellContext(settings);
var context = CreateShellContext(settings, StandaloneEnvironmentOptions.None);
ActivateShell(context);
}
catch (Exception e) {
@@ -190,15 +190,14 @@ namespace Orchard.Environment {
/// <summary>
/// Creates a shell context based on shell settings.
/// </summary>
private ShellContext CreateShellContext(ShellSettings settings) {
switch (settings.State) {
case TenantState.Uninitialized:
Logger.Debug("Creating shell context for tenant {0} setup.", settings.Name);
return _shellContextFactory.CreateSetupContext(settings);
default:
Logger.Debug("Creating shell context for tenant {0}.", settings.Name);
return _shellContextFactory.CreateShellContext(settings);
private ShellContext CreateShellContext(ShellSettings settings, StandaloneEnvironmentOptions options) {
if (settings.State != TenantState.Uninitialized || options.Running) {
Logger.Debug("Creating shell context for tenant {0}.", settings.Name);
return _shellContextFactory.CreateShellContext(settings);
}
Logger.Debug("Creating shell context for tenant {0} setup.", settings.Name);
return _shellContextFactory.CreateSetupContext(settings);
}
private void SetupExtensions() {
@@ -285,7 +284,7 @@ namespace Orchard.Environment {
// is this is a new tenant ? or is it a tenant waiting for setup ?
if (shellContext == null || settings.State == TenantState.Uninitialized) {
// create the Shell
var context = CreateShellContext(settings);
var context = CreateShellContext(settings, StandaloneEnvironmentOptions.None);
// activate the Shell
ActivateShell(context);

View File

@@ -31,6 +31,6 @@ namespace Orchard.Environment {
/// Can be used to build an temporary self-contained instance of a shell's configured code.
/// Services may be resolved from within this instance to configure and initialize its storage.
/// </summary>
IWorkContextScope CreateStandaloneEnvironment(ShellSettings shellSettings);
IWorkContextScope CreateStandaloneEnvironment(ShellSettings shellSettings, StandaloneEnvironmentOptions options = null);
}
}

View File

@@ -0,0 +1,7 @@
namespace Orchard.Environment {
public class StandaloneEnvironmentOptions {
public static readonly StandaloneEnvironmentOptions None = new StandaloneEnvironmentOptions();
public static readonly StandaloneEnvironmentOptions RunningEnvironment = new StandaloneEnvironmentOptions {Running = true};
public bool Running { get; set; }
}
}

View File

@@ -155,6 +155,7 @@
<Compile Include="Data\Migration\Schema\DropUniqueConstraintCommand.cs" />
<Compile Include="Environment\Extensions\Models\LifecycleStatus.cs" />
<Compile Include="Environment\ShellBuilders\ICompositionStrategy.cs" />
<Compile Include="Environment\StandaloneEnvironmentOptions.cs" />
<Compile Include="IBackgroundHttpContextFactory.cs" />
<Compile Include="Mvc\Updater.cs" />
<Compile Include="Recipes\Models\ConfigurationContext.cs" />