class Flipper::Adapters::Memoizable

Internal: Adapter that wraps another adapter with the ability to memoize adapter calls in memory. Used by flipper dsl and the memoizer middleware to make it possible to memoize adapter calls for the duration of a request.

Constants

FeaturesKey
GetAllKey

Attributes

adapter[R]

Internal: The adapter this adapter is wrapping.

cache[R]

Internal

name[R]

Public: The name of the adapter.

Public Class Methods

key_for(key) click to toggle source

Private

# File lib/flipper/adapters/memoizable.rb, line 24
def self.key_for(key)
  "feature/#{key}"
end
new(adapter, cache = nil) click to toggle source

Public

Calls superclass method
# File lib/flipper/adapters/memoizable.rb, line 29
def initialize(adapter, cache = nil)
  super(adapter)
  @adapter = adapter
  @name = :memoizable
  @cache = cache || {}
  @memoize = false
end

Public Instance Methods

add(feature) click to toggle source

Public

# File lib/flipper/adapters/memoizable.rb, line 47
def add(feature)
  result = @adapter.add(feature)
  expire_features_set
  result
end
clear(feature) click to toggle source

Public

# File lib/flipper/adapters/memoizable.rb, line 62
def clear(feature)
  result = @adapter.clear(feature)
  expire_feature(feature)
  result
end
disable(feature, gate, thing) click to toggle source

Public

# File lib/flipper/adapters/memoizable.rb, line 133
def disable(feature, gate, thing)
  result = @adapter.disable(feature, gate, thing)
  expire_feature(feature)
  result
end
enable(feature, gate, thing) click to toggle source

Public

# File lib/flipper/adapters/memoizable.rb, line 126
def enable(feature, gate, thing)
  result = @adapter.enable(feature, gate, thing)
  expire_feature(feature)
  result
end
features() click to toggle source

Public

# File lib/flipper/adapters/memoizable.rb, line 38
def features
  if memoizing?
    cache.fetch(FeaturesKey) { cache[FeaturesKey] = @adapter.features }
  else
    @adapter.features
  end
end
get(feature) click to toggle source

Public

# File lib/flipper/adapters/memoizable.rb, line 69
def get(feature)
  if memoizing?
    cache.fetch(key_for(feature.key)) { cache[key_for(feature.key)] = @adapter.get(feature) }
  else
    @adapter.get(feature)
  end
end
get_all() click to toggle source
# File lib/flipper/adapters/memoizable.rb, line 99
def get_all
  if memoizing?
    response = nil
    if cache[GetAllKey]
      response = {}
      cache[FeaturesKey].each do |key|
        response[key] = cache[key_for(key)]
      end
    else
      response = @adapter.get_all
      response.each do |key, value|
        cache[key_for(key)] = value
      end
      cache[FeaturesKey] = response.keys.to_set
      cache[GetAllKey] = true
    end

    # Ensures that looking up other features that do not exist doesn't
    # result in N+1 adapter calls.
    response.default_proc = ->(memo, key) { memo[key] = default_config }
    response
  else
    @adapter.get_all
  end
end
get_multi(features) click to toggle source

Public

# File lib/flipper/adapters/memoizable.rb, line 78
def get_multi(features)
  if memoizing?
    uncached_features = features.reject { |feature| cache[key_for(feature.key)] }

    if uncached_features.any?
      response = @adapter.get_multi(uncached_features)
      response.each do |key, hash|
        cache[key_for(key)] = hash
      end
    end

    result = {}
    features.each do |feature|
      result[feature.key] = cache[key_for(feature.key)]
    end
    result
  else
    @adapter.get_multi(features)
  end
end
memoize=(value) click to toggle source

Internal: Turns local caching on/off.

value - The Boolean that decides if local caching is on.

# File lib/flipper/adapters/memoizable.rb, line 142
def memoize=(value)
  cache.clear
  @memoize = value
end
memoizing?() click to toggle source

Internal: Returns true for using local cache, false for not.

# File lib/flipper/adapters/memoizable.rb, line 148
def memoizing?
  !!@memoize
end
remove(feature) click to toggle source

Public

# File lib/flipper/adapters/memoizable.rb, line 54
def remove(feature)
  result = @adapter.remove(feature)
  expire_features_set
  expire_feature(feature)
  result
end

Private Instance Methods

expire_feature(feature) click to toggle source
# File lib/flipper/adapters/memoizable.rb, line 158
def expire_feature(feature)
  cache.delete(key_for(feature.key)) if memoizing?
end
expire_features_set() click to toggle source
# File lib/flipper/adapters/memoizable.rb, line 162
def expire_features_set
  cache.delete(FeaturesKey) if memoizing?
end
key_for(key) click to toggle source
# File lib/flipper/adapters/memoizable.rb, line 154
def key_for(key)
  self.class.key_for(key)
end