class CanDo

Flips your features based on either a redis key, a config/features.yml file or environment variables. Redis keys always take precedence over Environment variables and the settings in your YAML file.

@example config/features.yml

defaults:
  some_feature: false
  other_feature: true
development:
  some_feature: true

@example test if a feature should be enabled

> RAILS_ENV=development rails console
CanDo.feature?(:some_feature) # => false

@example overwrite setting with environment variable

> SOME_FEATURE=true RAILS_ENV=development rails console
CanDo.feature?(:some_feature) # => true

@example call with a block

CanDo.feature?(:some_feature) do
  # this block get's called if some_feature is enabled
end

Constants

CONNECTION_POOL
CONNECTION_POOL_SIZE
DEFAULT_NAMESPACE
REDIS_ERRORS
THE_TRUTH

Public Class Methods

feature?(feature) { || ... } click to toggle source
# File lib/can_do.rb, line 40
def feature?(feature)
  is_enabled = read(feature)
  # If no block is passed, return true or false
  return is_enabled unless block_given?
  # If a block is passed, return block or nil
  yield if is_enabled
end
features() click to toggle source
# File lib/can_do.rb, line 66
def features
  keys = pool.with { |redis| redis.keys(redis_key("*")) }
  keys.map { |key| key.sub(redis_key(nil), "") }
rescue *REDIS_ERRORS
  []
end
read(feature) click to toggle source
# File lib/can_do.rb, line 48
def read(feature)
  name = feature.to_s
  shared_feature = redis_read(name)
  fallback_value = fallback.fetch(name, false)

  return !!(shared_feature =~ THE_TRUTH) unless shared_feature.nil?
  write(name, fallback_value)
  fallback_value
rescue *REDIS_ERRORS
  fallback_value
end
redis_read(name) click to toggle source
# File lib/can_do.rb, line 73
def redis_read(name)
  pool.with { |redis| redis.get(redis_key(name)) }
end
write(name, val) click to toggle source
# File lib/can_do.rb, line 60
def write(name, val)
  pool.with { |redis| redis.set(redis_key(name), val) } == "OK"
rescue *REDIS_ERRORS
  false
end

Private Class Methods

env() click to toggle source
# File lib/can_do.rb, line 114
def env
  ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
end
fallback() click to toggle source
# File lib/can_do.rb, line 87
def fallback
  @fallback ||= init_fallback
end
init_fallback() click to toggle source
# File lib/can_do.rb, line 95
def init_fallback
  features = load_yaml_features

  features.each do |key, val|
    begin
      write(key, redis_read(key) || val)
    rescue *REDIS_ERRORS
    end
  end

  features
end
load_yaml_features() click to toggle source
# File lib/can_do.rb, line 108
def load_yaml_features
  return {} unless File.exist?(yaml_file_path)
  data = YAML.safe_load(File.read(yaml_file_path))
  data.fetch(DEFAULT_NAMESPACE, {}).merge(data.fetch(env, {}))
end
pool() click to toggle source
# File lib/can_do.rb, line 83
def pool
  CONNECTION_POOL
end
redis_key(name) click to toggle source
# File lib/can_do.rb, line 79
def redis_key(name)
  "#{redis_namespace}:#{name}"
end
redis_namespace() click to toggle source
# File lib/can_do.rb, line 118
def redis_namespace
  "features"
end
yaml_file_path() click to toggle source
# File lib/can_do.rb, line 91
def yaml_file_path
  File.expand_path("config/features.yml", Dir.pwd)
end