Q:

ServiceStack Ormlite caching entries aren't deleted after expiry

We are using serviceStack caching with OrmLite Provider (MySql). We noticed that when we create caching keys with expiry dates, the keys don’t get deleted after the expiry date comes. Instead, they get NULL values in the “ExpiryDate” column. Thus, resulting in strange values when we calculate Cache.GetTimeToLive(). 
Is this a bug in serviceStack or is in our key creating code ? We are using ServiceStack version (4.5.4) and OrmLite version (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;
        }

A:

I think we got to the bottom of this .. it was caused by a misuse to the caching APIs from our side .. we found API calls to "Increment" and "Decrement" APIs in different other places causing the keys (those who had exceeded expiry date) to be deleted (by internal call to validate method) and then recreated from scratch (but without expiry date) .. the solution was to call GetOrCreate before calling Increment/Decrement to make sure the key does in fact exist and if it doesn't, recreate it with a fresh expiry date value .. 

