A simple, powerful pattern for caching data
- Cache step - data is cached in small buckets by time
- Break time range into small buckets
- Get cached values
- Caclulate uncached values
- Cache uncached values, except the current period
- Reduce step - group buckets and reduce
Results are cached automatically - no need to precompute values (the exact same method to query can be used to preheat the cache if necessary).
Since the current period is always calculated, results are real-time. 💥
class SearchesCount
include CacheReduce::Magic
def value(time_range)
Search.where(created_at: time_range).count
end
end
Count all searches
SearchesCount.all(time_range: time_range)
Count searches by day
SearchesCount.by_day(time_range: time_range)
Use the preload method for faster cache warming.
class NewUsersCount
include CacheReduce::Magic
def preload(time_range)
@users = User.group_by_hour(:created_at, range: time_range).count
end
def value(time_range)
@users[time_range.first]
end
end
And:
NewUsersCount.all(time_range: time_range)
NewUsersCount.by_day(time_range: time_range)
Reduce ids instead of numbers - great for creating funnels
class VisitorIds
include CacheReduce::Magic
def value(time_range)
Visit.where(created_at: time_range).uniq.pluck(:user_id)
end
def reduce(values)
values.flatten
end
end
Pass your own arguments
class EventCount
include CacheReduce::Magic
def initialize(name)
@name = name
end
def key
["event", @name]
end
def value(time_range)
Ahoy::Event.where(name: @name, time: time_range).count
end
end
Built-in methods
- all
- by_hour
- by_day
- by_week
- by_month
- by_year
Built-in operations
- sum
- flatten
Add this line to your application’s Gemfile:
gem 'cache_reduce'
Force recache [master]
SearchesCount.all(time_range: time_range, recache: true)
- more reducer methods -
by_week
,by_month
, etc. - custom cache period, not just hours
- more data stores
- better interface
- better readme
Everyone is encouraged to help improve this project. Here are a few ways you can help:
- Report bugs
- Fix bugs and submit pull requests
- Write, clarify, or fix documentation
- Suggest or add new features