Module: Philiprehberger::FeatureFlag

Extended by:
Dependencies, Groups, Metrics, Scheduling, Targeting
Defined in:
lib/philiprehberger/feature_flag.rb,
lib/philiprehberger/feature_flag/groups.rb,
lib/philiprehberger/feature_flag/metrics.rb,
lib/philiprehberger/feature_flag/rollout.rb,
lib/philiprehberger/feature_flag/version.rb,
lib/philiprehberger/feature_flag/targeting.rb,
lib/philiprehberger/feature_flag/scheduling.rb,
lib/philiprehberger/feature_flag/dependencies.rb,
lib/philiprehberger/feature_flag/configuration.rb,
lib/philiprehberger/feature_flag/backends/env_backend.rb,
lib/philiprehberger/feature_flag/backends/yaml_backend.rb,
lib/philiprehberger/feature_flag/backends/memory_backend.rb

Defined Under Namespace

Modules: Backends, Dependencies, Groups, Metrics, Rollout, Scheduling, Targeting Classes: Configuration

Constant Summary collapse

VERSION =
'0.3.0'

Class Method Summary collapse

Methods included from Groups

disable_group, enable_group, group, group_flags, reset_groups!

Methods included from Targeting

disable_for, enable_for, reset_targets!, targeted?, targeted_users

Methods included from Metrics

metrics, record_metric, reset_metrics!

Methods included from Scheduling

reset_schedules!, schedule, schedule_for, scheduled_active?

Methods included from Dependencies

dependencies_met?, dependency_for, depends_on, reset_dependencies!

Class Method Details

.configurationObject



24
25
26
# File 'lib/philiprehberger/feature_flag.rb', line 24

def configuration
  @configuration ||= Configuration.new
end

.configure {|configuration| ... } ⇒ Object

Yields:



28
29
30
# File 'lib/philiprehberger/feature_flag.rb', line 28

def configure
  yield(configuration)
end

.enabled?(flag, user_id: nil, user: nil) ⇒ Boolean

Returns:

  • (Boolean)


32
33
34
35
36
37
38
# File 'lib/philiprehberger/feature_flag.rb', line 32

def enabled?(flag, user_id: nil, user: nil)
  return @overrides[flag.to_s] if overridden?(flag)

  result = evaluate_flag(flag, user_id, user)
  record_metric(flag, result)
  result
end

.flag_namesArray<Symbol>

Return the sorted, deduplicated union of every flag name known to the configured backend and the registered dependency, schedule, targeting, and group subsystems.

Backends that do not expose their flag names (for example, opaque remote backends without an all accessor) are skipped silently.

Returns:

  • (Array<Symbol>)

    ascending-sorted unique flag names



76
77
78
79
80
81
82
83
84
85
# File 'lib/philiprehberger/feature_flag.rb', line 76

def flag_names
  names = []
  names.concat(backend_flag_names)
  names.concat(Array(@dependencies&.keys))
  names.concat(Array(@dependencies&.values))
  names.concat(Array(@schedules&.keys))
  names.concat(Array(@targets&.keys))
  names.concat(Array(@groups&.values).flatten)
  names.map(&:to_sym).uniq.sort
end

.reload!Object



64
65
66
# File 'lib/philiprehberger/feature_flag.rb', line 64

def reload!
  configuration.backend.reload!
end

.reset!Object



87
88
89
90
91
92
93
94
95
# File 'lib/philiprehberger/feature_flag.rb', line 87

def reset!
  @configuration = nil
  @overrides = nil
  reset_dependencies!
  reset_schedules!
  reset_metrics!
  reset_targets!
  reset_groups!
end

.variant(flag, user_id:) ⇒ Object



40
41
42
43
44
45
46
47
# File 'lib/philiprehberger/feature_flag.rb', line 40

def variant(flag, user_id:)
  value = configuration.backend.get(flag)
  return nil unless variant_value?(value)

  variants = value['variants']
  bucket = Zlib.crc32("#{flag}:#{user_id}") % variants.size
  variants[bucket]
end

.with(flag, value) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/philiprehberger/feature_flag.rb', line 49

def with(flag, value)
  @overrides ||= {}
  key = flag.to_s
  had_previous = @overrides.key?(key)
  previous = @overrides[key]
  @overrides[key] = value
  yield
ensure
  if had_previous
    @overrides[key] = previous
  else
    @overrides&.delete(key)
  end
end