Module: Components::Caching

Included in:
Base
Defined in:
lib/components/caching.rb

Overview

Component caching is very fine-grained - a component is cached based on all of its arguments. Any more or less would result in inaccurate cache hits.

Howto

First, configure fragment caching on ActionController. That cache store will be used for components as well.

Second, decide which component actions should be cached. Some components cache better than others due to the nature of the arguments passed.

For each component you wish to cache, add ‘cache :my_action` after you define the action itself. This is necessary because your action will be wrapped with another method - :my_action_with_caching. This enables component actions to be cached no matter how they are called.

Example

class UserComponent < Components::Base
  def show(user_id)
    @user = User.find(user_id)
    render
  end
  cache :show
end

Expiration

I know of three general methods to expire caches:

  • TTL: expires a cache after some number of seconds. This works well for content that is hit frequently but can stand to be a bit stale at times.

  • Versioning: caches are never actually expired, rather, they are eventually ignored when all new cache requests are for a new version. This only works with cache stores that have some kind of limited cache space, otherwise cache consumption will go through the metaphorical roof.

  • Direct Expiration: caches are expired by name. This does not work when cache keys have variable elements, or when the complete list of cache keys is not available or a brute-force regular expression approach.

Of those three, direct expiration is not a viable option due to the variable nature of component cache keys. And since both of the remaining methods are best supported by some variation of memcache, that is the officially recommended cache store.

TTL Expiration

If you are using Rails’ :mem_cache_store for fragments, then you can set up TTL-style expiration by specifying an :expires_in option, like so:

class UserComponent < Components::Base
  def show(user_id)
    @user = User.find(user_id)
    render
  end
  cache :show, :expires_in => 15.minutes
end

Versioned Expiration

Maintaining and incrementing version numbers may be implemented any number of ways. To use the version numbers, though, you can specify a :version option, which may either name a method (use a Symbol) or provide a proc. In either case, the method or proc should receive all of the same arguments as the action itself, and should return the version string.

class UserComponent < Components::Base
  def show(user_id)
    @user = User.find(user_id)
    render
  end
  cache :show, :version => :show_cache_version

  protected

  def show_cache_version(user_id)
    # you may want to find your version from a model object, from memcache, or whereever.
    Version.for("users/show", user_id)
  end
end

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Class Method Details

.included(base) ⇒ Object

:nodoc:



82
83
84
85
86
# File 'lib/components/caching.rb', line 82

def self.included(base) #:nodoc:
  base.class_eval do
    extend ClassMethods
  end
end