class Flipper::Adapters::Redis

Attributes

key_prefix[R]

Public Class Methods

new(client, key_prefix: nil) click to toggle source

Public: Initializes a Redis flipper adapter.

client - The Redis client to use. key_prefix - an optional prefix with which to namespace

flipper's Redis keys
# File lib/flipper/adapters/redis.rb, line 25
def initialize(client, key_prefix: nil)
  @client = client
  @key_prefix = key_prefix
end

Public Instance Methods

add(feature) click to toggle source

Public: Adds a feature to the set of known features.

# File lib/flipper/adapters/redis.rb, line 36
def add(feature)
  if redis_sadd_returns_boolean?
    @client.sadd? features_key, feature.key
  else
    @client.sadd features_key, feature.key
  end
  true
end
clear(feature) click to toggle source

Public: Clears the gate values for a feature.

# File lib/flipper/adapters/redis.rb, line 57
def clear(feature)
  @client.del key_for(feature.key)
  true
end
disable(feature, gate, thing) click to toggle source

Public: Disables a gate for a given thing.

feature - The Flipper::Feature for the gate. gate - The Flipper::Gate to disable. thing - The Flipper::Type being disabled for the gate.

Returns true.

# File lib/flipper/adapters/redis.rb, line 112
def disable(feature, gate, thing)
  feature_key = key_for(feature.key)
  case gate.data_type
  when :boolean
    @client.del feature_key
  when :integer
    @client.hset feature_key, gate.key, thing.value.to_s
  when :set
    @client.hdel feature_key, to_field(gate, thing)
  when :json
    @client.hdel feature_key, gate.key
  else
    unsupported_data_type gate.data_type
  end

  true
end
enable(feature, gate, thing) click to toggle source

Public: Enables a gate for a given thing.

feature - The Flipper::Feature for the gate. gate - The Flipper::Gate to enable. thing - The Flipper::Type being enabled for the gate.

Returns true.

# File lib/flipper/adapters/redis.rb, line 86
def enable(feature, gate, thing)
  feature_key = key_for(feature.key)
  case gate.data_type
  when :boolean
    clear(feature)
    @client.hset feature_key, gate.key, thing.value.to_s
  when :integer
    @client.hset feature_key, gate.key, thing.value.to_s
  when :set
    @client.hset feature_key, to_field(gate, thing), 1
  when :json
    @client.hset feature_key, gate.key, Typecast.to_json(thing.value)
  else
    unsupported_data_type gate.data_type
  end

  true
end
features() click to toggle source

Public: The set of known features.

# File lib/flipper/adapters/redis.rb, line 31
def features
  read_feature_keys
end
features_key() click to toggle source
# File lib/flipper/adapters/redis.rb, line 12
def features_key
  "#{key_prefix}flipper_features"
end
get(feature) click to toggle source

Public: Gets the values for all gates for a given feature.

Returns a Hash of Flipper::Gate#key => value.

# File lib/flipper/adapters/redis.rb, line 65
def get(feature)
  doc = doc_for(feature)
  result_for_feature(feature, doc)
end
get_all() click to toggle source
# File lib/flipper/adapters/redis.rb, line 74
def get_all
  features = read_feature_keys.map { |key| Flipper::Feature.new(key, self) }
  read_many_features(features)
end
get_multi(features) click to toggle source
# File lib/flipper/adapters/redis.rb, line 70
def get_multi(features)
  read_many_features(features)
end
key_for(feature_name) click to toggle source
# File lib/flipper/adapters/redis.rb, line 16
def key_for(feature_name)
  "#{key_prefix}#{feature_name}"
end
remove(feature) click to toggle source

Public: Removes a feature from the set of known features.

# File lib/flipper/adapters/redis.rb, line 46
def remove(feature)
  if redis_sadd_returns_boolean?
    @client.srem? features_key, feature.key
  else
    @client.srem features_key, feature.key
  end
  @client.del key_for(feature.key)
  true
end

Private Instance Methods

doc_for(feature, pipeline: @client) click to toggle source

Private: Gets a hash of fields => values for the given feature.

Returns a Hash of fields => values.

# File lib/flipper/adapters/redis.rb, line 152
def doc_for(feature, pipeline: @client)
  pipeline.hgetall(key_for(feature.key))
end
docs_for(features) click to toggle source
# File lib/flipper/adapters/redis.rb, line 156
def docs_for(features)
  @client.pipelined do |pipeline|
    features.each do |feature|
      doc_for(feature, pipeline: pipeline)
    end
  end
end
fields_to_gate_value(fields, gate) click to toggle source

Private: Returns a set of values given an array of fields and a gate.

Returns a Set of the values enabled for the gate.

# File lib/flipper/adapters/redis.rb, line 194
def fields_to_gate_value(fields, gate)
  regex = %r{^#{Regexp.escape(gate.key.to_s)}/}
  keys = fields.grep(regex)
  values = keys.map { |key| key.split('/', 2).last }
  values.to_set
end
read_feature_keys() click to toggle source
# File lib/flipper/adapters/redis.rb, line 145
def read_feature_keys
  @client.smembers(features_key).to_set
end
read_many_features(features) click to toggle source
# File lib/flipper/adapters/redis.rb, line 136
def read_many_features(features)
  docs = docs_for(features)
  result = {}
  features.zip(docs) do |feature, doc|
    result[feature.key] = result_for_feature(feature, doc)
  end
  result
end
redis_sadd_returns_boolean?() click to toggle source
# File lib/flipper/adapters/redis.rb, line 132
def redis_sadd_returns_boolean?
  @client.class.respond_to?(:sadd_returns_boolean) && @client.class.sadd_returns_boolean
end
result_for_feature(feature, doc) click to toggle source
# File lib/flipper/adapters/redis.rb, line 164
def result_for_feature(feature, doc)
  result = {}
  fields = doc.keys

  feature.gates.each do |gate|
    result[gate.key] =
      case gate.data_type
      when :boolean, :integer
        doc[gate.key.to_s]
      when :set
        fields_to_gate_value fields, gate
      when :json
        value = doc[gate.key.to_s]
        Typecast.from_json(value)
      else
        unsupported_data_type gate.data_type
      end
  end

  result
end
to_field(gate, thing) click to toggle source

Private: Converts gate and thing to hash key.

# File lib/flipper/adapters/redis.rb, line 187
def to_field(gate, thing)
  "#{gate.key}/#{thing.value}"
end
unsupported_data_type(data_type) click to toggle source

Private

# File lib/flipper/adapters/redis.rb, line 202
def unsupported_data_type(data_type)
  raise "#{data_type} is not supported by this adapter"
end