class WCC::Contentful::Middleware::Store::CachingMiddleware
Constants
- LAZILY_CACHEABLE_TYPES
Attributes
expires_in[RW]
Public Class Methods
new(cache = nil)
click to toggle source
# File lib/wcc/contentful/middleware/store/caching_middleware.rb, line 11 def initialize(cache = nil) @cache = cache || ActiveSupport::Cache::MemoryStore.new @expires_in = nil end
Public Instance Methods
find(key, **options)
click to toggle source
# File lib/wcc/contentful/middleware/store/caching_middleware.rb, line 16 def find(key, **options) event = 'fresh' found = @cache.fetch(key, expires_in: expires_in) do event = 'miss' # if it's not a contentful ID don't hit the API. # Store a nil object if we can't find the object on the CDN. (store.find(key, options) || nil_obj(key)) if key =~ /^\w+$/ end _instrument(event, key: key, options: options) case found.try(:dig, 'sys', 'type') when 'Nil', 'DeletedEntry', 'DeletedAsset' nil else found end end
find_by(content_type:, filter: nil, options: nil)
click to toggle source
TODO: github.com/watermarkchurch/wcc-contentful/issues/18
figure out how to cache the results of a find_by query, ex: `find_by('slug' => '/about')`
# File lib/wcc/contentful/middleware/store/caching_middleware.rb, line 38 def find_by(content_type:, filter: nil, options: nil) if filter&.keys == ['sys.id'] # Direct ID lookup, like what we do in `WCC::Contentful::ModelMethods.resolve` # We can return just this item. Stores are not required to implement :include option. if found = @cache.read(filter['sys.id']) return found end end store.find_by(content_type: content_type, filter: filter, options: options) end
index(json)
click to toggle source
index is called whenever the sync API comes back with more data.
# File lib/wcc/contentful/middleware/store/caching_middleware.rb, line 53 def index(json) delegated_result = store.index(json) if store.index? caching_result = _index(json) # _index returns nil if we don't already have it cached - so use the store result. # store result is nil if it doesn't index, so use the caching result if we have it. # They ought to be the same thing if it's cached and the store also indexes. caching_result || delegated_result end
index?()
click to toggle source
# File lib/wcc/contentful/middleware/store/caching_middleware.rb, line 62 def index? true end
Private Instance Methods
_index(json)
click to toggle source
# File lib/wcc/contentful/middleware/store/caching_middleware.rb, line 75 def _index(json) ensure_hash(json) id = json.dig('sys', 'id') type = json.dig('sys', 'type') prev = @cache.read(id) return if prev.nil? && LAZILY_CACHEABLE_TYPES.include?(type) if (prev_rev = prev&.dig('sys', 'revision')) && (next_rev = json.dig('sys', 'revision')) return prev if next_rev < prev_rev end # we also set DeletedEntry objects in the cache - no need to go hit the API when we know # this is a nil object @cache.write(id, json, expires_in: expires_in) case type when 'DeletedEntry', 'DeletedAsset' _instrument 'delete', id: id nil else _instrument 'set', id: id json end end
ensure_hash(val)
click to toggle source
# File lib/wcc/contentful/middleware/store/caching_middleware.rb, line 110 def ensure_hash(val) raise ArgumentError, 'Value must be a Hash' unless val.is_a?(Hash) end
nil_obj(id)
click to toggle source
# File lib/wcc/contentful/middleware/store/caching_middleware.rb, line 100 def nil_obj(id) { 'sys' => { 'id' => id, 'type' => 'Nil', 'revision' => 1 } } end