class Sprockets::Cache
Returns argument value.
value - A JSON serializable object.
key - An opaque String with a length less than 250 characters.
then later key “foo” with value “baz” is an undefined behavior.
Will only be called once per key. Setting a key “foo” with value “bar”,
set(key, value)
Returns an JSON serializable object.
key - An opaque String with a length less than 250 characters.
get(key)
The Backend cache store must implement two methods.
Backend cache interface
methods marked public on this class.
Environment#cache will always return a wrapped Cache interface. See the
environment.cache = Sprockets::Cache::MemoryStore.new(1000)
Always assign the backend store instance to Environment#cache=.
Public cache interface
even when the backend uses get/set or read/write.
Public: Wrapper interface to backend cache stores. Ensures a consistent API
def self.default_logger
def self.default_logger logger = Logger.new($stderr) logger.level = Logger::FATAL logger end
def expand_key(key)
key - JSON serializable key
Memcache.
The String should be under 250 characters so its compatible with
Internal: Expand object cache key into a short String key.
def expand_key(key) "sprockets/v#{VERSION}/#{DigestUtils.pack_urlsafe_base64digest(DigestUtils.digest(key))}" end
def fetch(key)
cache.fetch("foo") { "bar" }
Examples
Must return a consistent JSON serializable object for the given key.
block -
key - JSON serializable key
Public: Prefer API to retrieve and set values in the cache store.
def fetch(key) start = Time.now.to_f expanded_key = expand_key(key) value = @fetch_cache.get(expanded_key) if value.nil? value = @cache_wrapper.get(expanded_key) if value.nil? value = yield @cache_wrapper.set(expanded_key, value) @logger.debug do ms = "(#{((Time.now.to_f - start) * 1000).to_i}ms)" "Sprockets Cache miss #{peek_key(key)} #{ms}" end end @fetch_cache.set(expanded_key, value) end value end
def get(key, local = false)
local - Check local cache first (default: false)
key - JSON serializable key
Cache#fetch API over using this.
depending on the backend store being used. Prefer the
This API may be used publicaly, but may have undefined behavior
store.
Public: Low level API to retrieve item directly from the backend cache
def get(key, local = false) expanded_key = expand_key(key) value = @fetch_cache.get(expanded_key) if local value = @cache_wrapper.get(expanded_key) if value.nil? value end
def get_cache_wrapper(cache)
def get_cache_wrapper(cache) if cache.is_a?(Cache) cache # `Cache#get(key)` for Memcache elsif cache.respond_to?(:get) GetWrapper.new(cache) # `Cache#[key]` so `Hash` can be used elsif cache.respond_to?(:[]) HashWrapper.new(cache) # `Cache#read(key)` for `ActiveSupport::Cache` support elsif cache.respond_to?(:read) ReadWriteWrapper.new(cache) else cache = Sprockets::Cache::NullStore.new GetWrapper.new(cache) end end
def initialize(cache = nil, logger = self.class.default_logger)
use Environment#cache to retreive a wrapped interface.
Always assign a backend cache store instance to Environment#cache= and
Internal: Wrap a backend cache store.
def initialize(cache = nil, logger = self.class.default_logger) @cache_wrapper = get_cache_wrapper(cache) @fetch_cache = Cache::MemoryStore.new(1024) @logger = logger end
def inspect
Public: Pretty inspect
def inspect "#<#{self.class} local=#{@fetch_cache.inspect} store=#{@cache_wrapper.cache.inspect}>" end
def peek_key(key)
Internal: Show first 100 characters of cache key for logging purposes.
def peek_key(key) if key.is_a?(String) key[0, PEEK_SIZE].inspect elsif key.is_a?(Array) str = [] key.each { |k| str << peek_key(k) } str.join(':')[0, PEEK_SIZE] else peek_key(DigestUtils.pack_urlsafe_base64digest(DigestUtils.digest(key))) end end
def set(key, value, local = false)
local - Set on local cache (default: false)
a different value for the given key has undefined behavior.
value - A consistent JSON serializable object for the given key. Setting
key - JSON serializable key
Cache#fetch API over using this.
depending on the backend store being used. Prefer the
This API may be used publicaly, but may have undefined behavior
Public: Low level API to set item directly to the backend cache store.
def set(key, value, local = false) expanded_key = expand_key(key) @fetch_cache.set(expanded_key, value) @cache_wrapper.set(expanded_key, value) end