diff --git a/src/Orchard.Web/Modules/Orchard.Workflows/Models/WorkflowDefinitionRecord.cs b/src/Orchard.Web/Modules/Orchard.Workflows/Models/WorkflowDefinitionRecord.cs
index ab585ca4d..ebb7ec26d 100644
--- a/src/Orchard.Web/Modules/Orchard.Workflows/Models/WorkflowDefinitionRecord.cs
+++ b/src/Orchard.Web/Modules/Orchard.Workflows/Models/WorkflowDefinitionRecord.cs
@@ -43,7 +43,7 @@ namespace Orchard.Workflows.Models {
///
/// List of associated with this workflow definition.
///
- [CascadeAllDeleteOrphan, Aggregate]
+ [CascadeAllDeleteOrphan]
public virtual IList WorkflowRecords { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Orchard/Environment/DefaultOrchardHost.cs b/src/Orchard/Environment/DefaultOrchardHost.cs
index ceafd25af..f7587a841 100644
--- a/src/Orchard/Environment/DefaultOrchardHost.cs
+++ b/src/Orchard/Environment/DefaultOrchardHost.cs
@@ -11,7 +11,6 @@ using Orchard.Environment.Descriptor;
using Orchard.Environment.Descriptor.Models;
using Orchard.Localization;
using Orchard.Logging;
-using Orchard.Utility.Extensions;
namespace Orchard.Environment {
public class DefaultOrchardHost : IOrchardHost, IShellSettingsManagerEventHandler, IShellDescriptorManagerEventHandler {
@@ -23,7 +22,7 @@ namespace Orchard.Environment {
private readonly IExtensionLoaderCoordinator _extensionLoaderCoordinator;
private readonly IExtensionMonitoringCoordinator _extensionMonitoringCoordinator;
private readonly ICacheManager _cacheManager;
- private readonly object _syncLock = new object();
+ private readonly static object _syncLock = new object();
private IEnumerable _shellContexts;
private IEnumerable _tenantsToRestart;
@@ -54,13 +53,8 @@ namespace Orchard.Environment {
public Localizer T { get; set; }
public ILogger Logger { get; set; }
- public IList Current {
- get { return BuildCurrent().ToReadOnlyCollection(); }
- }
-
public ShellContext GetShellContext(ShellSettings shellSettings) {
- return Current
- .Single(shellContext => shellContext.Settings.Name.Equals(shellSettings.Name));
+ return BuildCurrent().SingleOrDefault(shellContext => shellContext.Settings.Name.Equals(shellSettings.Name));
}
void IOrchardHost.Initialize() {
@@ -112,7 +106,7 @@ namespace Orchard.Environment {
void StartUpdatedShells() {
lock (_syncLock) {
if (_tenantsToRestart.Any()) {
- foreach (var settings in _tenantsToRestart.Distinct().ToList()) {
+ foreach (var settings in _tenantsToRestart.ToList()) {
ActivateShell(settings);
}
@@ -155,7 +149,11 @@ namespace Orchard.Environment {
Logger.Debug("Activating context for tenant {0}", context.Settings.Name);
context.Shell.Activate();
- _shellContexts = (_shellContexts ?? Enumerable.Empty()).Union(new [] {context});
+ _shellContexts = (_shellContexts ?? Enumerable.Empty())
+ .Where(c => c.Settings.Name != context.Settings.Name)
+ .Concat(new[] { context })
+ .ToArray();
+
_runningShellTable.Add(context.Settings);
}
@@ -199,9 +197,13 @@ namespace Orchard.Environment {
Logger.Information("Disposing active shell contexts");
if (_shellContexts != null) {
- foreach (var shellContext in _shellContexts) {
- shellContext.Shell.Terminate();
- shellContext.LifetimeScope.Dispose();
+ lock (_syncLock) {
+ if (_shellContexts != null) {
+ foreach (var shellContext in _shellContexts) {
+ shellContext.Shell.Terminate();
+ shellContext.LifetimeScope.Dispose();
+ }
+ }
}
_shellContexts = null;
}
@@ -232,7 +234,9 @@ namespace Orchard.Environment {
// 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).Union(new[] { settings });
+ _tenantsToRestart = _tenantsToRestart
+ .Where(x => x.Name != settings.Name)
+ .Concat(new[] { settings });
}
}
}
@@ -284,12 +288,14 @@ namespace Orchard.Environment {
context = _shellContexts.First(x => x.Settings.Name == tenant);
}
- // don't update the settings themselves here
+ // don't flag the tenant if already listed
if(_tenantsToRestart.Any(x => x.Name == tenant)) {
return;
}
- _tenantsToRestart = _tenantsToRestart.Union(new[] { context.Settings });
+ _tenantsToRestart = _tenantsToRestart
+ .Concat(new[] { context.Settings })
+ .ToArray();
}
}
}
diff --git a/src/Orchard/Environment/RunningShellTable.cs b/src/Orchard/Environment/RunningShellTable.cs
index c0700a392..7713543a4 100644
--- a/src/Orchard/Environment/RunningShellTable.cs
+++ b/src/Orchard/Environment/RunningShellTable.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading;
using System.Web;
using Orchard.Environment.Configuration;
@@ -17,34 +18,53 @@ namespace Orchard.Environment {
private IEnumerable _shells = Enumerable.Empty();
private IEnumerable> _shellsByHost = Enumerable.Empty().GroupBy(x => default(string));
private ShellSettings _fallback;
+ private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
public void Add(ShellSettings settings) {
- _shells = _shells
- .Where(s => s.Name != settings.Name)
- .Concat(new[] { settings })
- .ToArray();
+ _lock.EnterWriteLock();
+ try {
+ _shells = _shells
+ .Where(s => s.Name != settings.Name)
+ .Concat(new[] {settings})
+ .ToArray();
- Organize();
+ Organize();
+ }
+ finally {
+ _lock.ExitWriteLock();
+ }
}
public void Remove(ShellSettings settings) {
- _shells = _shells
- .Where(s => s.Name != settings.Name)
- .ToArray();
+ _lock.EnterWriteLock();
+ try {
+ _shells = _shells
+ .Where(s => s.Name != settings.Name)
+ .ToArray();
- Organize();
+ Organize();
+ }
+ finally {
+ _lock.ExitWriteLock();
+ }
}
public void Update(ShellSettings settings) {
- _shells = _shells
- .Where(s => s.Name != settings.Name)
- .ToArray();
+ _lock.EnterWriteLock();
+ try {
+ _shells = _shells
+ .Where(s => s.Name != settings.Name)
+ .ToArray();
- _shells = _shells
- .Concat(new[] { settings })
- .ToArray();
+ _shells = _shells
+ .Concat(new[] {settings})
+ .ToArray();
- Organize();
+ Organize();
+ }
+ finally {
+ _lock.ExitWriteLock();
+ }
}
private void Organize() {
@@ -86,19 +106,21 @@ namespace Orchard.Environment {
}
public ShellSettings Match(string host, string appRelativePath) {
- // optimized path when only one tenant (Default)
- if (!_shellsByHost.Any()) {
- return _fallback;
- }
+ _lock.EnterReadLock();
+ try {
+ // optimized path when only one tenant (Default), configured with no custom host
+ if (!_shellsByHost.Any() && _fallback != null) {
+ return _fallback;
+ }
- var hostLength = host.IndexOf(':');
- if (hostLength != -1)
- host = host.Substring(0, hostLength);
+ var hostLength = host.IndexOf(':');
+ if (hostLength != -1)
+ host = host.Substring(0, hostLength);
- var mostQualifiedMatch = _shellsByHost
- .Where(group => host.EndsWith(group.Key, StringComparison.OrdinalIgnoreCase))
- .SelectMany(group => group
- .OrderByDescending(settings => (settings.RequestUrlPrefix ?? string.Empty).Length))
+ var mostQualifiedMatch = _shellsByHost
+ .Where(group => host.EndsWith(group.Key, StringComparison.OrdinalIgnoreCase))
+ .SelectMany(group => group
+ .OrderByDescending(settings => (settings.RequestUrlPrefix ?? string.Empty).Length))
.FirstOrDefault(settings => {
if (settings.State == TenantState.Disabled) {
return false;
@@ -112,7 +134,11 @@ namespace Orchard.Environment {
|| appRelativePath.Equals("~/" + settings.RequestUrlPrefix, StringComparison.OrdinalIgnoreCase);
});
- return mostQualifiedMatch ?? _fallback;
+ return mostQualifiedMatch ?? _fallback;
+ }
+ finally {
+ _lock.ExitReadLock();
+ }
}
}
}