Caching strategies in rails 4

Post on 24-Jun-2015

464 views 1 download

Tags:

Transcript of Caching strategies in rails 4

Key-based cache expiration in

Rails 4...or Rails 3 with a dependency

Wednesday, July 31, 13

Building Blocks (ActiveRecord::Base)

@product.cache_key

=> “products/1281-20130717091609”

“#{name}/#{id}-#{timestamp}”

Wednesday, July 31, 13

Building Blocks (ActionView::Helpers::CacheHelper)

- cache @product do %h1= @product.name = image_tag @product.image.url

Wednesday, July 31, 13

Write fragment views/products/1-20130728191246157664000

(“views/#{cache_key}”)

- cache @product do %h1= @product.name = image_tag @product.image.url

Wednesday, July 31, 13

You can compose fragment keys, too...

- cache [@product, “reviews”] do %h1= @product.name = image_tag @product.image.url

Write fragment views/products/1-20130728191246157664000/reviews

“views/#{cache_key}/#{extra_args.join(‘/’)}”

Wednesday, July 31, 13

“But what if I change a template?”

Wednesday, July 31, 13

Rails.cache.clear

Wednesday, July 31, 13

“But what if I deploy 5 times a day”

Wednesday, July 31, 13

sucks

Wednesday, July 31, 13

Just kidding!™

Wednesday, July 31, 13

# Gemfile

gem ‘pg’

gem ‘cache_digests’

gem ‘haml-rails’

gem ‘cancan’

# ...

(Rails 3 only – built into actionpack 4)

Wednesday, July 31, 13

Write fragment views/products/1-20130728191246157664000/3b2b93d56d331aa7a1bf9267a656d3c9

(“views/#{cache_key}/#{template_digest}”)

- cache @product do %h1= @product.name = image_tag @product.image.url

With cache_digests...

note: template_digest is a digest of the current template and all of it’s dependencies (more on that later)Wednesday, July 31, 13

Cache digest for products/_product.html: 42eb891316f21e68798de5d5aa8021d5

Read fragment views/products/1-20130728191246157664000/42eb891316f21e68798de5d5aa8021d5

Write fragment views/products/1-20130728191246157664000/42eb891316f21e68798de5d5aa8021d5

- cache @product do %h1= @product.name - # image_tag @product.image.url

...change the template

Wednesday, July 31, 13

template change-> new digest

-> new fragment key-> busted cache!

Wednesday, July 31, 13

And we didn’t have to do anything!

Wednesday, July 31, 13

“Russian doll” caching strategythe notorious

Wednesday, July 31, 13

class Product < ActiveRecord::Base has_many :reviewsend

class Review < ActiveRecord::Base belongs_to :product, touch: trueend

Product’s cache key now dependent on its reviews

Wednesday, July 31, 13

@review.update!(rating: 3)

@review.product’s key gets bumped as well

Wednesday, July 31, 13

the “russian doll”...

# products/index.haml

- cache [@products.order(“updated_at ASC”).last, “index”] do%ul.products

- @products.each do |product| = render product

# products/_product.haml

- cache product do %li.product %h1= product.name %h2 Reviews! %ul.reviews - product.reviews.each do |review| = render review

# reviews/_review.haml

- cache review do %li.review %h4= “#{review.rating} stars!” %p.content= review.content

Wednesday, July 31, 13

the “russian doll”...index

product

reviews list

review

review

review

Wednesday, July 31, 13

@product.reviews.last.update!(rating: 5)

Last review will get re-rendered (and cached) and container (review list) will get busted -

but when list re-renders all but this last review can be fetched from cache.

Wednesday, July 31, 13

View the template dependency tree...

$ rake cache_digests:nested_dependencies TEMPLATE=your/template/name

ex:

and rake task for Rails 4: https://gist.github.com/nzaillian/6127613

Wednesday, July 31, 13

Explicit dependencyIf Rails just can’t seem to figure out your dependency you can declare an explicit dependency in a template by including a comment with a special form:

- # Template Dependency: reviews/summary

(...but you shouldn’t ever have to do this)

Wednesday, July 31, 13

Other Resourceshttps://github.com/rails/cache_digests

http://37signals.com/svn/posts/3113-how-key-based-cache-expiration-works

http://www.youtube.com/watch?v=yhseQP52yIY&t=0:39:39

must watch! (DHH’s Railsconf 2013 outline of key-based caching)

http://api.rubyonrails.org/classes/ActionView/Helpers/CacheHelper.html

Wednesday, July 31, 13