debian-mirror-gitlab/lib/gitlab/experiment/rollout/feature.rb

68 lines
2.5 KiB
Ruby
Raw Normal View History

2022-04-04 11:22:00 +05:30
# frozen_string_literal: true
module Gitlab
class Experiment
module Rollout
class Feature < Percent
# For this rollout strategy to consider an experiment as enabled, we
# must:
#
# - have a feature flag yaml file that declares it.
# - be in an environment that permits it.
# - not have rolled out the feature flag at all (no percent of actors,
# no inclusions, etc.)
def enabled?
return false if ::Feature::Definition.get(feature_flag_name).nil?
return false unless Gitlab.dev_env_or_com?
::Feature.get(feature_flag_name).state != :off # rubocop:disable Gitlab/AvoidFeatureGet
end
# For assignment we first check to see if our feature flag is enabled
# for "self". This is done by calling `#flipper_id` (used behind the
# scenes by `Feature`). By default this is our `experiment.id` (or more
# specifically, the context key, which is an anonymous SHA generated
# using the details of an experiment.
#
# If the `Feature.enabled?` check is false, we return nil implicitly,
# which will assign the control. Otherwise we call super, which will
# assign a variant evenly, or based on our provided distribution rules.
def execute_assigment
super if ::Feature.enabled?(feature_flag_name, self, type: :experiment, default_enabled: :yaml)
end
# NOTE: There's a typo in the name of this method that we'll fix up.
alias_method :execute_assignment, :execute_assigment
# This is what's provided to the `Feature.enabled?` call that will be
# used to determine experiment inclusion. An experiment may provide an
# override for this method to make the experiment work on user, group,
# or projects.
#
# For example, when running an experiment on a project, you could make
# the experiment assignable by project (using chatops) by implementing
# a `flipper_id` method in the experiment:
#
# def flipper_id
# context.project.flipper_id
# end
#
# Or even cleaner, simply delegate it:
#
# delegate :flipper_id, to: -> { context.project }
def flipper_id
return experiment.flipper_id if experiment.respond_to?(:flipper_id)
"Experiment;#{id}"
end
private
def feature_flag_name
experiment.name.tr('/', '_')
end
end
end
end
end