Created
September 19, 2014 19:28
-
-
Save darrencauthon/1510f6de75a64c9b6d7c to your computer and use it in GitHub Desktop.
Surgical caching
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module CachingLayer | |
class << self | |
def method_missing meth, *args, &block | |
action = meth.to_s.split('_')[0].to_sym | |
object_id = args[0].is_a?(ActiveRecord::Base) ? args[0].id : args[0] | |
object_type = meth.to_s.sub("#{action}_", '').to_sym | |
case action | |
when :find | |
block = -> { object_type.to_s.classify.constantize.where(id: object_id).first } if block.nil? | |
fetch_object object_type, object_id, &block | |
when :bust | |
bust_object object_type, object_id | |
end | |
end | |
end | |
def self.register_cached_item_and_fetch key, options = {}, &block | |
register_cached_item key, options, &block | |
fetch key | |
end | |
def self.register_cached_item key, options = {}, &block | |
@cached_items ||= {} | |
exists = @cached_items[key].present? | |
@cached_items[key] = { block: block, options: options } | |
if exists | |
if @cached_items[key][:options][:related_to_objects] | |
@cached_items[key][:options][:related_to_objects].each do |object_type| | |
tie_object_type_with_key object_type, key | |
end | |
end | |
else | |
bust key | |
end | |
end | |
def self.tie_object_type_with_key object_type, key | |
cache_keys_for(object_type) << key | |
end | |
def self.cache_keys_for object_type | |
@cache_busters ||= {} | |
@cache_busters[object_type] ||= [] | |
end | |
def self.cache_key_for object_type, object_id | |
"fast_#{object_type}_#{object_id}" | |
end | |
def self.fetch_object object_type, object_id, &block | |
fetch(cache_key_for(object_type, object_id), &block) | |
end | |
def self.fetch key, &block | |
@cached_items ||= {} | |
block_to_run = if @cached_items[key] | |
@cached_items[key][:block] | |
else | |
block | |
end | |
enabled? ? Rails.cache.fetch(key, &block_to_run) : block_to_run.call | |
end | |
def self.bust_object object_type, object_id | |
bust cache_key_for(object_type, object_id) | |
cache_keys_for(object_type).each { |k| bust k } | |
end | |
def self.bust key | |
Rails.cache.delete key | |
end | |
def self.enabled? | |
true # ? | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ComplicatedController < ApplicationController | |
def list | |
#render json: a_buncha_complicated_processes | |
data = CachingLayer.register_cached_item_and_fetch('a buncha complicated processes', { related_to_objects: [:form] }) do | |
a_buncha_complicated_processes | |
end | |
render json: data | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Form < ActiveRecord::Base | |
after_save { |f| CachingLayer.bust_form f } | |
after_destroy { |f| CachingLayer.bust_form f } | |
def self.cached_find id | |
CachingLayer.find_form id | |
end | |
def self.cached_all | |
CachingLayer.register_cached_item_and_fetch('forms_all', { related_to_objects: [:form] }) { Form.all } | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If I call
The processes and items tied to "form" will be invalidated.