Skip to content

Commit 7a9bc84

Browse files
Make TestDistributedLockProvider thread-safe with Interlocked operations (#7163)
* Initial plan * Make TestDistributedLockProvider thread-safe using Interlocked operations Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: sfmskywalker <938393+sfmskywalker@users.noreply.github.com>
1 parent 1cca430 commit 7a9bc84

1 file changed

Lines changed: 33 additions & 17 deletions

File tree

test/component/Elsa.Workflows.ComponentTests/Scenarios/DistributedLockResilience/Mocks/TestDistributedLockProvider.cs

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ public class TestDistributedLockProvider(IDistributedLockProvider innerProvider)
1515
public int AcquisitionAttemptCount => _acquisitionAttemptCount;
1616
public int ReleaseAttemptCount => _releaseAttemptCount;
1717

18-
public void FailAcquisitionOnce() => _acquisitionFailuresRemaining = 1;
19-
public void FailAcquisitionTimes(int count) => _acquisitionFailuresRemaining = count;
20-
public void FailReleaseOnce() => _releaseFailuresRemaining = 1;
18+
public void FailAcquisitionOnce() => Interlocked.Exchange(ref _acquisitionFailuresRemaining, 1);
19+
public void FailAcquisitionTimes(int count) => Interlocked.Exchange(ref _acquisitionFailuresRemaining, count);
20+
public void FailReleaseOnce() => Interlocked.Exchange(ref _releaseFailuresRemaining, 1);
2121

2222
public void Reset()
2323
{
24-
_acquisitionFailuresRemaining = 0;
25-
_releaseFailuresRemaining = 0;
26-
_acquisitionAttemptCount = 0;
27-
_releaseAttemptCount = 0;
24+
Interlocked.Exchange(ref _acquisitionFailuresRemaining, 0);
25+
Interlocked.Exchange(ref _releaseFailuresRemaining, 0);
26+
Interlocked.Exchange(ref _acquisitionAttemptCount, 0);
27+
Interlocked.Exchange(ref _releaseAttemptCount, 0);
2828
}
2929

3030
public IDistributedLock CreateLock(string name)
@@ -34,21 +34,37 @@ public IDistributedLock CreateLock(string name)
3434

3535
internal bool ShouldFailAcquisition()
3636
{
37-
_acquisitionAttemptCount++;
38-
if (_acquisitionFailuresRemaining <= 0)
39-
return false;
40-
41-
_acquisitionFailuresRemaining--;
37+
Interlocked.Increment(ref _acquisitionAttemptCount);
38+
39+
// Atomically decrement if > 0 using compare-exchange loop
40+
int currentValue, newValue;
41+
do
42+
{
43+
currentValue = Volatile.Read(ref _acquisitionFailuresRemaining);
44+
if (currentValue <= 0)
45+
return false;
46+
47+
newValue = currentValue - 1;
48+
} while (Interlocked.CompareExchange(ref _acquisitionFailuresRemaining, newValue, currentValue) != currentValue);
49+
4250
return true;
4351
}
4452

4553
internal bool ShouldFailRelease()
4654
{
47-
_releaseAttemptCount++;
48-
if (_releaseFailuresRemaining <= 0)
49-
return false;
50-
51-
_releaseFailuresRemaining--;
55+
Interlocked.Increment(ref _releaseAttemptCount);
56+
57+
// Atomically decrement if > 0 using compare-exchange loop
58+
int currentValue, newValue;
59+
do
60+
{
61+
currentValue = Volatile.Read(ref _releaseFailuresRemaining);
62+
if (currentValue <= 0)
63+
return false;
64+
65+
newValue = currentValue - 1;
66+
} while (Interlocked.CompareExchange(ref _releaseFailuresRemaining, newValue, currentValue) != currentValue);
67+
5268
return true;
5369
}
5470
}

0 commit comments

Comments
 (0)