mysql - ServiceStack Ormlite 缓存条目在到期后不会被删除

标签 mysql caching servicestack ormlite-servicestack

我们在 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/

相关文章:

servicestack - 我可以让它在服务堆栈上自定义我的 GET 请求的显示吗?

c# - 为什么在 VIsual Studio 2017 中使用 ServiceStack 时出现错误 "The type ' Return< >' is defined in an assembly that is not referenced"

mysql - 从连接表中获取 child 的总记录

mysql - 如何多次查询包含一个字母的字符串?

asp.net - 无需在系统上安装 MySQL ODBC 5.1 驱动程序即可运行 .net 网站

image - 使用任意 QML 项作为缓存图像源

javascript - 如何从 php 变量中获取值到我们的 javascript 文件中?

optimization - 将代码保存在 L1 缓存中

java - Guava Cache CacheLoader.refreshAfterWrite() 和 .expireAfterAccess() 结合使用

c# - ServiceStack 是如何处理并发调用的?