Class: RecordCache::Dispatcher

Inherits:
Object
  • Object
show all
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.

Instance Method Summary collapse

Constructor Details

#initialize(base) ⇒ Dispatcher

Returns a new instance of Dispatcher.



9
10
11
12
13
14
# File 'lib/record_cache/dispatcher.rb', line 9

def initialize(base)
  @base = base
  @strategy_by_id = {}
  # all strategies except :request_cache, with the :id stategy first (most used and best performing)
  @ordered_strategies = []
end

Instance Method Details

#[](strategy_id) ⇒ Object

Retrieve the caching strategy for the given attribute



31
32
33
# File 'lib/record_cache/dispatcher.rb', line 31

def [](strategy_id)
  @strategy_by_id[strategy_id]
end

#cacheable?(query) ⇒ Boolean

Can the cache retrieve the records based on this query?

Returns:

  • (Boolean)


36
37
38
# File 'lib/record_cache/dispatcher.rb', line 36

def cacheable?(query)
  !!first_cacheable_strategy(query)
end

#fetch(query) ⇒ Object

retrieve the record(s) with the given id(s) as an array



41
42
43
44
45
46
47
48
49
# File 'lib/record_cache/dispatcher.rb', line 41

def fetch(query)
  if request_cache
    # cache the query in the request
    request_cache.fetch(query) { fetch_from_first_cacheable_strategy(query) }
  else
    # fetch the results using the first strategy that accepts this query
    fetch_from_first_cacheable_strategy(query)
  end
end

#invalidate(strategy, value = nil) ⇒ Object

Explicitly invalidate one or more records @param: strategy: the strategy to invalidate @param: value: the value to send to the invalidate method of the chosen strategy



64
65
66
67
68
69
70
# File 'lib/record_cache/dispatcher.rb', line 64

def invalidate(strategy, value = nil)
  (value = strategy; strategy = :id) unless strategy.is_a?(Symbol)
  # call the invalidate method of the chosen strategy
  @strategy_by_id[strategy].invalidate(value) if @strategy_by_id[strategy]
  # always clear the request cache if invalidate is explicitly called for this class
  request_cache.try(:invalidate, value)
end

#record_change(record, action) ⇒ Object

Update the version store and the record store (used by callbacks)

Parameters:

  • record

    the updated record (possibly with

  • action

    one of :create, :update or :destroy



54
55
56
57
58
59
# File 'lib/record_cache/dispatcher.rb', line 54

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_id.values.each { |strategy| strategy.record_change(record, action) }
end

#register(strategy_id, strategy_klass, record_store, options) ⇒ Object

Register a cache strategy for this model



17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/record_cache/dispatcher.rb', line 17

def register(strategy_id, strategy_klass, record_store, options)
  if @strategy_by_id.key?(strategy_id)
    return if strategy_id == :id
    raise "Multiple record cache definitions found for '#{strategy_id}' on #{@base.name}"
  end
  # Instantiate the cache strategy
  strategy = strategy_klass.new(@base, strategy_id, record_store, options)
  # Keep track of all strategies for this model
  @strategy_by_id[strategy_id] = strategy
  # Note that the :id strategy is always registered first
  @ordered_strategies << strategy unless strategy_id == :request_cache
end