Class: CanDo

Inherits:
Object
  • Object
show all
Defined in:
lib/can_do.rb

Overview

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.

Examples:

config/features.yml

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

test if a feature should be enabled

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

overwrite setting with environment variable

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

call with a block

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

Constant Summary collapse

CONNECTION_POOL_SIZE =
ENV.fetch("CANDO_CONNECTION_POOL_SIZE", 5)
CONNECTION_POOL =
ConnectionPool.new(size: CONNECTION_POOL_SIZE, timeout: 5) do
  Redis.new(url: ENV["CANDO_REDIS_URL"])
end
THE_TRUTH =
/^(true|t|yes|y|1)$/i
DEFAULT_NAMESPACE =
"defaults".freeze
REDIS_ERRORS =
[Redis::CannotConnectError, SocketError, RuntimeError]

Class Method Summary collapse

Class Method Details

.feature?(feature) ⇒ Boolean

Returns:

  • (Boolean)


40
41
42
43
44
45
46
# 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

.featuresObject



66
67
68
69
70
71
# 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) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
# 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) ⇒ Object



73
74
75
# File 'lib/can_do.rb', line 73

def redis_read(name)
  pool.with { |redis| redis.get(redis_key(name)) }
end

.write(name, val) ⇒ Object



60
61
62
63
64
# 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