CachedUntil - Only reuse cached value within its own period, and no overflow for the last period
This commit is contained in:
1 parent
9b380aaa7d
commit
ce13d92371
2 files changed
+48
-9
No files matched your search
@@ -88,6 +88,7 @@ namespace NLog.LayoutRenderers.Wrappers
|
|||||||
private string? _renderedCacheKey;
|
private string? _renderedCacheKey;
|
||||||
private DateTime _cachedValueExpires;
|
private DateTime _cachedValueExpires;
|
||||||
private TimeSpan? _cachedValueTimeout;
|
private TimeSpan? _cachedValueTimeout;
|
||||||
|
private DateTime _cachedValuePeriodStart;
|
||||||
private DateTime _cachedValuePeriodEnd;
|
private DateTime _cachedValuePeriodEnd;
|
||||||
private CachedUntilOption _cachedUntil;
|
private CachedUntilOption _cachedUntil;
|
||||||
|
|
||||||
@@ -186,7 +187,7 @@ namespace NLog.LayoutRenderers.Wrappers
|
|||||||
if (_cachedValueTimeout.HasValue)
|
if (_cachedValueTimeout.HasValue)
|
||||||
_cachedValueExpires = logEvent.TimeStamp + _cachedValueTimeout.Value;
|
_cachedValueExpires = logEvent.TimeStamp + _cachedValueTimeout.Value;
|
||||||
if (_cachedUntil != CachedUntilOption.None)
|
if (_cachedUntil != CachedUntilOption.None)
|
||||||
_cachedValuePeriodEnd = CalculatePeriodEnd(_cachedUntil, logEvent.TimeStamp);
|
UpdateCachedValuePeriod(logEvent.TimeStamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -207,20 +208,18 @@ namespace NLog.LayoutRenderers.Wrappers
|
|||||||
if (_cachedValueTimeout.HasValue && logEvent.TimeStamp > _cachedValueExpires)
|
if (_cachedValueTimeout.HasValue && logEvent.TimeStamp > _cachedValueExpires)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (_cachedUntil != CachedUntilOption.None && logEvent.TimeStamp >= _cachedValuePeriodEnd)
|
if (_cachedUntil != CachedUntilOption.None && (logEvent.TimeStamp < _cachedValuePeriodStart || logEvent.TimeStamp > _cachedValuePeriodEnd))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return _cachedValue;
|
return _cachedValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DateTime CalculatePeriodEnd(CachedUntilOption cachedUntil, DateTime timeStamp)
|
private void UpdateCachedValuePeriod(DateTime timeStamp)
|
||||||
{
|
{
|
||||||
switch (cachedUntil)
|
var periodTicks = _cachedUntil == CachedUntilOption.DayChange ? TimeSpan.TicksPerDay : TimeSpan.TicksPerHour;
|
||||||
{
|
_cachedValuePeriodStart = new DateTime(timeStamp.Ticks - timeStamp.Ticks % periodTicks, timeStamp.Kind);
|
||||||
case CachedUntilOption.DayChange: return new DateTime(timeStamp.Year, timeStamp.Month, timeStamp.Day, 0, 0, 0, timeStamp.Kind).AddDays(1);
|
// Inclusive end, so the last period ends at DateTime.MaxValue without overflow
|
||||||
case CachedUntilOption.HourChange: return new DateTime(timeStamp.Year, timeStamp.Month, timeStamp.Day, timeStamp.Hour, 0, 0, timeStamp.Kind).AddHours(1);
|
_cachedValuePeriodEnd = _cachedValuePeriodStart.AddTicks(periodTicks - 1);
|
||||||
default: return DateTime.MaxValue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string? IStringValueRenderer.GetFormattedString(LogEventInfo logEvent) => Cached ? RenderInner(logEvent) : null;
|
string? IStringValueRenderer.GetFormattedString(LogEventInfo logEvent) => Cached ? RenderInner(logEvent) : null;
|
||||||
|
|||||||
@@ -152,5 +152,45 @@ namespace NLog.UnitTests.LayoutRenderers.Wrappers
|
|||||||
var s3 = l.Render(new LogEventInfo() { TimeStamp = timeStamp.AddHours(6.5) });
|
var s3 = l.Render(new LogEventInfo() { TimeStamp = timeStamp.AddHours(6.5) });
|
||||||
Assert.NotEqual(s2, s3);
|
Assert.NotEqual(s2, s3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CachedUntilHourChangeEarlierTimeStampTest()
|
||||||
|
{
|
||||||
|
SimpleLayout l = "${guid:cachedUntil=HourChange}";
|
||||||
|
var timeStamp = new DateTime(2021, 2, 27, 17, 30, 0);
|
||||||
|
var s1 = l.Render(new LogEventInfo() { TimeStamp = timeStamp });
|
||||||
|
var s2 = l.Render(new LogEventInfo() { TimeStamp = timeStamp.AddMinutes(30) });
|
||||||
|
Assert.NotEqual(s1, s2);
|
||||||
|
var s3 = l.Render(new LogEventInfo() { TimeStamp = timeStamp.AddMinutes(15) });
|
||||||
|
Assert.NotEqual(s2, s3);
|
||||||
|
var s4 = l.Render(new LogEventInfo() { TimeStamp = timeStamp.AddMinutes(-30) });
|
||||||
|
Assert.Equal(s3, s4);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CachedUntilDayChangeEarlierTimeStampTest()
|
||||||
|
{
|
||||||
|
SimpleLayout l = "${guid:cachedUntil=DayChange}";
|
||||||
|
var timeStamp = new DateTime(2021, 2, 27, 17, 30, 0);
|
||||||
|
var s1 = l.Render(new LogEventInfo() { TimeStamp = timeStamp });
|
||||||
|
var s2 = l.Render(new LogEventInfo() { TimeStamp = timeStamp.AddHours(7) });
|
||||||
|
Assert.NotEqual(s1, s2);
|
||||||
|
var s3 = l.Render(new LogEventInfo() { TimeStamp = timeStamp.AddHours(6) });
|
||||||
|
Assert.NotEqual(s2, s3);
|
||||||
|
var s4 = l.Render(new LogEventInfo() { TimeStamp = timeStamp.AddHours(-17.5) });
|
||||||
|
Assert.Equal(s3, s4);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("HourChange")]
|
||||||
|
[InlineData("DayChange")]
|
||||||
|
public void CachedUntilLastPeriodTest(string cachedUntil)
|
||||||
|
{
|
||||||
|
SimpleLayout l = "${guid:cachedUntil=" + cachedUntil + "}";
|
||||||
|
var s1 = l.Render(new LogEventInfo() { TimeStamp = DateTime.MaxValue.AddMinutes(-30) });
|
||||||
|
var s2 = l.Render(new LogEventInfo() { TimeStamp = DateTime.MaxValue });
|
||||||
|
Assert.NotEmpty(s1);
|
||||||
|
Assert.Equal(s1, s2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user