|
|
|
@ -7,6 +7,7 @@ |
|
|
|
|
|
|
|
using System; |
|
|
|
using System.IO; |
|
|
|
using System.Text; |
|
|
|
using System.Threading; |
|
|
|
using System.Threading.Tasks; |
|
|
|
using Orleans; |
|
|
|
@ -16,7 +17,8 @@ namespace Squidex.Infrastructure.Log |
|
|
|
{ |
|
|
|
public sealed class LockingLogStore : ILogStore |
|
|
|
{ |
|
|
|
private static readonly TimeSpan LockWaitingTime = TimeSpan.FromMinutes(10); |
|
|
|
private static readonly byte[] LockedText = Encoding.UTF8.GetBytes("Another process is currenty running, try it again later."); |
|
|
|
private static readonly TimeSpan LockWaitingTime = TimeSpan.FromMinutes(1); |
|
|
|
private readonly ILogStore inner; |
|
|
|
private readonly ILockGrain lockGrain; |
|
|
|
|
|
|
|
@ -30,12 +32,17 @@ namespace Squidex.Infrastructure.Log |
|
|
|
lockGrain = grainFactory.GetGrain<ILockGrain>(SingleGrain.Id); |
|
|
|
} |
|
|
|
|
|
|
|
public async Task ReadLogAsync(string key, DateTime from, DateTime to, Stream stream) |
|
|
|
public Task ReadLogAsync(string key, DateTime from, DateTime to, Stream stream) |
|
|
|
{ |
|
|
|
string releaseToken = null; |
|
|
|
return ReadLogAsync(key, from, to, stream, LockWaitingTime); |
|
|
|
} |
|
|
|
|
|
|
|
using (var cts = new CancellationTokenSource(LockWaitingTime)) |
|
|
|
public async Task ReadLogAsync(string key, DateTime from, DateTime to, Stream stream, TimeSpan lockTimeout) |
|
|
|
{ |
|
|
|
using (var cts = new CancellationTokenSource(lockTimeout)) |
|
|
|
{ |
|
|
|
string releaseToken = null; |
|
|
|
|
|
|
|
while (!cts.IsCancellationRequested) |
|
|
|
{ |
|
|
|
releaseToken = await lockGrain.AcquireLockAsync(key); |
|
|
|
@ -47,15 +54,22 @@ namespace Squidex.Infrastructure.Log |
|
|
|
|
|
|
|
await Task.Delay(2000); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
try |
|
|
|
{ |
|
|
|
await inner.ReadLogAsync(key, from, to, stream); |
|
|
|
} |
|
|
|
finally |
|
|
|
{ |
|
|
|
await lockGrain.ReleaseLockAsync(releaseToken); |
|
|
|
if (!cts.IsCancellationRequested) |
|
|
|
{ |
|
|
|
try |
|
|
|
{ |
|
|
|
await inner.ReadLogAsync(key, from, to, stream); |
|
|
|
} |
|
|
|
finally |
|
|
|
{ |
|
|
|
await lockGrain.ReleaseLockAsync(releaseToken); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
await stream.WriteAsync(LockedText, 0, LockedText.Length); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|