FoundatioFx / Foundatio

Pluggable foundation blocks for building distributed apps.
Apache License 2.0
1.99k stars 244 forks source link

`InMemoryCacheClient` throws error in `DoMaintenanceAsync` #311

Closed pinkfloydx33 closed 2 months ago

pinkfloydx33 commented 2 months ago

I am running Foundatio 11.0.2. I am using a hybrid cache client (redis + in memory) as well as Queue and Distributed Cron jobs (if that matters).

I am noticing the following error in the logs.

[11:13:21 ERR]  Error trying to find expired cache items
System.ArgumentOutOfRangeException: The UTC time represented when the offset is applied must be between year 0 and 10,000. (Parameter 'offset')
   at System.DateTimeOffset.ValidateDate(DateTime dateTime, TimeSpan offset)
   at System.DateTimeOffset..ctor(DateTime dateTime)
   at System.DateTimeOffset.op_Implicit(DateTime dateTime)
   at Foundatio.Caching.InMemoryCacheClient.DoMaintenanceAsync() in /_/src/Foundatio/Caching/InMemoryCacheClient.cs:line 931

Here's line 931: https://github.com/FoundatioFx/Foundatio/blob/ad61485bf82e67d3298375595842c0d43490603f/src/Foundatio/Caching/InMemoryCacheClient.cs#L931

Note that this doesn't crash the application or anything like that, but it is a bit annoying and probably needs to be fixed.

pinkfloydx33 commented 2 months ago

I set a breakpoint per @ejsmith and here's the values at that line:

kvp.Value.LastAccessTicks = 638621018469854381 lastAccessMaximumTicks = 638621022184909277 lastAccessTimeIsInfrequent = true kvp.Value.ExpiresAt = {12/31/9999 11:59:59 PM} (DateTime) utcNow = {9/16/2024 4:50:18 PM +00:00} (DateTimeOffset) _timeProvider = SystemTimeProvider

So since ExpiresAt is a DateTime and utcNow is a DateTimeOffset the implicit conversion from DateTime to DateTimeOffset is invoked. In this case, ExpiresAt happens to be DateTime.MaxValue.

The problem is that ExpiresAt's DateTime.Kind is Unspecified which for the purposes of the DateTimeOffset(DateTime) constructor that the implicit conversion invokes is treated as Local. I am currently in EST so it tries to advance the UTC time by 4 hours which is greater than the maximum allowed value and throws during validation

niemyjski commented 2 months ago

Thanks for reporting! Any chance you could submit a test / and or pr fix for this

ejsmith commented 2 months ago

New 11.0.3 release out with a fix for this.