mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Added thread synchronization.
This ensures that only one thread at a time can acquire a lock.
This commit is contained in:
@@ -1,10 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Orchard.Environment;
|
using Orchard.Environment;
|
||||||
using Orchard.Logging;
|
using Orchard.Logging;
|
||||||
|
|
||||||
namespace Orchard.Tasks.Locking {
|
namespace Orchard.Tasks.Locking {
|
||||||
public class DistributedLockService : IDistributedLockService {
|
public class DistributedLockService : IDistributedLockService {
|
||||||
|
private static readonly object _semaphore = new object();
|
||||||
private readonly Work<IDistributedLock> _lock;
|
private readonly Work<IDistributedLock> _lock;
|
||||||
private readonly IMachineNameProvider _machineNameProvider;
|
private readonly IMachineNameProvider _machineNameProvider;
|
||||||
|
|
||||||
@@ -17,22 +19,35 @@ namespace Orchard.Tasks.Locking {
|
|||||||
public ILogger Logger { get; set; }
|
public ILogger Logger { get; set; }
|
||||||
|
|
||||||
public bool TryAcquireLock(string name, TimeSpan maxLifetime, TimeSpan timeout, out IDistributedLock @lock) {
|
public bool TryAcquireLock(string name, TimeSpan maxLifetime, TimeSpan timeout, out IDistributedLock @lock) {
|
||||||
var waitedTime = TimeSpan.Zero;
|
|
||||||
var waitTime = TimeSpan.FromMilliseconds(timeout.TotalMilliseconds / 10);
|
|
||||||
@lock = _lock.Value;
|
|
||||||
bool acquired;
|
|
||||||
|
|
||||||
while (!(acquired = @lock.TryAcquire(name, maxLifetime)) && waitedTime < timeout) {
|
|
||||||
Task.Delay(timeout).ContinueWith(t => {
|
|
||||||
waitedTime += waitTime;
|
|
||||||
}).Wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
var machineName = _machineNameProvider.GetMachineName();
|
var machineName = _machineNameProvider.GetMachineName();
|
||||||
|
@lock = _lock.Value;
|
||||||
|
|
||||||
if (acquired) {
|
if (Monitor.TryEnter(_semaphore)) {
|
||||||
Logger.Debug(String.Format("Successfully acquired a lock named {0} on machine {1}.", name, machineName));
|
try {
|
||||||
return true;
|
var waitedTime = TimeSpan.Zero;
|
||||||
|
var waitTime = TimeSpan.FromMilliseconds(timeout.TotalMilliseconds / 10);
|
||||||
|
bool acquired;
|
||||||
|
|
||||||
|
while (!(acquired = @lock.TryAcquire(name, maxLifetime)) && waitedTime < timeout) {
|
||||||
|
Task.Delay(timeout).ContinueWith(t => {
|
||||||
|
waitedTime += waitTime;
|
||||||
|
}).Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (acquired) {
|
||||||
|
Logger.Debug(String.Format("Successfully acquired a lock named {0} on machine {1}.", name, machineName));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
Logger.Error(ex, "Error during acquire lock.");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
Monitor.Exit(_semaphore);
|
||||||
|
Logger.Debug("Ending sweep.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Debug(String.Format("Failed to acquire a lock named {0} on machine {1}.", name, machineName));
|
Logger.Debug(String.Format("Failed to acquire a lock named {0} on machine {1}.", name, machineName));
|
||||||
|
|||||||
Reference in New Issue
Block a user