1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
require "forwardable"
module Flipper
extend self
extend Forwardable
# Private: The namespace for all instrumented events.
InstrumentationNamespace = :flipper
# Public: Start here. Given an adapter returns a handy DSL to all the flipper
# goodness. To see supported options, check out dsl.rb.
def new(adapter, options = {})
DSL.new(adapter, options)
end
# Public: Configure flipper.
#
# Flipper.configure do |config|
# config.adapter { ... }
# end
#
# Yields Flipper::Configuration instance.
def configure
yield configuration if block_given?
end
# Public: Returns Flipper::Configuration instance.
def configuration
@configuration ||= Configuration.new
end
# Public: Sets Flipper::Configuration instance.
def configuration=(configuration)
# need to reset flipper instance if configuration changes
self.instance = nil
@configuration = configuration
end
# Public: Default per thread flipper instance if configured. You should not
# need to use this directly as most of the Flipper::DSL methods are delegated
# from Flipper module itself. Instead of doing Flipper.instance.enabled?(:search),
# you can use Flipper.enabled?(:search) for the same result.
#
# Returns Flipper::DSL instance.
def instance
Thread.current[:flipper_instance] ||= configuration.default
end
# Public: Set the flipper instance. It is most common to use the
# Configuration#default to set this instance, but for things like the test
# environment, this writer is actually useful.
def instance=(flipper)
Thread.current[:flipper_instance] = flipper
end
# Public: All the methods delegated to instance. These should match the
# interface of Flipper::DSL.
def_delegators :instance,
:enabled?, :enable, :disable, :bool, :boolean,
:enable_actor, :disable_actor, :actor,
:enable_group, :disable_group,
:enable_percentage_of_actors, :disable_percentage_of_actors,
:actors, :percentage_of_actors,
:enable_percentage_of_time, :disable_percentage_of_time,
:time, :percentage_of_time,
:features, :feature, :[], :preload, :preload_all,
:adapter, :add, :exist?, :remove, :import,
:memoize=, :memoizing?,
:sync, :sync_secret # For Flipper::Cloud. Will error for OSS Flipper.
# Public: Use this to register a group by name.
#
# name - The Symbol name of the group.
# block - The block that should be used to determine if the group matches a
# given thing.
#
# Examples
#
# Flipper.register(:admins) { |thing|
# thing.respond_to?(:admin?) && thing.admin?
# }
#
# Returns a Flipper::Group.
# Raises Flipper::DuplicateGroup if the group is already registered.
def register(name, &block)
group = Types::Group.new(name, &block)
groups_registry.add(group.name, group)
group
rescue Registry::DuplicateKey
raise DuplicateGroup, "Group #{name.inspect} has already been registered"
end
# Public: Returns a Set of registered Types::Group instances.
def groups
groups_registry.values.to_set
end
# Public: Returns a Set of symbols where each symbol is a registered
# group name. If you just want the names, this is more efficient than doing
# `Flipper.groups.map(&:name)`.
def group_names
groups_registry.keys.to_set
end
# Public: Clears the group registry.
#
# Returns nothing.
def unregister_groups
groups_registry.clear
end
# Public: Check if a group exists
#
# Returns boolean
def group_exists?(name)
groups_registry.key?(name)
end
# Public: Fetches a group by name.
#
# name - The Symbol name of the group.
#
# Examples
#
# Flipper.group(:admins)
#
# Returns Flipper::Group.
def group(name)
groups_registry.get(name) || Types::Group.new(name)
end
# Internal: Registry of all groups_registry.
def groups_registry
@groups_registry ||= Registry.new
end
# Internal: Change the groups_registry registry.
def groups_registry=(registry)
@groups_registry = registry
end
end
require 'flipper/actor'
require 'flipper/adapter'
require 'flipper/adapters/memoizable'
require 'flipper/adapters/memory'
require 'flipper/adapters/instrumented'
require 'flipper/configuration'
require 'flipper/dsl'
require 'flipper/errors'
require 'flipper/feature'
require 'flipper/gate'
require 'flipper/instrumenters/memory'
require 'flipper/instrumenters/noop'
require 'flipper/identifier'
require 'flipper/middleware/memoizer'
require 'flipper/middleware/setup_env'
require 'flipper/poller'
require 'flipper/registry'
require 'flipper/type'
require 'flipper/types/actor'
require 'flipper/types/boolean'
require 'flipper/types/group'
require 'flipper/types/percentage'
require 'flipper/types/percentage_of_actors'
require 'flipper/types/percentage_of_time'
require 'flipper/typecast'
require "flipper/railtie" if defined?(Rails::Railtie)
|