diff --git a/src/Orchard.Tests/DatabaseEnabledTestsBase.cs b/src/Orchard.Tests/DatabaseEnabledTestsBase.cs index e2f1fda3c..51e467618 100644 --- a/src/Orchard.Tests/DatabaseEnabledTestsBase.cs +++ b/src/Orchard.Tests/DatabaseEnabledTestsBase.cs @@ -24,7 +24,7 @@ namespace Orchard.Tests { protected string _databaseFilePath; protected ISessionFactory _sessionFactory; protected StubClock _clock; - + protected ShellSettings _shellSettings; [TestFixtureSetUp] public void InitFixture() { @@ -48,7 +48,7 @@ namespace Orchard.Tests { builder.RegisterInstance(new StubLocator(_session)).As(); builder.RegisterInstance(_clock).As(); builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>)).InstancePerLifetimeScope(); - builder.RegisterInstance(new ShellSettings { Name = ShellSettings.DefaultName, DataProvider = "SqlCe" }); + builder.RegisterInstance(_shellSettings = new ShellSettings { Name = ShellSettings.DefaultName, DataProvider = "SqlCe" }); builder.RegisterType().As().InstancePerLifetimeScope(); builder.Register(context => _sessionFactory.OpenSession()).As().InstancePerLifetimeScope(); diff --git a/src/Orchard.Tests/Orchard.Framework.Tests.csproj b/src/Orchard.Tests/Orchard.Framework.Tests.csproj index 5dd02f1f0..eb80350bd 100644 --- a/src/Orchard.Tests/Orchard.Framework.Tests.csproj +++ b/src/Orchard.Tests/Orchard.Framework.Tests.csproj @@ -272,7 +272,6 @@ - diff --git a/src/Orchard.Tests/Stubs/StubThreadProvider.cs b/src/Orchard.Tests/Stubs/StubThreadProvider.cs deleted file mode 100644 index 73d6ebcaf..000000000 --- a/src/Orchard.Tests/Stubs/StubThreadProvider.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Orchard.Environment; - -namespace Orchard.Tests.Stubs { - public class StubThreadProvider : IThreadProvider { - public StubThreadProvider() { - ManagedThreadId = 1; - } - - public int ManagedThreadId { get; set; } - - public int GetCurrentThreadId() { - return ManagedThreadId; - } - } -} diff --git a/src/Orchard.Tests/Tasks/DistributedLockServiceTests.cs b/src/Orchard.Tests/Tasks/DistributedLockServiceTests.cs index 5b0074c27..71efdc6d2 100644 --- a/src/Orchard.Tests/Tasks/DistributedLockServiceTests.cs +++ b/src/Orchard.Tests/Tasks/DistributedLockServiceTests.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Autofac; using NUnit.Framework; using Orchard.Data; using Orchard.Environment; +using Orchard.Environment.Configuration; using Orchard.Services; using Orchard.Tasks.Locking.Records; using Orchard.Tasks.Locking.Services; @@ -16,10 +18,8 @@ namespace Orchard.Tests.Tasks { private const string LockName = "Orchard Test Lock"; private DistributedLockService _distributedLockService; private StubMachineNameProvider _machineNameProvider; - private StubThreadProvider _threadProvider; private IRepository _distributedLockRepository; private ITransactionManager _transactionManager; - protected override IEnumerable DatabaseTypes { get { yield return typeof(DistributedLockRecord); } @@ -28,7 +28,6 @@ namespace Orchard.Tests.Tasks { public override void Register(ContainerBuilder builder) { builder.RegisterType().As(); builder.RegisterType().As().SingleInstance(); - builder.RegisterType().As().SingleInstance(); builder.RegisterType().AsSelf(); } @@ -36,74 +35,64 @@ namespace Orchard.Tests.Tasks { base.Init(); _distributedLockService = _container.Resolve(); _machineNameProvider = (StubMachineNameProvider)_container.Resolve(); - _threadProvider = (StubThreadProvider)_container.Resolve(); _distributedLockRepository = _container.Resolve>(); _transactionManager = _container.Resolve(); } - [Test] - public void TryAcquiringLockSucceeds() { - DistributedLock @lock; - var lockAcquired = _distributedLockService.TryAcquireLockForMachine(LockName, TimeSpan.FromSeconds(60), null, out @lock); - - Assert.That(lockAcquired, Is.True); - } - [Test] public void TryAcquiringLockTwiceOnSameMachineSucceeds() { - DistributedLock @lock; - var attempt1 = _distributedLockService.TryAcquireLockForMachine(LockName, TimeSpan.FromSeconds(60), null, out @lock); - var attempt2 = _distributedLockService.TryAcquireLockForMachine(LockName, TimeSpan.FromSeconds(60), null, out @lock); + IDistributedLock @lock; + var attempt1 = _distributedLockService.TryAcquireLock(LockName, TimeSpan.FromSeconds(60), out @lock); + var attempt2 = _distributedLockService.TryAcquireLock(LockName, TimeSpan.FromSeconds(60), out @lock); Assert.That(attempt1, Is.True); Assert.That(attempt2, Is.True); } - [Test] - public void TryAcquiringLockTwiceOnSameMachineIncreasesLockCountTwice() { - DistributedLock @lock; - _distributedLockService.TryAcquireLockForMachine(LockName, TimeSpan.FromSeconds(60), null, out @lock); - _distributedLockService.TryAcquireLockForMachine(LockName, TimeSpan.FromSeconds(60), null, out @lock); - var lockId = Int32.Parse(@lock.Id); - var lockRecord = _distributedLockRepository.Get(lockId); - Assert.That(lockRecord.Count, Is.EqualTo(2)); + [Test] + public void AcquiringTheLockOnTheSameMachineReturnsTheSameLock() { + IDistributedLock lock1, lock2; + _distributedLockService.TryAcquireLock(LockName, TimeSpan.FromSeconds(60), out lock1); + _distributedLockService.TryAcquireLock(LockName, TimeSpan.FromSeconds(60), out lock2); + + Assert.AreEqual(lock1, lock2); } [Test] - public void ReleasingLockDecreasesLockCount() { - DistributedLock @lock; - _distributedLockService.TryAcquireLockForMachine(LockName, TimeSpan.FromSeconds(60), null, out @lock); - _distributedLockService.TryAcquireLockForMachine(LockName, TimeSpan.FromSeconds(60), null, out @lock); + public void ReleasingSingleLockDeletesRecord() { + IDistributedLock lock1; + _distributedLockService.TryAcquireLock(LockName, TimeSpan.FromSeconds(60), out lock1); - var lockId = Int32.Parse(@lock.Id); - var lockRecord = _distributedLockRepository.Get(lockId); - - _distributedLockService.ReleaseLock(@lock); - _session.Refresh(lockRecord); - Assert.That(lockRecord.Count, Is.EqualTo(1)); - } - - [Test] - public void ReleasingLockAndCountReachesZeroDeletesLock() - { - DistributedLock @lock; - _distributedLockService.TryAcquireLockForMachine(LockName, TimeSpan.FromSeconds(60), null, out @lock); - - var lockId = Int32.Parse(@lock.Id); - _distributedLockService.ReleaseLock(@lock); - var lockRecord = _distributedLockRepository.Get(lockId); + lock1.Dispose(); + var lockRecord = _distributedLockRepository.Table.FirstOrDefault(); Assert.That(lockRecord, Is.Null); } + [Test] + public void ReleasingFirstLockDoesntDeleteRecord() { + IDistributedLock lock1, lock2; + _distributedLockService.TryAcquireLock(LockName, TimeSpan.FromSeconds(60), out lock1); + _distributedLockService.TryAcquireLock(LockName, TimeSpan.FromSeconds(60), out lock2); + + lock1.Dispose(); + var lockRecord = _distributedLockRepository.Table.FirstOrDefault(); + Assert.That(lockRecord, Is.Not.Null); + + lock2.Dispose(); + lockRecord = _distributedLockRepository.Table.FirstOrDefault(); + Assert.That(lockRecord, Is.Null); + } + [Test] public void TryAcquiringLockTwiceFails() { - DistributedLock @lock; + _distributedLockService.DisableMonitorLock = true; + IDistributedLock @lock; _machineNameProvider.MachineName = "Orchard Test Machine 1"; - var attempt1 = _distributedLockService.TryAcquireLockForMachine(LockName, TimeSpan.FromSeconds(60), null, out @lock); + var attempt1 = _distributedLockService.TryAcquireLock(LockName, TimeSpan.FromSeconds(60), out @lock); _machineNameProvider.MachineName = "Orchard Test Machine 2"; - var attempt2 = _distributedLockService.TryAcquireLockForMachine(LockName, TimeSpan.FromSeconds(60), null, out @lock); + var attempt2 = _distributedLockService.TryAcquireLock(LockName, TimeSpan.FromSeconds(60), out @lock); Assert.That(attempt1, Is.True); Assert.That(attempt2, Is.False); @@ -111,66 +100,90 @@ namespace Orchard.Tests.Tasks { [Test] public void TryAcquiringNonExpiredActiveLockFails() { - DistributedLock @lock; - CreateNonExpiredActiveLock("Other Machine", threadId: null); - var success = _distributedLockService.TryAcquireLockForMachine(LockName, TimeSpan.FromHours(1), null, out @lock); + IDistributedLock @lock; + CreateNonExpiredActiveLock("Other Machine"); + var success = _distributedLockService.TryAcquireLock(LockName, TimeSpan.FromHours(1), out @lock); Assert.That(success, Is.False); } [Test] - public void TryAcquiringNonExpiredButInactiveLockSucceeds() { - DistributedLock @lock; - CreateNonExpiredButInactiveLock("Other Machine", threadId: null); - var success = _distributedLockService.TryAcquireLockForMachine(LockName, TimeSpan.FromHours(1), null, out @lock); + public void TryAcquiringNonExpiredButInactiveLockFromOtherMachineFails() { + IDistributedLock @lock; + CreateNonExpiredActiveLock("Other Machine"); + var success = _distributedLockService.TryAcquireLock(LockName, TimeSpan.FromHours(1), out @lock); + + Assert.That(success, Is.False); + } + + [Test] + public void TryAcquiringNonExpiredButInactiveLockFromSameMachineSucceeds() { + IDistributedLock @lock; + CreateNonExpiredActiveLock("Orchard Machine"); + var success = _distributedLockService.TryAcquireLock(LockName, TimeSpan.FromHours(1), out @lock); Assert.That(success, Is.True); } [Test] public void TryAcquiringExpiredButActiveLockSucceeds() { - DistributedLock @lock; - CreateExpiredButActiveLock("Other Machine", threadId: null); - var success = _distributedLockService.TryAcquireLockForMachine(LockName, TimeSpan.FromHours(1), null, out @lock); + IDistributedLock @lock; + CreateExpiredButActiveLock("Other Machine"); + var success = _distributedLockService.TryAcquireLock(LockName, TimeSpan.FromHours(1), out @lock); Assert.That(success, Is.True); } [Test] public void TryAcquiringNonExpiredAndActiveLockFromCurrentOwnerSucceeds() { - DistributedLock @lock; - CreateNonExpiredActiveLock(GetMachineName(), threadId: null); - var success = _distributedLockService.TryAcquireLockForMachine(LockName, TimeSpan.FromHours(1), null, out @lock); + IDistributedLock @lock; + CreateNonExpiredActiveLock(GetMachineName()); + var success = _distributedLockService.TryAcquireLock(LockName, TimeSpan.FromHours(1), out @lock); Assert.That(success, Is.True); } [Test] public void AcquiringNonExpiredAndActiveLockFromDifferentOwnerThrowsTimeoutException() { - CreateNonExpiredActiveLock("Other Machine", threadId: null); - Assert.Throws(() => _distributedLockService.AcquireLockForMachine(LockName, TimeSpan.FromHours(1), TimeSpan.Zero)); + CreateNonExpiredActiveLock("Other Machine"); + Assert.Throws(() => _distributedLockService.AcquireLock(LockName, TimeSpan.FromHours(1), TimeSpan.Zero)); } [Test] public void MultipleAcquisitionsFromDifferentMachinesShouldFail() { - DistributedLock @lock; + IDistributedLock @lock; + _distributedLockService.DisableMonitorLock = true; _machineNameProvider.MachineName = "Orchard Test Machine 1"; - var attempt1 = _distributedLockService.TryAcquireLockForMachine(LockName, TimeSpan.FromSeconds(60), null, out @lock); + var attempt1 = _distributedLockService.TryAcquireLock(LockName, TimeSpan.FromSeconds(60), out @lock); _machineNameProvider.MachineName = "Orchard Test Machine 2"; - var attempt2 = _distributedLockService.TryAcquireLockForMachine(LockName, TimeSpan.FromSeconds(60), null, out @lock); + var attempt2 = _distributedLockService.TryAcquireLock(LockName, TimeSpan.FromSeconds(60), out @lock); Assert.That(attempt1, Is.True); Assert.That(attempt2, Is.False); } + [Test] + public void MultipleAcquisitionsFromDifferentMachinesOnDifferentTenantShouldSucceed() { + IDistributedLock @lock; + _distributedLockService.DisableMonitorLock = true; + _machineNameProvider.MachineName = "Orchard Test Machine 1"; + var attempt1 = _distributedLockService.TryAcquireLock(LockName, TimeSpan.FromSeconds(60), out @lock); + _machineNameProvider.MachineName = "Orchard Test Machine 2"; + _shellSettings.Name = "Foo"; + var attempt2 = _distributedLockService.TryAcquireLock(LockName, TimeSpan.FromSeconds(60), out @lock); + + Assert.That(attempt1, Is.True); + Assert.That(attempt2, Is.True); + } + [Test] public void MultithreadedAcquisitionsShouldNotCauseTransactionErrors() { var tasks = new List(); for (var i = 0; i < 10; i++) { var task = Task.Factory.StartNew(() => { - DistributedLock @lock; - Assert.DoesNotThrow(() => _distributedLockService.TryAcquireLockForMachine(LockName, TimeSpan.FromHours(1), null, out @lock)); + IDistributedLock @lock; + Assert.DoesNotThrow(() => _distributedLockService.TryAcquireLock(LockName, TimeSpan.FromHours(1), out @lock)); }); tasks.Add(task); @@ -179,61 +192,57 @@ namespace Orchard.Tests.Tasks { Task.WaitAll(tasks.ToArray()); } - [Test] - public void MixedScopeAcquisitionsShouldThrow() { - DistributedLock @lock; - Assert.DoesNotThrow(() => _distributedLockService.TryAcquireLockForMachine(LockName, TimeSpan.FromSeconds(60), null, out @lock)); - Assert.Throws(() => _distributedLockService.TryAcquireLockForThread(LockName, TimeSpan.FromSeconds(60), null, out @lock)); - } - [Test] public void TryAcquireActiveLockWithNullTimeoutReturnsFalseImmediately() { - CreateNonExpiredActiveLock("Other Machine", null); + // Disable monitor locking to simulate concurrent requests + _distributedLockService.DisableMonitorLock = true; + CreateNonExpiredActiveLock("Other Machine"); - DistributedLock @lock; - var acquired = _distributedLockService.TryAcquireLockForThread(LockName, TimeSpan.FromMinutes(1), null, out @lock); + IDistributedLock @lock; + var acquired = _distributedLockService.TryAcquireLock(LockName, TimeSpan.FromMinutes(1), out @lock); Assert.That(acquired, Is.False); } [Test] public void ActiveLockWithUndefinedValidUntilNeverExpires() { - CreateNonExpiredActiveLockThatNeverExpires("Other Machine", null); + // Disable monitor locking to simulate concurrent requests + _distributedLockService.DisableMonitorLock = true; + CreateNonExpiredActiveLockThatNeverExpires("Other Machine"); + _clock.Advance(DateTime.MaxValue - _clock.UtcNow); // Fast forward to the End of Time. - DistributedLock @lock; - var acquired = _distributedLockService.TryAcquireLockForThread(LockName, TimeSpan.FromMinutes(1), null, out @lock); + IDistributedLock @lock; + var acquired = _distributedLockService.TryAcquireLock(LockName, TimeSpan.FromMinutes(1), out @lock); Assert.That(acquired, Is.False); } [Test] public void ActiveLockWithUndefinedValidUntilNeverExpiresUntilReleased() { - DistributedLock @lock; + IDistributedLock @lock; // Create a never expiring lock. _machineNameProvider.MachineName = "Orchard Test Machine 1"; - var attempt1 = _distributedLockService.TryAcquireLockForThread(LockName, maxValidFor: null, timeout: null, @lock: out @lock); + var attempt1 = _distributedLockService.TryAcquireLock(LockName, maxValidFor: null, timeout: null, l: out @lock); // Release the lock. - _distributedLockService.ReleaseLock(@lock); + _distributedLockService.ReleaseDistributedLock((DistributedLock)@lock); // Acquire the lock from another machine. _machineNameProvider.MachineName = "Orchard Test Machine 2"; - var attempt2 = _distributedLockService.TryAcquireLockForThread(LockName, maxValidFor: null, timeout: null, @lock: out @lock); + var attempt2 = _distributedLockService.TryAcquireLock(LockName, maxValidFor: null, timeout: null, l: out @lock); // Validate the results. Assert.That(attempt1, Is.True); Assert.That(attempt2, Is.True); } - private DistributedLockRecord CreateLockRecord(int count, DateTime createdUtc, DateTime? validUntilUtc, string machineName, int? threadId) { + private DistributedLockRecord CreateLockRecord(DateTime createdUtc, DateTime? validUntilUtc, string machineName) { var record = new DistributedLockRecord { - Name = LockName, - Count = count, + Name = ShellSettings.DefaultName + ":" + LockName, CreatedUtc = createdUtc, ValidUntilUtc = validUntilUtc, MachineName = machineName, - ThreadId = threadId }; _distributedLockRepository.Create(record); @@ -241,32 +250,23 @@ namespace Orchard.Tests.Tasks { return record; } - private DistributedLockRecord CreateNonExpiredActiveLock(string machineName, int? threadId) { + private DistributedLockRecord CreateNonExpiredActiveLock(string machineName) { var now = _clock.UtcNow; - return CreateLockRecord(1, now, now + TimeSpan.FromHours(1), machineName, threadId); + return CreateLockRecord(now, now + TimeSpan.FromHours(1), machineName); } - private DistributedLockRecord CreateNonExpiredButInactiveLock(string machineName, int? threadId) { + private DistributedLockRecord CreateExpiredButActiveLock(string machineName) { var now = _clock.UtcNow; - return CreateLockRecord(0, now, now + TimeSpan.FromHours(1), machineName, threadId); + return CreateLockRecord(now, now - TimeSpan.FromHours(1), machineName); } - private DistributedLockRecord CreateExpiredButActiveLock(string machineName, int? threadId) { + private DistributedLockRecord CreateNonExpiredActiveLockThatNeverExpires(string machineName) { var now = _clock.UtcNow; - return CreateLockRecord(1, now, now - TimeSpan.FromHours(1), machineName, threadId); - } - - private DistributedLockRecord CreateNonExpiredActiveLockThatNeverExpires(string machineName, int? threadId) { - var now = _clock.UtcNow; - return CreateLockRecord(1, now, null, machineName, threadId); + return CreateLockRecord(now, null, machineName); } private string GetMachineName() { return _machineNameProvider.GetMachineName(); } - - private int GetThreadId() { - return _threadProvider.GetCurrentThreadId(); - } } } diff --git a/src/Orchard.Tests/Tasks/LockTests.cs b/src/Orchard.Tests/Tasks/LockTests.cs index d94218428..2b7f0687a 100644 --- a/src/Orchard.Tests/Tasks/LockTests.cs +++ b/src/Orchard.Tests/Tasks/LockTests.cs @@ -7,24 +7,23 @@ namespace Orchard.Tests.Tasks { [TestFixture] public class LockTests : ContainerTestBase { private const string LockName = "Orchard Test Lock"; - private const string LockId = "1"; - private Mock _distributedLockServiceMock; + private Mock _distributedLockServiceMock; private DistributedLock _lock; protected override void Register(ContainerBuilder builder) { - _distributedLockServiceMock = new Mock(); + _distributedLockServiceMock = new Mock(); builder.RegisterInstance(_distributedLockServiceMock.Object); } protected override void Resolve(ILifetimeScope container) { - _lock = DistributedLock.ForMachine(_distributedLockServiceMock.Object, LockName, "Orchard Test Machine", LockId); + _lock = new DistributedLock(_distributedLockServiceMock.Object, LockName); } [Test] public void DisposeInvokesDistributedLockServiceDisposeLock() { _lock.Dispose(); - _distributedLockServiceMock.Verify(service => service.ReleaseLock(_lock), Times.Exactly(1)); + _distributedLockServiceMock.Verify(service => service.ReleaseDistributedLock(_lock), Times.Exactly(1)); } [Test] @@ -33,7 +32,7 @@ namespace Orchard.Tests.Tasks { _lock.Dispose(); _lock.Dispose(); - _distributedLockServiceMock.Verify(service => service.ReleaseLock(_lock), Times.Exactly(1)); + _distributedLockServiceMock.Verify(service => service.ReleaseDistributedLock(_lock), Times.Exactly(1)); } } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs index 1a648ed78..846c35827 100644 --- a/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs +++ b/src/Orchard.Web/Modules/Orchard.AuditTrail/Services/AuditTrailTrimmingBackgroundTask.cs @@ -41,8 +41,8 @@ namespace Orchard.AuditTrail.Services { Logger.Debug("Beginning sweep."); // Only allow this task to run on one farm node at a time. - DistributedLock @lock; - if (_distributedLockService.TryAcquireLockForMachine(GetType().FullName, TimeSpan.FromHours(1), out @lock)) { + IDistributedLock @lock; + if (_distributedLockService.TryAcquireLock(GetType().FullName, TimeSpan.FromHours(1), out @lock)) { using (@lock) { // We don't need to check the audit trail for events to remove every minute. Let's stick with twice a day. diff --git a/src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Services/Jobs/JobProcessor.cs b/src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Services/Jobs/JobProcessor.cs index 4a066e68a..4912cdde9 100644 --- a/src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Services/Jobs/JobProcessor.cs +++ b/src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Services/Jobs/JobProcessor.cs @@ -51,8 +51,8 @@ namespace Orchard.Azure.MediaServices.Services.Jobs { } // Only allow this task to run on one farm node at a time. - DistributedLock @lock; - if (_distributedLockService.TryAcquireLockForMachine(GetType().FullName, TimeSpan.FromHours(1), out @lock)) { + IDistributedLock @lock; + if (_distributedLockService.TryAcquireLock(GetType().FullName, TimeSpan.FromHours(1), out @lock)) { using (@lock) { var jobs = _jobManager.GetActiveJobs().ToDictionary(job => job.WamsJobId); diff --git a/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueProcessor.cs b/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueProcessor.cs index 039bfbc75..dc9cb6438 100644 --- a/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueProcessor.cs +++ b/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueProcessor.cs @@ -32,8 +32,8 @@ namespace Orchard.JobsQueue.Services { // prevent two threads on the same machine to process the message queue if (_rwl.TryEnterWriteLock(0)) { try { - DistributedLock @lock; - if(_distributedLockService.TryAcquireLockForMachine(GetType().FullName, TimeSpan.FromMinutes(5), out @lock)){ + IDistributedLock @lock; + if(_distributedLockService.TryAcquireLock(GetType().FullName, TimeSpan.FromMinutes(5), out @lock)){ using (@lock) { IEnumerable messages; diff --git a/src/Orchard.Web/Modules/Orchard.TaskLease/Services/ITaskLeaseService.cs b/src/Orchard.Web/Modules/Orchard.TaskLease/Services/ITaskLeaseService.cs index 625472446..c32e3d37e 100644 --- a/src/Orchard.Web/Modules/Orchard.TaskLease/Services/ITaskLeaseService.cs +++ b/src/Orchard.Web/Modules/Orchard.TaskLease/Services/ITaskLeaseService.cs @@ -6,7 +6,7 @@ namespace Orchard.TaskLease.Services { /// Describes a service to save and acquire task leases. A task lease can't be acquired by two different machines, /// for a specific amount of time. Optionnally a State can be saved along with the lease. /// - [Obsolete("Use Orchard.Tasks.Locking.IDistributedLockService and the AcquireLockForMachine/TryAcquireLockForMachine methods instead.")] + [Obsolete("Use Orchard.Tasks.Locking.IDistributedLockService instead.")] public interface ITaskLeaseService : IDependency { /// diff --git a/src/Orchard.Web/Modules/Orchard.TaskLease/Services/TaskLeaseService.cs b/src/Orchard.Web/Modules/Orchard.TaskLease/Services/TaskLeaseService.cs index 8cf04b3fe..398c1092f 100644 --- a/src/Orchard.Web/Modules/Orchard.TaskLease/Services/TaskLeaseService.cs +++ b/src/Orchard.Web/Modules/Orchard.TaskLease/Services/TaskLeaseService.cs @@ -9,7 +9,7 @@ namespace Orchard.TaskLease.Services { /// /// Provides a database driven implementation of /// - [Obsolete("Use Orchard.Tasks.Locking.DistributedLockService and the AcquireLockForMachine/TryAcquireLockForMachine methods instead.")] + [Obsolete("Use Orchard.Tasks.Locking.DistributedLockService instead.")] public class TaskLeaseService : ITaskLeaseService { private readonly IRepository _repository; diff --git a/src/Orchard/Data/Migration/AutomaticDataMigrations.cs b/src/Orchard/Data/Migration/AutomaticDataMigrations.cs index 50727d47f..7c0693540 100644 --- a/src/Orchard/Data/Migration/AutomaticDataMigrations.cs +++ b/src/Orchard/Data/Migration/AutomaticDataMigrations.cs @@ -29,8 +29,8 @@ namespace Orchard.Data.Migration { public ILogger Logger { get; set; } public void Activated() { - DistributedLock @lock; - if(_distributedLockService.TryAcquireLockForThread(GetType().FullName, TimeSpan.FromMinutes(30), TimeSpan.FromMilliseconds(250), out @lock)) { + 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[] { diff --git a/src/Orchard/Environment/IThreadProvider.cs b/src/Orchard/Environment/IThreadProvider.cs deleted file mode 100644 index 29458bf27..000000000 --- a/src/Orchard/Environment/IThreadProvider.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Orchard.Environment { - - /// - /// Describes a service which returns the managed thread ID of the current thread. - /// - public interface IThreadProvider { - - /// - /// Returns the managed thread ID of the current thread. - /// - int GetCurrentThreadId(); - } -} \ No newline at end of file diff --git a/src/Orchard/Environment/OrchardStarter.cs b/src/Orchard/Environment/OrchardStarter.cs index 1e0db5736..66ea2a066 100644 --- a/src/Orchard/Environment/OrchardStarter.cs +++ b/src/Orchard/Environment/OrchardStarter.cs @@ -67,7 +67,6 @@ namespace Orchard.Environment { builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); builder.RegisterType().As().SingleInstance(); - builder.RegisterType().As().SingleInstance(); //builder.RegisterType().As().SingleInstance(); RegisterVolatileProvider(builder); diff --git a/src/Orchard/Environment/ThreadProvider.cs b/src/Orchard/Environment/ThreadProvider.cs deleted file mode 100644 index d3a65d8fb..000000000 --- a/src/Orchard/Environment/ThreadProvider.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Threading; - -namespace Orchard.Environment { - public class ThreadProvider : IThreadProvider { - public int GetCurrentThreadId() { - return Thread.CurrentThread.ManagedThreadId; - } - } -} \ No newline at end of file diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index 0cdfdf839..6e2f60292 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -152,8 +152,6 @@ - - @@ -402,6 +400,7 @@ + diff --git a/src/Orchard/Tasks/Locking/Migrations/FrameworkMigrations.cs b/src/Orchard/Tasks/Locking/Migrations/FrameworkMigrations.cs index ce27736a6..2a43a2e19 100644 --- a/src/Orchard/Tasks/Locking/Migrations/FrameworkMigrations.cs +++ b/src/Orchard/Tasks/Locking/Migrations/FrameworkMigrations.cs @@ -7,15 +7,13 @@ namespace Orchard.Tasks.Locking.Migrations { public int Create() { SchemaBuilder.CreateTable("DistributedLockRecord", table => table .Column("Id", column => column.PrimaryKey().Identity()) - .Column("Name", column => column.NotNull().WithLength(256)) + .Column("Name", column => column.NotNull().WithLength(512).Unique()) .Column("MachineName", column => column.WithLength(256)) - .Column("ThreadId", column => column.Nullable()) - .Column("Count") .Column("CreatedUtc") .Column("ValidUntilUtc", column => column.Nullable())); SchemaBuilder.AlterTable("DistributedLockRecord", table => { - table.CreateIndex("IDX_DistributedLockRecord_Name_ValidUntilUtc_Count", "Name", "ValidUntilUtc", "Count"); + table.CreateIndex("IDX_DistributedLockRecord_Name", "Name"); }); return 1; diff --git a/src/Orchard/Tasks/Locking/Records/DistributedLockRecord.cs b/src/Orchard/Tasks/Locking/Records/DistributedLockRecord.cs index ec8fbff96..5dee047b0 100644 --- a/src/Orchard/Tasks/Locking/Records/DistributedLockRecord.cs +++ b/src/Orchard/Tasks/Locking/Records/DistributedLockRecord.cs @@ -5,8 +5,6 @@ namespace Orchard.Tasks.Locking.Records { public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual string MachineName { get; set; } - public virtual int? ThreadId { get; set; } - public virtual int Count { get; set; } public virtual DateTime CreatedUtc { get; set; } public virtual DateTime? ValidUntilUtc { get; set; } } diff --git a/src/Orchard/Tasks/Locking/Services/DistributedLock.cs b/src/Orchard/Tasks/Locking/Services/DistributedLock.cs index 05977bea4..a15da99ca 100644 --- a/src/Orchard/Tasks/Locking/Services/DistributedLock.cs +++ b/src/Orchard/Tasks/Locking/Services/DistributedLock.cs @@ -3,44 +3,34 @@ using System.Threading; namespace Orchard.Tasks.Locking.Services { - /// - /// Represents a distributed lock. /> - /// - public class DistributedLock : IDisposable { - public static DistributedLock ForMachine(IDistributedLockService service, string name, string machineName, string lockId) { - return new DistributedLock { - _service = service, - Name = name, - MachineName = machineName, - Id = lockId - }; + public class DistributedLock : IDistributedLock { + + private DistributedLockService _service; + private string _name; + private int _count; + + public string Name { + get { + return _name; + } } - public static DistributedLock ForThread(IDistributedLockService service, string name, string machineName, int threadId, string lockId) { - return new DistributedLock { - _service = service, - Name = name, - MachineName = machineName, - ThreadId = threadId, - Id = lockId - }; + public DistributedLock(DistributedLockService service, string name) { + _service = service; + _name = name; + _count = 1; } - private IDistributedLockService _service; - private int _isDisposed; - - private DistributedLock() { + public void IncreaseReferenceCount() { + _count++; } - public string Id { get; private set; } - public string Name { get; private set; } - public string MachineName { get; private set; } - public int? ThreadId { get; private set; } - - // This will be called at least and at the latest by the IoC container when the request ends. public void Dispose() { - if(Interlocked.CompareExchange(ref _isDisposed, 1, 0) == 0) - _service.ReleaseLock(this); + _count--; + if (_count == 0) { + Monitor.Exit(String.Intern(_name)); + _service.ReleaseDistributedLock(this); + } } } } \ No newline at end of file diff --git a/src/Orchard/Tasks/Locking/Services/DistributedLockService.cs b/src/Orchard/Tasks/Locking/Services/DistributedLockService.cs index ed0fb21e0..34ab4332f 100644 --- a/src/Orchard/Tasks/Locking/Services/DistributedLockService.cs +++ b/src/Orchard/Tasks/Locking/Services/DistributedLockService.cs @@ -1,10 +1,13 @@ using System; +using System.Collections.Concurrent; using System.Data; using System.Linq; +using System.Threading; using System.Threading.Tasks; using Autofac; using Orchard.Data; using Orchard.Environment; +using Orchard.Environment.Configuration; using Orchard.Exceptions; using Orchard.Logging; using Orchard.Services; @@ -13,85 +16,49 @@ using Orchard.Tasks.Locking.Records; namespace Orchard.Tasks.Locking.Services { public class DistributedLockService : Component, IDistributedLockService { - private readonly IMachineNameProvider _machineNameProvider; - private readonly ILifetimeScope _lifetimeScope; private readonly IClock _clock; - private readonly IThreadProvider _threadProvider; + private readonly IMachineNameProvider _machineNameProvider; + private readonly ShellSettings _shellSettings; + private readonly ILifetimeScope _lifetimeScope; + private readonly ConcurrentDictionary _locks = new ConcurrentDictionary(); - public DistributedLockService(IMachineNameProvider machineNameProvider, IThreadProvider threadProvider, ILifetimeScope lifetimeScope, IClock clock) { - _machineNameProvider = machineNameProvider; - _lifetimeScope = lifetimeScope; + public bool DisableMonitorLock { get; set; } + + public DistributedLockService( + IMachineNameProvider machineNameProvider, + ILifetimeScope lifetimeScope, + IClock clock, + ShellSettings shellSettings) { _clock = clock; - _threadProvider = threadProvider; + _lifetimeScope = lifetimeScope; + + _shellSettings = shellSettings; + _machineNameProvider = machineNameProvider; } - public bool TryAcquireLockForMachine(string name, TimeSpan? maxValidFor, TimeSpan? timeout, out DistributedLock @lock) { - return TryAcquireLock(name, maxValidFor, timeout, GetMachineName(), null, out @lock); - } - - public DistributedLock AcquireLockForMachine(string name, TimeSpan? maxValidFor, TimeSpan? timeout) { - return AcquireLock(name, maxValidFor, timeout, GetMachineName(), null); - } - - public bool TryAcquireLockForThread(string name, TimeSpan? maxValidFor, TimeSpan? timeout, out DistributedLock @lock) { - return TryAcquireLock(name, maxValidFor, timeout, GetMachineName(), GetThreadId(), out @lock); - } - - public DistributedLock AcquireLockForThread(string name, TimeSpan? maxValidFor, TimeSpan? timeout) { - return AcquireLock(name, maxValidFor, timeout, GetMachineName(), GetThreadId()); - } - - public void ReleaseLock(DistributedLock @lock) { - var childLifetimeScope = CreateChildLifetimeScope(@lock.Name); - + public bool TryAcquireLock(string name, TimeSpan? maxValidFor, TimeSpan? timeout, out IDistributedLock l) { try { - var repository = childLifetimeScope.Resolve>(); - var transactionManager = childLifetimeScope.Resolve(); - transactionManager.RequireNew(IsolationLevel.ReadCommitted); - var lockId = Int32.Parse(@lock.Id); - var record = repository.Get(lockId); - - if (record == null) - throw new OrchardException(T("No lock record could be found for the specified lock to be released.")); - - if (record.Count <= 0) - throw new OrchardException(T("The specified lock has already been released.")); - - record.Count--; - - if(record.Count == 0) - repository.Delete(record); + l = AcquireLock(name, maxValidFor, timeout); + return l != null; } - catch (Exception ex) { - if (ex.IsFatal()) throw; - Logger.Error(ex, "An non-fatal error occurred while trying to dispose a distributed lock with name '{0}' and ID {1}.", @lock.Name, @lock.Id); - } - finally { - childLifetimeScope.Dispose(); + catch { + l = null; + return false; } } - private bool TryAcquireLock(string name, TimeSpan? maxValidFor, TimeSpan? timeout, string machineName, int? threadId, out DistributedLock @lock) { - @lock = AcquireLock(name, maxValidFor, machineName, threadId, timeout ?? TimeSpan.Zero); - return @lock != null; - } - - private DistributedLock AcquireLock(string name, TimeSpan? maxValidFor, TimeSpan? timeout, string machineName, int? threadId) { - var @lock = AcquireLock(name, maxValidFor, machineName, threadId, timeout); - if (@lock != null) - return @lock; - - throw new TimeoutException(String.Format("Failed to acquire a lock named '{0}' within the specified timeout ('{1}').", name, timeout)); - } - - private DistributedLock AcquireLock(string name, TimeSpan? maxValidFor, string machineName, int? threadId, TimeSpan? timeout = null) { + public IDistributedLock AcquireLock(string name, TimeSpan? maxValidFor, TimeSpan? timeout) { + DistributedLock l = null; + try { - DistributedLock @lock = null; - var acquired = Poll(() => (@lock = AcquireLockInternal(name, maxValidFor, machineName, threadId)) != null, timeout); + + var acquired = Poll(() => (l = AcquireLockInternal(name, maxValidFor)) != null, timeout); if (acquired) { Logger.Debug("Successfully acquired a lock named '{0}'.", name); - return @lock; + } + else { + Logger.Debug("Failed to acquire a lock named '{0}'.", name); } } catch (Exception ex) { @@ -99,42 +66,79 @@ namespace Orchard.Tasks.Locking.Services { throw; } - Logger.Debug(timeout == null - ? "Failed to acquire a lock named '{0}'." - : "Failed to acquire a lock named '{0}' within the specified timeout ('{1}')." - , name, timeout); + if (l == null && timeout != null) { + throw new TimeoutException(String.Format("Failed to acquire a lock named '{0}' within the specified timeout ('{1}').", name, timeout)); + } - return null; + return l; } - private DistributedLock AcquireLockInternal(string name, TimeSpan? maxValidFor, string machineName, int? threadId) { - var childLifetimeScope = CreateChildLifetimeScope(name); + public void ReleaseDistributedLock(DistributedLock l) { try { - var transactionManager = childLifetimeScope.Resolve(); - transactionManager.RequireNew(IsolationLevel.ReadCommitted); + var record = GetDistributedLockRecordByName(l.Name); - // This way we can create a nested transaction scope instead of having the unwanted effect - // of manipulating the transaction of the caller. - var repository = childLifetimeScope.Resolve>(); + if (record == null) { + throw new OrchardException(T("No lock record could be found for the specified lock to be released.")); + } + + TryCommitNewTransaction(repository => repository.Delete(record)); + } + catch (Exception ex) { + if (ex.IsFatal()) throw; + Logger.Error(ex, "An non-fatal error occurred while trying to dispose a distributed lock with name '{0}'.", l.Name); + } + } + + private DistributedLockRecord GetDistributedLockRecordByName(string name) { + DistributedLockRecord result = null; + TryCommitNewTransaction(repository => { + result = repository.Table.FirstOrDefault(x => + x.Name == name + ); + }); + + return result; + } + + private DistributedLockRecord GetValidDistributedLockRecordByName(string name) { + DistributedLockRecord result = null; + TryCommitNewTransaction(repository => { + result = repository.Table.FirstOrDefault(x => + x.Name == name && + (x.ValidUntilUtc == null || x.ValidUntilUtc >= _clock.UtcNow) + ); + }); + + return result; + } + + private DistributedLock AcquireLockInternal(string name, TimeSpan? maxValidFor) { + try { + name = GetTenantLockName(name); + + if (!DisableMonitorLock && !Monitor.TryEnter(String.Intern(name))) { + return null; + } + + DistributedLock dLock = null; + + // Returns the existing lock in case of reentrancy. + if(!DisableMonitorLock && _locks.TryGetValue(name, out dLock)) { + dLock.IncreaseReferenceCount(); + return dLock; + } // Find an existing, active lock, if any. - var record = repository.Table.FirstOrDefault(x => x.Name == name && (x.ValidUntilUtc == null || x.ValidUntilUtc >= _clock.UtcNow) && x.Count > 0); + var record = GetValidDistributedLockRecordByName(name); - // The current owner name (based on machine name and current thread ID). + // The current owner name (based on machine name). var canAcquireLock = false; // Check if there's already an active lock. if (record != null) { // Check if the machine name assigned to the lock is the one trying to acquire it. - if (record.MachineName == machineName) { - if (record.ThreadId != threadId) - throw new InvalidOperationException( - threadId == null - ? "An attempt to acquire a lock for a machine was detected while the requested lock is already assigned to a specific thread." - : "An attempt to acquire a lock for a thread was detected while the requested lock is already assigned to a machine."); - - record.Count++; + if (record.MachineName == _machineNameProvider.GetMachineName()) { canAcquireLock = true; } } @@ -142,30 +146,38 @@ namespace Orchard.Tasks.Locking.Services { // No one has an active lock yet, so good to go. record = new DistributedLockRecord { Name = name, - MachineName = machineName, - ThreadId = threadId, - Count = 1, + MachineName = _machineNameProvider.GetMachineName(), CreatedUtc = _clock.UtcNow, ValidUntilUtc = maxValidFor != null ? _clock.UtcNow + maxValidFor : null }; - repository.Create(record); - canAcquireLock = true; + + + canAcquireLock = TryCommitNewTransaction( repository => { + repository.Create(record); + }); } - if (!canAcquireLock) + if (!canAcquireLock) { return null; + } - return threadId != null - ? DistributedLock.ForThread(this, name, machineName, threadId.Value, record.Id.ToString()) - : DistributedLock.ForMachine(this, name, machineName, record.Id.ToString()); + dLock = new DistributedLock(this, name); + if (!DisableMonitorLock) { + _locks.TryAdd(name, dLock); + } + + return dLock; } catch (Exception ex) { + Monitor.Exit(String.Intern(name)); + Logger.Error(ex, "An error occurred while trying to acquire a lock."); throw; - } - finally { - childLifetimeScope.Dispose(); - } + } + } + + private string GetTenantLockName(string name) { + return _shellSettings.Name + ":" + name; } /// @@ -188,16 +200,25 @@ namespace Orchard.Tasks.Locking.Services { return acquired; } - private string GetMachineName() { - return _machineNameProvider.GetMachineName(); - } + private bool TryCommitNewTransaction(Action> action) { + if (action == null) { + throw new ArgumentNullException(); + } - private int GetThreadId() { - return _threadProvider.GetCurrentThreadId(); - } + try { + using (var childLifetimeScope = _lifetimeScope.BeginLifetimeScope()) { + var repository = childLifetimeScope.Resolve>(); + var transactionManager = childLifetimeScope.Resolve(); + transactionManager.RequireNew(IsolationLevel.ReadCommitted); + action(repository); + } - private ILifetimeScope CreateChildLifetimeScope(string name) { - return _lifetimeScope.BeginLifetimeScope("Orchard.Tasks.Locking." + name); + return true; + } + catch { + return false; + } + } } } \ No newline at end of file diff --git a/src/Orchard/Tasks/Locking/Services/IDistributedLock.cs b/src/Orchard/Tasks/Locking/Services/IDistributedLock.cs new file mode 100644 index 000000000..6151554ff --- /dev/null +++ b/src/Orchard/Tasks/Locking/Services/IDistributedLock.cs @@ -0,0 +1,11 @@ +using System; + +namespace Orchard.Tasks.Locking.Services { + + /// + /// Represents a distributed lock. /> + /// + public interface IDistributedLock : IDisposable { + string Name { get; } + } +} \ No newline at end of file diff --git a/src/Orchard/Tasks/Locking/Services/IDistributedLockService.cs b/src/Orchard/Tasks/Locking/Services/IDistributedLockService.cs index 31818f200..c638a7aca 100644 --- a/src/Orchard/Tasks/Locking/Services/IDistributedLockService.cs +++ b/src/Orchard/Tasks/Locking/Services/IDistributedLockService.cs @@ -4,51 +4,26 @@ namespace Orchard.Tasks.Locking.Services { /// /// Provides distributed locking functionality. /// - public interface IDistributedLockService : ISingletonDependency { + public interface IDistributedLockService : IDependency { /// - /// Tries to acquire a lock on the specified name for the current machine. + /// Tries to acquire a distributed lock on a named resource for the current tenant. /// /// The name to use for the lock. - /// The maximum amount of time the lock is allowed. This is a safety net in case the caller fails to release the lock. - /// The amount of time to wait for the lock to be acquired before timing out. A null value will cause the method to return immedieately if no lock could be acquired. + /// The maximum amount of time the lock is allowed. This is a safety net in case the caller fails to release the lock. If null is specified, the lock never expires until it's released by the owner. + /// The amount of time to wait for the lock to be acquired before timing out. A null value will cause the method to block indefinitely until a lock can be acquired. /// The acquired lock. /// Returns true if a lock was successfully acquired, false otherwise. - bool TryAcquireLockForMachine(string name, TimeSpan? maxValidFor, TimeSpan? timeout, out DistributedLock @lock); + bool TryAcquireLock(string name, TimeSpan? maxValidFor, TimeSpan? timeout, out IDistributedLock @lock); /// - /// Acquires a lock with the specified parameters for the current machine. + /// Acquires a distributed lock on a named resource for the current tenant. /// /// The name to use for the lock. - /// The maximum amount of time the lock is allowed. This is a safety net in case the caller fails to release the lock. If null is specified, the lock never expires until it's released by the owner. + /// The maximum amount of time the lock is allowed. This is a safety net in case the caller fails to release the lock. If null is specified, the lock never expires until it's released by the owner. /// The amount of time to wait for the lock to be acquired before timing out. A null value will cause the method to block indefinitely until a lock can be acquired. /// Returns a lock. /// Throws a TimeoutException if no lock could be acquired in time. - DistributedLock AcquireLockForMachine(string name, TimeSpan? maxValidFor, TimeSpan? timeout); - - /// - /// Tries to acquire a lock on the specified name for the current thread. - /// - /// The name to use for the lock. - /// The maximum amount of time the lock is allowed. This is a safety net in case the caller fails to release the lock. If null is specified, the lock never expires until it's released by the owner. - /// The amount of time to wait for the lock to be acquired before timing out. A null value will cause the method to return immedieately if no lock could be acquired. - /// The acquired lock. - /// Returns true if a lock was successfully acquired, false otherwise. - bool TryAcquireLockForThread(string name, TimeSpan? maxValidFor, TimeSpan? timeout, out DistributedLock @lock); - - /// - /// Acquires a lock with the specified parameters for the current thread. - /// - /// The name to use for the lock. - /// The maximum amount of time the lock is allowed. This is a safety net in case the caller fails to release the lock. If null is specified, the lock never expires until it's released by the owner. - /// The amount of time to wait for the lock to be acquired before timing out. A null value will cause the method to block indefinitely until a lock can be acquired. - /// Returns a lock. - /// Throws a TimeoutException if no lock could be acquired in time. - DistributedLock AcquireLockForThread(string name, TimeSpan? maxValidFor, TimeSpan? timeout); - - /// - /// Disposes the specified lock. - /// - void ReleaseLock(DistributedLock @lock); + IDistributedLock AcquireLock(string name, TimeSpan? maxValidFor, TimeSpan? timeout); } public static class DistributedLockServiceExtensions { @@ -59,8 +34,8 @@ namespace Orchard.Tasks.Locking.Services { /// The maximum amount of time the lock is allowed. This is a safety net in case the caller fails to release the lock. If null is specified, the lock never expires until it's released by the owner. /// The acquired lock. /// Returns true if a lock was successfully acquired, false otherwise. - public static bool TryAcquireLockForMachine(this IDistributedLockService service, string name, TimeSpan? maxValidFor, out DistributedLock @lock) { - return service.TryAcquireLockForMachine(name, maxValidFor, null, out @lock); + public static bool TryAcquireLock(this IDistributedLockService service, string name, TimeSpan? maxValidFor, out IDistributedLock @lock) { + return service.TryAcquireLock(name, maxValidFor, TimeSpan.Zero, out @lock); } /// @@ -69,8 +44,8 @@ namespace Orchard.Tasks.Locking.Services { /// The name to use for the lock. /// The acquired lock. /// Returns true if a lock was successfully acquired, false otherwise. - public static bool TryAcquireLockForMachine(this IDistributedLockService service, string name, out DistributedLock @lock) { - return service.TryAcquireLockForMachine(name, null, null, out @lock); + public static bool TryAcquireLock(this IDistributedLockService service, string name, out IDistributedLock @lock) { + return service.TryAcquireLock(name, null, TimeSpan.Zero, out @lock); } /// @@ -80,8 +55,8 @@ namespace Orchard.Tasks.Locking.Services { /// The maximum amount of time the lock is allowed. This is a safety net in case the caller fails to release the lock. If null is specified, the lock never expires until it's released by the owner. /// Returns a lock. /// Throws a TimeoutException if no lock could be acquired in time. - public static DistributedLock AcquireLockForMachine(this IDistributedLockService service, string name, TimeSpan? maxValidFor) { - return service.AcquireLockForMachine(name, maxValidFor, null); + public static IDistributedLock AcquireLock(this IDistributedLockService service, string name, TimeSpan? maxValidFor) { + return service.AcquireLock(name, maxValidFor, null); } /// @@ -90,39 +65,8 @@ namespace Orchard.Tasks.Locking.Services { /// The name to use for the lock. /// Returns a lock. /// Throws a TimeoutException if no lock could be acquired in time. - public static DistributedLock AcquireLockForMachine(this IDistributedLockService service, string name) { - return service.AcquireLockForMachine(name, null, null); - } - - /// - /// Tries to acquire a lock on the specified name for the current thread. - /// - /// The name to use for the lock. - /// The maximum amount of time the lock is allowed. This is a safety net in case the caller fails to release the lock. If null is specified, the lock never expires until it's released by the owner. - /// The acquired lock. - /// Returns true if a lock was successfully acquired, false otherwise. - public static bool TryAcquireLockForThread(this IDistributedLockService service, string name, TimeSpan? maxValidFor, out DistributedLock @lock) { - return service.TryAcquireLockForThread(name, maxValidFor, null, out @lock); - } - - /// - /// Tries to acquire a lock on the specified name for the current thread. - /// - /// The name to use for the lock. - /// The acquired lock. - /// Returns true if a lock was successfully acquired, false otherwise. - public static bool TryAcquireLockForThread(this IDistributedLockService service, string name, out DistributedLock @lock) { - return service.TryAcquireLockForThread(name, null, null, out @lock); - } - - /// - /// Acquires a lock with the specified parameters for the current thread. - /// - /// The name to use for the lock. - /// Returns a lock. - /// Throws a TimeoutException if no lock could be acquired in time. - public static DistributedLock AcquireLockForThread(this IDistributedLockService service, string name) { - return service.AcquireLockForThread(name, null, null); + public static IDistributedLock AcquireLock(this IDistributedLockService service, string name) { + return service.AcquireLock(name, null, null); } } } \ No newline at end of file