class IknowCache::CacheGroup

Constants

ROOT_PATH

Attributes

default_options[R]
key[R]
key_name[R]
name[R]
parent[R]

Public Class Methods

new(parent, name, key_name, default_options, static_version) click to toggle source
# File lib/iknow_cache.rb, line 13
def initialize(parent, name, key_name, default_options, static_version)
  @parent          = parent
  @name            = name
  @key_name        = key_name
  @key             = Struct.new(*parent.try { |p| p.key.members }, key_name)
  @default_options = IknowCache.merge_options(parent&.default_options, default_options).try { |x| x.dup.freeze }
  @static_version  = static_version

  @caches          = []
  @children        = []
end

Public Instance Methods

delete_all(key, parent_path: nil) click to toggle source

Clear this key in all Caches in this CacheGroup. It is an error to do this if this CacheGroup has an statically versioned child, as that child cannot be invalidated.

# File lib/iknow_cache.rb, line 40
def delete_all(key, parent_path: nil)
  @caches.each do |cache|
    cache.delete(key, parent_path: parent_path)
  end

  @children.each do |child_group|
    child_group.invalidate_cache_group(key)
  end
end
invalidate_cache_group(parent_key = nil) click to toggle source

Clear all keys in this cache group (for the given parent), invalidating all caches in it and its children

# File lib/iknow_cache.rb, line 52
def invalidate_cache_group(parent_key = nil)
  parent_path = self.parent_path(parent_key)
  Rails.cache.increment(version_path_string(parent_path))
end
parent_path(parent_key = nil) click to toggle source
# File lib/iknow_cache.rb, line 72
def parent_path(parent_key = nil)
  if parent.nil?
    ROOT_PATH
  else
    parent.path(parent_key)
  end
end
parent_path_multi(parent_keys = nil) click to toggle source

look up multiple parent paths at once, returns { key => parent_path }

# File lib/iknow_cache.rb, line 109
def parent_path_multi(parent_keys = nil)
  if parent.nil?
    parent_keys.each_with_object({}) { |k, h| h[k] = ROOT_PATH }
  else
    parent.path_multi(parent_keys)
  end
end
path(key, parent_path = nil) click to toggle source

Fetch the path for this cache. We allow the parent_path to be precomputed to save hitting the cache multiple times for its version.

# File lib/iknow_cache.rb, line 59
def path(key, parent_path = nil)
  if key.nil? || key[self.key_name].nil?
    raise ArgumentError.new("Missing required key '#{self.key_name}' for cache '#{self.name}'")
  end

  key_value     = key[self.key_name]
  parent_path ||= self.parent_path(key)
  version       = self.version(parent_path)
  path_string(parent_path, version, key_value)
end
path_multi(keys) click to toggle source

compute multiple paths at once: returns { key => path }

# File lib/iknow_cache.rb, line 85
def path_multi(keys)
  # compute parent path for each key
  parent_paths = self.parent_path_multi(keys)

  # and versions for each parent path
  versions = self.version_multi(parent_paths.values.uniq)

  # update parent_paths with our paths
  keys.each do |key|
    parent_path = parent_paths[key]
    version     = versions[parent_path]
    key_value   = key[self.key_name]

    unless key_value
      raise ArgumentError.new("Required cache key missing: #{self.key_name}")
    end

    parent_paths[key] = path_string(parent_path, version, key_value)
  end

  parent_paths
end
register_cache(name, cache_options: nil) click to toggle source
# File lib/iknow_cache.rb, line 32
def register_cache(name, cache_options: nil)
  c = Cache.new(self, name, cache_options)
  @caches << c
  c
end
register_child_group(name, key_name, default_options: nil, static_version: 1) { |group| ... } click to toggle source
# File lib/iknow_cache.rb, line 25
def register_child_group(name, key_name, default_options: nil, static_version: 1)
  group = CacheGroup.new(self, name, key_name, default_options, static_version)
  @children << group
  yield group if block_given?
  group
end
version(parent_path) click to toggle source
# File lib/iknow_cache.rb, line 80
def version(parent_path)
  Rails.cache.fetch(version_path_string(parent_path), raw: true) { 1 }
end
version_multi(parent_paths) click to toggle source

Look up multiple versions at once, returns { parent_path => version }

# File lib/iknow_cache.rb, line 118
def version_multi(parent_paths)
  # compute version paths
  version_by_pp = parent_paths.each_with_object({}) { |pp, h| h[pp] = version_path_string(pp) }
  version_paths = version_by_pp.values

  # look up versions in cache
  versions = Rails.cache.read_multi(*version_paths, raw: true)

  version_paths.each do |vp|
    next if versions.has_key?(vp)

    versions[vp] = Rails.cache.fetch(vp, raw: true) { 1 }
  end

  # swap in the versions
  parent_paths.each do |pp|
    vp = version_by_pp[pp]
    version = versions[vp]
    version_by_pp[pp] = version
  end

  version_by_pp
end

Private Instance Methods

path_string(parent_path, version, value) click to toggle source
# File lib/iknow_cache.rb, line 144
def path_string(parent_path, version, value)
  "#{parent_path}/#{name}/#{@static_version}/#{version}/#{value}"
end
version_path_string(parent_path) click to toggle source
# File lib/iknow_cache.rb, line 148
def version_path_string(parent_path)
  "#{parent_path}/#{name}/_version"
end