lib/mobility/plugins/cache.rb
# frozen_string_literal: true
module Mobility
module Plugins
=begin
Caches values fetched from the backend so subsequent fetches can be performed
more quickly. The cache stores cached values in a simple hash, which is not
optimal for some storage strategies, so some backends (KeyValue, Table) use a
custom module by defining a method, +include_cache+, on the backend class.
The cache is reset when one of a set of events happens (saving, reloading,
etc.). See {BackendResetter} for details.
Values are added to the cache in two ways:
1. first read from backend
2. any write to backend
=end
module Cache
extend Plugin
default true
requires :backend, include: :before
# Applies cache plugin to attributes.
included_hook do |_, backend_class|
if options[:cache]
if backend_class.respond_to?(:include_cache)
backend_class.include_cache
else
include_cache(backend_class)
end
end
end
private
def include_cache(backend_class)
backend_class.include BackendMethods
end
# Used in ORM cache plugins
def define_cache_hooks(klass, *reset_methods)
mod = self
private_methods = reset_methods & klass.private_instance_methods
reset_methods.each do |method_name|
define_method method_name do |*args|
super(*args).tap do
mod.names.each { |name| mobility_backends[name].clear_cache }
end
end
end
klass.class_eval { private(*private_methods) }
end
module BackendMethods
# @group Backend Accessors
#
# @!macro backend_reader
# @!method read(locale, value, options = {})
# @option options [Boolean] cache *false* to disable cache.
def read(locale, **options)
return super(locale, **options) if options.delete(:cache) == false
if cache.has_key?(locale)
cache[locale]
else
cache[locale] = super(locale, **options)
end
end
# @!macro backend_writer
# @option options [Boolean] cache
# *false* to disable cache.
def write(locale, value, **options)
return super if options.delete(:cache) == false
cache[locale] = super
end
# @!endgroup
def clear_cache
@cache = {}
end
private
def cache
@cache ||= {}
end
end
end
register_plugin(:cache, Cache)
end
end