class InfoparkComponentCache::ComponentCache

@author Tomasz Przedmojski <tomasz.przedmojski@infopark.de> This class provides user-level access to component cache.

@example Do some expensive computation on a page

InfoparkComponentCache::ComponentCache.new(@obj, 'processed_body', :page => 14) do
  expensive_process_body @obj.body
end

By default ComponentCache comes with a set of Guards, i.e. classes that check the consistency of cache and invalidate it, should it be neccesary. @see ComponentCache#initialize

Attributes

component[R]
guards[R]

Public Class Methods

new(obj, name, params = {}, guards = []) click to toggle source

First three parameters are used to construct the component @see Component

@param [Array<Class>, Array<Hash>] guards list of guard

classes used when deciding whether cache is valid
when left empty the default set is used:
@see Guard::ValuePresent
@see Guard::LastChanged
@see Guard::ObjCount
# File lib/infopark_component_cache/component_cache.rb, line 27
def initialize(obj, name, params = {}, guards = [])
  @component = Component.new(obj, name, params)
  @guards = if guards.empty?
              [
                Guards::ValuePresent.new(@component),
                Guards::LastChanged.new(@component),
                Guards::ObjCount.new(@component),
                Guards::ValidFrom.new(@component),
                Guards::ValidUntil.new(@component)
              ]
            else
              guards.map do |klass_or_hash|
                if klass_or_hash.kind_of?(Hash)
                  klass = klass_or_hash.delete(:guard)
                  klass.new(@component, klass_or_hash)
                else
                  klass = klass_or_hash
                  klass.new(@component)
                end
              end
            end
end

Public Instance Methods

cache() click to toggle source

@private @return [CacheStorage] instance of CacheStorage to use

# File lib/infopark_component_cache/component_cache.rb, line 95
def cache
  CacheStorage.instance
end
ensure_consistency!() click to toggle source

@private

# File lib/infopark_component_cache/component_cache.rb, line 100
def ensure_consistency!
  guards.each(&:guard!)
end
expired?() click to toggle source

Checks if cache is valid (in consistent state). It delegates work to specified guards

For any unexpected case it returns true.

@return true if cache is valid and in consistent state

# File lib/infopark_component_cache/component_cache.rb, line 56
def expired?
  return true unless cache.enabled?

  !guards.all?(&:consistent?)
rescue StandardError => e
  raise e if Rails.env.test?

  true
end
fetch() { || ... } click to toggle source

Checks if the cache is in consistent state and cached value can be returned. In such case it returns cached value. Otherwise it evaluates passed block and updates the cache.

@see {#expired?} @yieldreturn value to be used in case of cache miss @return cached value or the return value of the block

# File lib/infopark_component_cache/component_cache.rb, line 74
def fetch(&_block)
  if expired?
    value = yield
    begin
      if cache.enabled?
        cache.write(component.cache_key, value)
        ensure_consistency!
      end
      value
    rescue StandardError => e
      raise e if Rails.env.test?

      value
    end
  else
    cache.read(component.cache_key)
  end
end