Ruby gem for lazy caching (in background)
Ruby gem for lazy caching (in background).
Currently supports:
Add this line to your application's Gemfile:
gem 'lazy_caching'
And then execute:
$ bundle
Or install it yourself as:
$ gem install lazy_caching
First, run lazy_caching config generator
$ rails generate lazy_caching:install
Open the file config/initializers/lazy_caching.rb. It should contain
LazyCaching.setup do |config|
# option `base` means NO background processing
config.processor = :delayed_job
# or :resque for Resque
# or :delayed_job for DJ
# or :sidekiq for Sidekiq
# You can also specify processors for different environments
# config.processor = {
# :development => :resque,
# :test => :base,
# :production => :delayed_job
# }
# You can specify logger
config.logger = Logger.new(STDOUT) # default value
# Or set
# config.logger = Rails.logger
# Or disable logging.
# config.logger = nil
end
Run DJ, Resque or Sidekiq workers.
You can use DSL like this
has_cached_attribute do
# Some DSL
end
DSL:
:base:delayed_job:resque:sidekiqSo, in your model simply write something like this
- Example for class attribute
class Shop < ActiveRecord::Base
include LazyCaching::ActiveRecordExtensions
# don't forget to include this module
has_cached_attribute do
name :names
type :class
result { pluck(:name) }
end
end
Shop.product_names.lazy_recache!
# and wait for background processing ....
Shop.product_names.cached
# => ["product1", "product2", "product3"]
- Example for instance attribute
class Profile < ActiveRecord::Base
include LazyCaching::ActiveRecordExtensions
has_many :followers
has_cached_attribute do
name :followers_counter
type :instance
result { followers.count }
end
end
p = Profile.first
p.followers_counter.lazy_recache!
# wait again ....
p.followers_counter.cached
# => 3 # or something else :)
In fact, when you define cached attribute using has_cachd_attribute method, you just define another method with the same name as cached attribute name. And when you call this method, you receieves an instance of LazyCaching::CachedAttribute class. This class has 4 base methods:
Product.product_names.tap do |p|
p.recache!
puts p.cached
end
You can specify default processor for each attribute like this:
has_cached_attribute do
name :names
type :class
processor :base # No background processing for this attribute.
result { pluck(:name) }
end
You can specify default value for cached attribute (if it's blank)
has_cached_attribute do
name :names
type :class
processor :base
result { pluck(:name) }
default ["product1", "product2"]
# or as a block
# default do
# ["product1", "product2"]
# end
end
Rails.cache.clear
Product.names.cached
# => ["product1", "product2"]
By default, each call of lazy_recache! checks, do we have a job with the same arguments in our queue. If it's true, then recache action will be blocked. But if you are sure that you need to recache your data again (twice), simpy call
Product.names.lazy_recache!(:force => true)
If you wan't to recache same attribute with different processor, pass paramater :processor to lazy_recache!
Product.names.lazy_recache!(:processor => :base)
This means that we have 3 levels of processor definition:
processor option in has_cached_attribute block):processor for lazy_recache! methodYou can combine different options as you wish!
git checkout -b my-new-feature)git commit -am 'Added some feature')git push origin my-new-feature)