Class: RecordCache::Dispatcher
- Inherits:
-
Object
- Object
- RecordCache::Dispatcher
- Defined in:
- lib/record_cache/dispatcher.rb
Overview
Every model that calls cache_records will receive an instance of this class accessible through <model>.record_cache
The dispatcher is responsible for dispatching queries, record_changes and invalidation calls to the appropriate cache strategies.
Class Method Summary collapse
-
.strategy_classes ⇒ Object
Retrieve all strategies ordered by fastest strategy first.
Instance Method Summary collapse
-
#[](attribute) ⇒ Object
Retrieve the caching strategy for the given attribute.
-
#fetch(query, &block) ⇒ Object
retrieve the record(s) based on the given query (check with cacheable?(query) first).
-
#initialize(base) ⇒ Dispatcher
constructor
A new instance of Dispatcher.
-
#invalidate(strategy, value = nil) ⇒ Object
Explicitly invalidate one or more records @param: strategy: the id of the strategy to invalidate (defaults to
:id
) @param: value: the value to send to the invalidate method of the chosen strategy. -
#parse(options) ⇒ Object
Parse the options provided to the cache_records method and create the appropriate cache strategies.
-
#record_change(record, action) ⇒ Object
Update the version store and the record store (used by callbacks).
Constructor Details
#initialize(base) ⇒ Dispatcher
Returns a new instance of Dispatcher.
18 19 20 21 |
# File 'lib/record_cache/dispatcher.rb', line 18 def initialize(base) @base = base @strategy_by_attribute = {} end |
Class Method Details
.strategy_classes ⇒ Object
Retrieve all strategies ordered by fastest strategy first.
Roll your own cache strategies by extending from RecordCache::Strategy::Base
, and registering it here RecordCache::Dispatcher.strategy_classes << MyStrategy
14 15 16 |
# File 'lib/record_cache/dispatcher.rb', line 14 def self.strategy_classes @strategy_classes ||= [RecordCache::Strategy::UniqueIndexCache, RecordCache::Strategy::FullTableCache, RecordCache::Strategy::IndexCache] end |
Instance Method Details
#[](attribute) ⇒ Object
Retrieve the caching strategy for the given attribute
38 39 40 |
# File 'lib/record_cache/dispatcher.rb', line 38 def [](attribute) @strategy_by_attribute[attribute] end |
#fetch(query, &block) ⇒ Object
retrieve the record(s) based on the given query (check with cacheable?(query) first)
43 44 45 46 |
# File 'lib/record_cache/dispatcher.rb', line 43 def fetch(query, &block) strategy = query && ordered_strategies.detect { |strategy| strategy.cacheable?(query) } strategy ? strategy.fetch(query) : yield end |
#invalidate(strategy, value = nil) ⇒ Object
Explicitly invalidate one or more records @param: strategy: the id of the strategy to invalidate (defaults to :id
) @param: value: the value to send to the invalidate method of the chosen strategy
61 62 63 64 65 |
# File 'lib/record_cache/dispatcher.rb', line 61 def invalidate(strategy, value = nil) (value = strategy; strategy = :id) unless strategy.is_a?(Symbol) # call the invalidate method of the chosen strategy @strategy_by_attribute[strategy].invalidate(value) if @strategy_by_attribute[strategy] end |
#parse(options) ⇒ Object
Parse the options provided to the cache_records method and create the appropriate cache strategies.
24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/record_cache/dispatcher.rb', line 24 def parse() # find the record store, possibly based on the :store option store = record_store(.delete(:store)) # dispatch the parse call to all known strategies Dispatcher.strategy_classes.map{ |klass| klass.parse(@base, store, ) }.flatten.compact.each do |strategy| raise "Multiple record cache definitions found for '#{strategy.attribute}' on #{@base.name}" if @strategy_by_attribute[strategy.attribute] # and keep track of all strategies @strategy_by_attribute[strategy.attribute] = strategy end # make sure the strategies are ordered again on next call to +ordered_strategies+ @ordered_strategies = nil end |
#record_change(record, action) ⇒ Object
Update the version store and the record store (used by callbacks)
51 52 53 54 55 56 |
# File 'lib/record_cache/dispatcher.rb', line 51 def record_change(record, action) # skip unless something has actually changed return if action == :update && record.previous_changes.empty? # dispatch the record change to all known strategies @strategy_by_attribute.values.each { |strategy| strategy.record_change(record, action) } end |