mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Updated AutomaticDataMigrations to take advantage of the DistributedLockService.
This commit is contained in:
@@ -17,6 +17,7 @@ namespace Orchard.Tests.Stubs {
|
|||||||
|
|
||||||
public void Dispose() {
|
public void Dispose() {
|
||||||
IsDisposed = true;
|
IsDisposed = true;
|
||||||
|
IsAcquired = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ namespace Orchard.Tests.Tasks {
|
|||||||
private DistributedLockService _distributedLockService;
|
private DistributedLockService _distributedLockService;
|
||||||
|
|
||||||
protected override void Register(ContainerBuilder builder) {
|
protected override void Register(ContainerBuilder builder) {
|
||||||
|
builder.RegisterType<StubWorkContextAccessor>().As<IWorkContextAccessor>();
|
||||||
builder.RegisterType<StubMachineNameProvider>().As<IMachineNameProvider>();
|
builder.RegisterType<StubMachineNameProvider>().As<IMachineNameProvider>();
|
||||||
builder.RegisterType<StubDistributedLock>().As<IDistributedLock>();
|
builder.RegisterType<StubDistributedLock>().As<IDistributedLock>();
|
||||||
builder.RegisterType<DistributedLockService>().AsSelf();
|
builder.RegisterType<DistributedLockService>().AsSelf();
|
||||||
@@ -24,6 +25,7 @@ namespace Orchard.Tests.Tasks {
|
|||||||
_distributedLockService = container.Resolve<DistributedLockService>();
|
_distributedLockService = container.Resolve<DistributedLockService>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void AcquiringLockSucceeds() {
|
public void AcquiringLockSucceeds() {
|
||||||
IDistributedLock @lock;
|
IDistributedLock @lock;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ using Orchard.Mvc.ViewEngines.ThemeAwareness;
|
|||||||
using Orchard.Recipes.Services;
|
using Orchard.Recipes.Services;
|
||||||
using Orchard.Settings;
|
using Orchard.Settings;
|
||||||
using Orchard.Tasks;
|
using Orchard.Tasks;
|
||||||
|
using Orchard.Tasks.Locking;
|
||||||
using Orchard.Themes;
|
using Orchard.Themes;
|
||||||
using Orchard.UI.Notify;
|
using Orchard.UI.Notify;
|
||||||
using Orchard.UI.PageClass;
|
using Orchard.UI.PageClass;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Linq;
|
|||||||
using Orchard.Environment;
|
using Orchard.Environment;
|
||||||
using Orchard.Environment.Features;
|
using Orchard.Environment.Features;
|
||||||
using Orchard.Logging;
|
using Orchard.Logging;
|
||||||
|
using Orchard.Tasks.Locking;
|
||||||
|
|
||||||
namespace Orchard.Data.Migration {
|
namespace Orchard.Data.Migration {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -11,13 +12,16 @@ namespace Orchard.Data.Migration {
|
|||||||
public class AutomaticDataMigrations : IOrchardShellEvents {
|
public class AutomaticDataMigrations : IOrchardShellEvents {
|
||||||
private readonly IDataMigrationManager _dataMigrationManager;
|
private readonly IDataMigrationManager _dataMigrationManager;
|
||||||
private readonly IFeatureManager _featureManager;
|
private readonly IFeatureManager _featureManager;
|
||||||
|
private readonly IDistributedLockService _distributedLockService;
|
||||||
|
|
||||||
public AutomaticDataMigrations(
|
public AutomaticDataMigrations(
|
||||||
IDataMigrationManager dataMigrationManager,
|
IDataMigrationManager dataMigrationManager,
|
||||||
IFeatureManager featureManager
|
IFeatureManager featureManager,
|
||||||
) {
|
IDistributedLockService distributedLockService) {
|
||||||
|
|
||||||
_dataMigrationManager = dataMigrationManager;
|
_dataMigrationManager = dataMigrationManager;
|
||||||
_featureManager = featureManager;
|
_featureManager = featureManager;
|
||||||
|
_distributedLockService = distributedLockService;
|
||||||
|
|
||||||
Logger = NullLogger.Instance;
|
Logger = NullLogger.Instance;
|
||||||
}
|
}
|
||||||
@@ -25,24 +29,28 @@ namespace Orchard.Data.Migration {
|
|||||||
public ILogger Logger { get; set; }
|
public ILogger Logger { get; set; }
|
||||||
|
|
||||||
public void Activated() {
|
public void Activated() {
|
||||||
|
IDistributedLock @lock;
|
||||||
|
if (_distributedLockService.TryAcquireLock(GetType().FullName, TimeSpan.FromMinutes(30), TimeSpan.FromMilliseconds(250), out @lock)) {
|
||||||
|
using (@lock) {
|
||||||
|
// Let's make sure that the basic set of features is enabled. If there are any that are not enabled, then let's enable them first.
|
||||||
|
var theseFeaturesShouldAlwaysBeActive = new[] {
|
||||||
|
"Common", "Containers", "Contents", "Dashboard", "Feeds", "Navigation", "Scheduling", "Settings", "Shapes", "Title"
|
||||||
|
};
|
||||||
|
|
||||||
// Let's make sure that the basic set of features is enabled. If there are any that are not enabled, then let's enable them first.
|
var enabledFeatures = _featureManager.GetEnabledFeatures().Select(f => f.Id).ToList();
|
||||||
var theseFeaturesShouldAlwaysBeActive = new[] {
|
var featuresToEnable = theseFeaturesShouldAlwaysBeActive.Where(shouldBeActive => !enabledFeatures.Contains(shouldBeActive)).ToList();
|
||||||
"Common", "Containers", "Contents", "Dashboard", "Feeds", "Navigation", "Scheduling", "Settings", "Shapes", "Title"
|
if (featuresToEnable.Any()) {
|
||||||
};
|
_featureManager.EnableFeatures(featuresToEnable, true);
|
||||||
|
}
|
||||||
|
|
||||||
var enabledFeatures = _featureManager.GetEnabledFeatures().Select(f => f.Id).ToList();
|
foreach (var feature in _dataMigrationManager.GetFeaturesThatNeedUpdate()) {
|
||||||
var featuresToEnable = theseFeaturesShouldAlwaysBeActive.Where(shouldBeActive => !enabledFeatures.Contains(shouldBeActive)).ToList();
|
try {
|
||||||
if (featuresToEnable.Any()) {
|
_dataMigrationManager.Update(feature);
|
||||||
_featureManager.EnableFeatures(featuresToEnable, true);
|
}
|
||||||
}
|
catch (Exception e) {
|
||||||
|
Logger.Error("Could not run migrations automatically on " + feature, e);
|
||||||
foreach (var feature in _dataMigrationManager.GetFeaturesThatNeedUpdate()) {
|
}
|
||||||
try {
|
}
|
||||||
_dataMigrationManager.Update(feature);
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
Logger.Error("Could not run migrations automatically on " + feature, e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,31 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Orchard.Tasks.Locking {
|
namespace Orchard.Tasks.Locking {
|
||||||
|
|
||||||
public class DefaultLock : IDistributedLock {
|
public class DefaultLock : IDistributedLock {
|
||||||
|
private readonly IStaticLockSemaphore _semaphore;
|
||||||
|
|
||||||
|
public DefaultLock(IStaticLockSemaphore semaphore) {
|
||||||
|
_semaphore = semaphore;
|
||||||
|
}
|
||||||
|
|
||||||
public bool TryAcquire(string name, TimeSpan maxLifetime) {
|
public bool TryAcquire(string name, TimeSpan maxLifetime) {
|
||||||
return true;
|
if (_semaphore.IsAcquired)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return _semaphore.IsAcquired = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose() {
|
||||||
// Noop.
|
_semaphore.IsAcquired = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IStaticLockSemaphore : ISingletonDependency {
|
||||||
|
bool IsAcquired { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class StaticLockSemaphore : IStaticLockSemaphore {
|
||||||
|
public bool IsAcquired { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user