Question

I am trying to interact with the cache store in a Rails app using Dalli. I am doing just fragment caching and have set up my dev config like this:

#config.action_controller.perform_caching = true
config.cache_store = :dalli_store

So that it isn't caching everything. The fragment I'm interested in caching is like this:

<% cache("home_main", :expires_in => 1.minute) do %>
<div class='tabbed-content content-1'>
  <%=render :partial => 'shared/launch-main', :locals => { :locations => @locations } %>
</div>
<% end %>

When I go in and run

ruby-1.9.2-p290 :019 > Rails.cache.stats
ruby-1.9.2-p290 :019 > y _

I get:

conn_yields: '0'
 bytes: '17153'
 curr_items: '1'
 total_items: '5'
 evictions: '0'
 reclaimed: '0'

Now is there a way to get back that fragement cache? Or to see it? I tried:

Rails.cache.fetch('home_main')

but that isn't working. Is there a way for me to see a list of cache keys?

thx

edit #1

for @cpuguy83 - so clearly going to DB with 196ms :-(

Read fragment views/home_main (2.4ms)
Rendered index/homepage_launch_main.html.erb (2.8ms)
Completed 200 OK in 1623ms (Views: 11.5ms | ActiveRecord: 195.8ms)
Was it helpful?

Solution

Fragment caching prefixes the cache with your address and URL.... So your key ends up being something like:

localhost:3000/your/URL/cache_key

You can see what key it uses by looking at your dev logs.

Also, pulling the item out of the cache is done automatically with the call to cache in your view. When you load the page it is checking to see if the item in the cache is valid, if it is then it grabs it, if not it regenerates the HTML and stores it in your cache.

Also if you just want to read from the cache you should use Rails.cache.read, Rails.cache.fetch is generally to grab from the cache if the key is valid and if not write to the cache with the provided block.

So: Rails.cache.read your_cache_key will just read return whatever is stored with that cache key (if anything)

Fetch would be used like this:

Rails.cache.fetch your_cache_key do
  # Logic to generate items you want to cache
end

The call to <% cache @object do %> in your view is essentially a shortcut for Rails.cache.fetch

I would recommend changing your cache call to something like this:

<% cache ['home_main', @locations.order('updated_at DESC').first] do %>
    # your html here
<% end %>

In this case the cache key is based on the most recently updated location object. If a location is updated then the cache will miss on the next request and it will be re-generated. What cache is doing here is calling cache_key on your most recently updated location object. cache_key grabs the updated_at timestamp from your object and embeds that in the key used for storing your cached items.

Check out http://www.broadcastingadam.com/2012/07/advanced_caching_part_1-caching_strategies/ for a wonderful tutorial on caching. Also deals with really nice tricks for auto-expiring caches without the need of using time based cache expires or cache sweepers.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top