-
Notifications
You must be signed in to change notification settings - Fork 3
Add caching without changing any call sites
Donald Dong edited this page Apr 24, 2021
·
6 revisions
Instead of building separate cached code paths or providing new API such as Product.fetch
, RedisMemo takes advantage of metaprogramming in Ruby and adds caching to existing code paths as annotation:
class Post < ApplicationRecord
extend RedisMemo::MemoizeMethod
def author_display_name
author.display_name
end
memoize_method :author_display_name do |post|
depends_on Post.where(id: post.id)
depends_on User.where(id: post.author_id)
end
end
Here are some of the motivations:
- Caching should be the default behavior, rather than a conscious choice each developer has to make every time; they might not even be aware of the existence of the cached code path.
- Cached and uncached code paths can diverge over time. Switching to the cached ones may require changing a ton of files; it’s not always possible to change all the call sites, since some of them could be used in some gem code.
- Separate code paths such as
Product.fetch
have other usability and compatibility issues with ActiveRecord. Learn more about those issues here.
- We’re aware of Shopify/identity_cache, a gem that also provides query caching with automatic cache invalidation. It documented the motivation for providing separate cached query code paths in its caveats. With RedisMemo, caching is still a deliberate decision: there are models and computations that would not benefit from caching. When caching does make sense, RedisMemo makes caching easy and robust.