Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix Metric livelock by replacing potential infinate loop in MetricValuesBuffer.GetAndResetValue #2612

Merged
merged 10 commits into from
Jun 17, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public int NextFlushIndex
set { this.nextFlushIndex = value; }
}

protected abstract TValue InvalidValue { get; }

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int IncWriteIndex()
{
Expand Down Expand Up @@ -91,13 +93,18 @@ public TValue GetAndResetValue(int index)
while (this.IsInvalidValue(value))
{
spinWait.SpinOnce();

if (spinWait.Count % 100 == 0)
{
// In tests (including stress tests) we always finished wating before 100 cycles.
// However, this is a protection against en extreme case on a slow machine.
Task.Delay(10).ConfigureAwait(continueOnCapturedContext: false).GetAwaiter().GetResult();
}
else if (spinWait.Count > 10000)
{
// exceeded maximum spin count. Break out to avoid infinite loop.
TimothyMothra marked this conversation as resolved.
Show resolved Hide resolved
return this.InvalidValue;
TimothyMothra marked this conversation as resolved.
Show resolved Hide resolved
}

value = this.GetAndResetValueOnce(this.values, index);
}
Expand Down Expand Up @@ -127,6 +134,8 @@ public MetricValuesBuffer_Double(int capacity)
{
}

protected override double InvalidValue => double.NaN;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected override bool IsInvalidValue(double value)
{
Expand Down Expand Up @@ -162,6 +171,8 @@ public MetricValuesBuffer_Object(int capacity)
{
}

protected override object InvalidValue => null;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected override bool IsInvalidValue(object value)
{
Expand Down