Cacheable: a simple gem for caching methods in Ruby

Today we’re releasing a new gem that makes it easy to add caching to any Ruby code. It’s called cacheable!

The cacheable gem is an aspect-oriented, unobtrusive approach to caching. It turns this example code (taken from the Rails caching documentation):

class Product < ApplicationRecord
  def competing_price
    Rails.cache.fetch("#{cache_key}/competing_price") do
      Competitor::API.find_price(id)
    end
  end
end

Into this:

class Product < ApplicationRecord
  cacheable :competing_price

  def competing_price
    Competitor::API.find_price(id)
  end
end

And to help handle more complex caching scenarios, cacheable includes many more powerful features too: conditional caching, dynamic cache key generation, utility methods to skip and clear the cache, and more.

You can read the full story behind cacheable here, and start using cacheable by reading our docs on GitHub. Building cacheable enabled us to clean up Splitwise’s balance-caching code significantly, and it helped us solve several hard-to-diagnose bugs in the process!

Why cacheable?

At Splitwise, we found ourselves writing the same crufty caching code over and over again. Wrapping our code in caching blocks made it harder to read and more difficult to test. And any time that we wanted to perform more complex logic in one of our cached methods – for example, conditional caching – it would cause that method to balloon in size and complexity.

We decided to step back and reexamine our first principles – specifically, the single responsibility principle. We realized that a method like Product#competing_price shouldn’t be responsible for caching at all! We began to think, “What if we could extract the caching logic from our cached methods? What if each method was only responsible for its own logic, and the caching could be tested and built separately?”

Enter aspect-oriented programming (AOP). By switching to an aspect-oriented approach, we were able to build a caching framework that was easier to use, easier to test, and MUCH more reliable across the various parts of our codebase.

Try it yourself!

We’ve been using cacheable in production on Splitwise for many months, and today we’re excited to share it with the rest of the world 🙂 Check out our docs on GitHub for complete instructions on how to start using cacheable in your own Ruby app. We look forward to making additional improvements, and we welcome enhancements and pull requests from the Ruby community!

Published by

Ryan Laughlin

CTO @ Splitwise, the app that makes sharing expenses easy.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s