我们在 OrmLite Provider (MySql) 中使用 serviceStack 缓存。我们注意到,当我们创建具有到期日期的缓存键时,键不会在到期日期到来后被删除。相反,他们在“ExpiryDate”列中得到 NULL 值。因此,当我们计算 Cache.GetTimeToLive() 时会产生奇怪的值。
这是 serviceStack 中的错误还是我们的 key 创建代码中的错误?我们使用的是ServiceStack版本(4.5.4)和OrmLite版本(4.5.4)
IAppSettings appSettings = new AppSettings();
var userConsultsPerHourLimit = appSettings.Get<int>("throttling:consultations:requests:perHourLimit");
var userConsultsPerDayLimit = appSettings.Get<int>("throttling:consultations:requests:perDayLimit");
var userConsultsPerMonthLimit = appSettings.Get<int>("throttling:consultations:requests:perMonthLimit");
var userConsultsMadePerHour = Cache.GetOrCreate<int>(UserConsultPerHourCacheKey, TimeSpan.FromHours(1), () => { return 0; });
var userConsultsMadePerDay = Cache.GetOrCreate<int>(UserConsultPerDayCacheKey, TimeSpan.FromDays(1), () => { return 0; });
var userConsultsMadePerMonth = Cache.GetOrCreate<int>(UserConsultPerMonthCacheKey, (new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, 1).AddMonths(1).AddDays(-1) - DateTime.UtcNow), () => { return 0; });
string retryAfter = System.Threading.Thread.CurrentThread.CurrentCulture.Name == "ar-SA" ? "يوم" : "day";
bool shouldThrottleRequest = false;
bool didExceedMonthlyLimit = false;
if (userConsultsMadePerHour >= userConsultsPerHourLimit)
{
shouldThrottleRequest = true;
TimeSpan? timeToLive = Cache.GetTimeToLive(UserConsultPerHourCacheKey);
if (timeToLive.HasValue)
retryAfter = Humanizer.TimeSpanHumanizeExtensions.Humanize(timeToLive.Value, 2, System.Threading.Thread.CurrentThread.CurrentUICulture);
}
else if (userConsultsMadePerDay >= userConsultsPerDayLimit)
{
shouldThrottleRequest = true;
TimeSpan? timeToLive = Cache.GetTimeToLive(UserConsultPerDayCacheKey);
if (timeToLive.HasValue)
retryAfter = Humanizer.TimeSpanHumanizeExtensions.Humanize(timeToLive.Value, 2, System.Threading.Thread.CurrentThread.CurrentUICulture);
}
else if (userConsultsMadePerMonth >= userConsultsPerMonthLimit)
{
shouldThrottleRequest = true;
TimeSpan? timeToLive = Cache.GetTimeToLive(UserConsultPerMonthCacheKey);
if (timeToLive.HasValue)
retryAfter = Humanizer.TimeSpanHumanizeExtensions.Humanize(timeToLive.Value, 3, System.Threading.Thread.CurrentThread.CurrentUICulture);
didExceedMonthlyLimit = true;
}
最佳答案
这是 working as expected在最新版本的 ServiceStack 中,在获取过期的缓存条目后删除该行:
var ormliteCache = Cache as OrmLiteCacheClient;
var key = "int:key";
var value = Cache.GetOrCreate(key, TimeSpan.FromMilliseconds(100), () => 1);
var ttl = Cache.GetTimeToLive(key);
using (var db = ormliteCache.DbFactory.OpenDbConnection())
{
var row = db.SingleById<CacheEntry>(key);
Assert.That(row, Is.Not.Null);
Assert.That(row.ExpiryDate, Is.Not.Null);
}
Assert.That(value, Is.EqualTo(1));
Assert.That(ttl.Value.TotalMilliseconds, Is.GreaterThan(0));
Thread.Sleep(200);
value = Cache.Get<int>(key);
ttl = Cache.GetTimeToLive(key);
Assert.That(value, Is.EqualTo(0));
Assert.That(ttl, Is.Null);
using (var db = ormliteCache.DbFactory.OpenDbConnection())
{
var row = db.SingleById<CacheEntry>(key);
Assert.That(row, Is.Null);
}
We noticed that when we create caching keys with expiry dates, the keys don’t get deleted after the expiry date comes.
RDBMS 不会按日期自动使缓存条目过期,但在解析缓存条目时,OrmLiteCacheClient
会自动删除过期的条目(如上所示),因此它永远不会返回过期的条目.
Instead, they get NULL values in the “ExpiryDate” column.
这是不可能的。 ExpiryDate
仅在创建或替换现有条目时填充,它在过期时永远不会设置为 null。当条目过期时,整个条目将被删除。
关于mysql - ServiceStack Ormlite 缓存条目在到期后不会被删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44524688/