ruby-on-railsrubymemcacheddalli

How to update expiration time in MemCached using Dalli?


I'm using Ruby on Rails (v3.2.13), Dalli (v2.6.4) and MemCached (v1.4.13).

I do caching like this:

    result = Rails.cache.fetch("test_key", :expires_in => 1.week) do
        get_data()    # slow call, result of which should be cached
    end

I want to update cache expiration date based on the data, since some of my data can be kept longer.

Right now the following code does the job:

    if keep_longer(result)
        Rails.cache.write("test_key", result, :expires_in => 6.months)
    end

I know that MemCached supports "touch" command that allows to update expiration date without sending the value. And I don't see how to use it through the Dalli gem. Is there a way to update expiration date without resending the result?

UPDATE:

    Rails.cache.dalli.touch('some_key', 24.hours)

This should work, but for me it doesn't. Does it work for you?

Here is small example you can try. After execution of the following code in the IRB

      dc = Dalli::Client.new("localhost:11211")
      dc.set("test_key", "test_value", 5.minutes)
      dc.set(     "key",      "value", 5.minutes)
      dc.touch(   "key",   10.minutes)

I'm checking the expiration dates using telnet:

telnet localhost 11211

Then given the correct slab_id and using "stats cachedump" command I obtain expiration times in seconds:

stats cachedump 1 0

ITEM key [9 b; 1375733492 s]
ITEM test_key [14 b; 1375905957 s]

Note that the expiration time of the key "key" points to the past. When I expect it to be 300 seconds later than "test_key" expiration time. Also I noticed that "key" expiration time is approximately 1 second before the MemCached server has started. Which probably indicates that this key has no expiration time. And in fact "key" doesn't get deleted in the near future.

Am I doing something wrong or it is a bug of Dalli/MemCached?


Solution

  • Dalli does support this - there's a touch method on Dalli::Client that does exactly what it says on the tin. Rails.cache returns a cache store rather than the underlying Dalli object so you need to do

    Rails.cache.dalli.touch('some_key', 24.hours)
    

    To bump the cache entry's expiry time by 24 hours (and of course memcache may decide to drop the entry anyway)