Second level cache

Write Through and Read Through caching library inspired by CacheMoney and cache_fu, support ActiveRecord 4.

SecondLevelCache

Gem Version Dependency Status Build Status Code Climate

SecondLevelCache is a write-through and read-through caching library inspired by Cache Money and cache_fu, support ActiveRecord 4.

Read-Through: Queries by ID, like current_user.articles.find(params[:id]), will first look in cache store and then look in the database for the results of that query. If there is a cache miss, it will populate the cache.

Write-Through: As objects are created, updated, and deleted, all of the caches are automatically kept up-to-date and coherent.

Install

In your gem file:

gem "second_level_cache", "~> 2.0.0.rc1"

Usage

For example, cache User objects:

class User < ActiveRecord::Base
  acts_as_cached(:version => 1, :expires_in => 1.week)
end

Then it will fetch cached object in this situations:

User.find(1)
user.articles.find(1)
User.where(:status => 1).find(1)
article.user

Cache key:

user = User.find 1
user.second_level_cache_key  # We will get the key looks like "slc/user/1/0"

Expires cache:

user = User.find(1)
user.expire_second_level_cache

or expires cache using class method:

User.expire_second_level_cache(1)

Disable SecondLevelCache:

User.without_second_level_cache do
  user = User.find 1
  # ...
end

Only SELECT * query will be cached:

# this query will NOT be cached
User.select("id, name").find(1)

Notice:

# user and account's write_second_level_cache operation will invoke after the logger.
ActiveRecord::Base.transaction do
   user.save
   account.save
   Rails.logger.info "info"
end # <- Cache write 

# if you want to do something after user and account's write_second_level_cache operation, do this way:
ActiveRecord::Base.transaction do
   user.save
   account.save
end # <- Cache write 
Rails.logger.info "info"

Configure

In production env, we recommend to use Dalli as Rails cache store.

 config.cache_store = [:dalli_store, APP_CONFIG["memcached_host"], {:namespace => "ns", :compress => true}]

Tips:

SecondLevelCache.configure.cache_key_prefix = "slc1"
class User < ActiveRecord::Base
  acts_as_cached(:version => 2, :expires_in => 1.week)
end
# this will fetch from cache
user = User.fetch_by_uniq_key("hooopo", :nick_name)

# this also fetch from cache
user = User.fetch_by_uniq_key!("hooopo", :nick_name) # this will raise `ActiveRecord::RecordNotFound` Exception when nick name not exists.
Answer.includes(:question).limit(10).order("id DESC").each{|answer| answer.question.title}
Answer Load (0.2ms)  SELECT `answers`.* FROM `answers` ORDER BY id DESC LIMIT 10 # Only one SQL query and one Rails.cache.read_multi fetching operation.

Details for read_multi feature.

Contributors

License

MIT License

Donate

If you find my work useful and you want to encourage the development of more free resources, you can do it by donating... alipay