class Flipper::Adapters::Dalli

Public: Adapter that wraps another adapter with the ability to cache adapter calls in Memcached using the Dalli gem.

Constants

FeaturesKey
GetAllKey
Namespace
Version

Attributes

cache[R]

Internal

name[R]

Public: The name of the adapter.

ttl[R]

Public: The ttl for all cached data.

Public Class Methods

key_for(key) click to toggle source

Private

# File lib/flipper/adapters/dalli.rb, line 17
def self.key_for(key)
  "#{Namespace}/feature/#{key}"
end
new(adapter, cache, ttl = 0) click to toggle source

Public

# File lib/flipper/adapters/dalli.rb, line 31
def initialize(adapter, cache, ttl = 0)
  @adapter = adapter
  @name = :dalli
  @cache = cache
  @ttl = ttl
end

Public Instance Methods

add(feature) click to toggle source

Public

# File lib/flipper/adapters/dalli.rb, line 44
def add(feature)
  result = @adapter.add(feature)
  @cache.delete(FeaturesKey)
  result
end
clear(feature) click to toggle source

Public

# File lib/flipper/adapters/dalli.rb, line 59
def clear(feature)
  result = @adapter.clear(feature)
  @cache.delete(key_for(feature.key))
  result
end
disable(feature, gate, thing) click to toggle source

Public

# File lib/flipper/adapters/dalli.rb, line 98
def disable(feature, gate, thing)
  result = @adapter.disable(feature, gate, thing)
  @cache.delete(key_for(feature.key))
  result
end
enable(feature, gate, thing) click to toggle source

Public

# File lib/flipper/adapters/dalli.rb, line 91
def enable(feature, gate, thing)
  result = @adapter.enable(feature, gate, thing)
  @cache.delete(key_for(feature.key))
  result
end
features() click to toggle source

Public

# File lib/flipper/adapters/dalli.rb, line 39
def features
  read_feature_keys
end
get(feature) click to toggle source

Public

# File lib/flipper/adapters/dalli.rb, line 66
def get(feature)
  @cache.fetch(key_for(feature.key), @ttl) do
    @adapter.get(feature)
  end
end
get_all() click to toggle source
# File lib/flipper/adapters/dalli.rb, line 76
def get_all
  if @cache.add(GetAllKey, Time.now.to_i, @ttl)
    response = @adapter.get_all
    response.each do |key, value|
      @cache.set(key_for(key), value, @ttl)
    end
    @cache.set(FeaturesKey, response.keys.to_set, @ttl)
    response
  else
    features = read_feature_keys.map { |key| Flipper::Feature.new(key, self) }
    read_many_features(features)
  end
end
get_multi(features) click to toggle source
# File lib/flipper/adapters/dalli.rb, line 72
def get_multi(features)
  read_many_features(features)
end
remove(feature) click to toggle source

Public

# File lib/flipper/adapters/dalli.rb, line 51
def remove(feature)
  result = @adapter.remove(feature)
  @cache.delete(FeaturesKey)
  @cache.delete(key_for(feature.key))
  result
end

Private Instance Methods

key_for(key) click to toggle source
# File lib/flipper/adapters/dalli.rb, line 106
def key_for(key)
  self.class.key_for(key)
end
read_feature_keys() click to toggle source
# File lib/flipper/adapters/dalli.rb, line 110
def read_feature_keys
  @cache.fetch(FeaturesKey, @ttl) { @adapter.features }
end
read_many_features(features) click to toggle source

Internal: Given an array of features, attempts to read through cache in as few network calls as possible.

# File lib/flipper/adapters/dalli.rb, line 116
def read_many_features(features)
  keys = features.map { |feature| key_for(feature.key) }
  cache_result = @cache.get_multi(keys)
  uncached_features = features.reject { |feature| cache_result[key_for(feature.key)] }

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

  result = {}
  features.each do |feature|
    result[feature.key] = cache_result[key_for(feature.key)]
  end
  result
end