[backend/queue] Fix QueueService race condition (properly this time)
While the previous fix was likely enough, there was still a razor-thin theoretical race condition remaining. This commit fixes said race condition, and simplifies some if statements across the file.
This commit is contained in:
parent
4690d5c1fb
commit
a845405c45
2 changed files with 14 additions and 9 deletions
|
@ -4,4 +4,10 @@ public class SemaphorePlus(int maxCount) : SemaphoreSlim(maxCount, maxCount)
|
||||||
{
|
{
|
||||||
private readonly int _maxCount = maxCount;
|
private readonly int _maxCount = maxCount;
|
||||||
public int ActiveCount => _maxCount - CurrentCount;
|
public int ActiveCount => _maxCount - CurrentCount;
|
||||||
|
|
||||||
|
public async Task WaitAndReleaseAsync(CancellationToken token)
|
||||||
|
{
|
||||||
|
await WaitAsync(token);
|
||||||
|
Release();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -188,24 +188,23 @@ public class PostgresJobQueue<T>(
|
||||||
await using var db = GetDbContext(scope);
|
await using var db = GetDbContext(scope);
|
||||||
|
|
||||||
var queuedCount = await db.GetJobQueuedCount(name, token);
|
var queuedCount = await db.GetJobQueuedCount(name, token);
|
||||||
var actualParallelism = Math.Min(parallelism - _semaphore.ActiveCount, queuedCount);
|
var actualParallelism = Math.Min(_semaphore.CurrentCount, queuedCount);
|
||||||
|
|
||||||
if (actualParallelism <= 0)
|
if (actualParallelism == 0)
|
||||||
{
|
{
|
||||||
await _queuedChannel.WaitAsync(token).SafeWaitAsync(queueToken);
|
if (_semaphore.CurrentCount == 0 && queuedCount > 0)
|
||||||
|
await _semaphore.WaitAndReleaseAsync(token).SafeWaitAsync(queueToken);
|
||||||
|
else
|
||||||
|
await _queuedChannel.WaitAsync(token).SafeWaitAsync(queueToken);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReSharper disable MethodSupportsCancellation
|
// ReSharper disable MethodSupportsCancellation
|
||||||
var queuedChannelCts = new CancellationTokenSource();
|
var queuedChannelCts = new CancellationTokenSource();
|
||||||
if (_semaphore.ActiveCount + queuedCount < parallelism)
|
if (_semaphore.CurrentCount - queuedCount > 0)
|
||||||
{
|
{
|
||||||
_ = _queuedChannel.WaitWithoutResetAsync()
|
_ = _queuedChannel.WaitWithoutResetAsync()
|
||||||
.ContinueWith(_ =>
|
.ContinueWith(_ => queuedChannelCts.Cancel())
|
||||||
{
|
|
||||||
if (_semaphore.ActiveCount < parallelism)
|
|
||||||
queuedChannelCts.Cancel();
|
|
||||||
})
|
|
||||||
.SafeWaitAsync(queueToken);
|
.SafeWaitAsync(queueToken);
|
||||||
}
|
}
|
||||||
// ReSharper restore MethodSupportsCancellation
|
// ReSharper restore MethodSupportsCancellation
|
||||||
|
|
Loading…
Add table
Reference in a new issue