2020-12-16 04:10:26 -05:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2021-02-03 10:09:24 -05:00
|
|
|
class ApplicationExperiment < Gitlab::Experiment # rubocop:disable Gitlab/NamespacedClass
|
2021-02-01 07:09:03 -05:00
|
|
|
def enabled?
|
2021-02-03 10:09:24 -05:00
|
|
|
return false if Feature::Definition.get(feature_flag_name).nil? # there has to be a feature flag yaml file
|
2021-02-23 04:10:45 -05:00
|
|
|
return false unless Gitlab.dev_env_or_com? # we have to be in an environment that allows experiments
|
2021-02-01 07:09:03 -05:00
|
|
|
|
2021-02-23 04:10:45 -05:00
|
|
|
# the feature flag has to be rolled out
|
2021-02-03 10:09:24 -05:00
|
|
|
Feature.get(feature_flag_name).state != :off # rubocop:disable Gitlab/AvoidFeatureGet
|
2021-02-01 07:09:03 -05:00
|
|
|
end
|
|
|
|
|
2021-03-11 16:09:09 -05:00
|
|
|
def publish(_result = nil)
|
2021-03-15 11:09:07 -04:00
|
|
|
return unless should_track? # don't track events for excluded contexts
|
|
|
|
|
2021-05-26 11:10:57 -04:00
|
|
|
record_experiment if @record # record the subject in the database if the context contains a namespace, group, project, actor or user
|
|
|
|
|
2020-12-16 04:10:26 -05:00
|
|
|
track(:assignment) # track that we've assigned a variant for this context
|
2021-03-10 10:09:11 -05:00
|
|
|
|
2021-06-15 20:10:15 -04:00
|
|
|
push_to_client
|
|
|
|
end
|
|
|
|
|
|
|
|
# push the experiment data to the client
|
|
|
|
def push_to_client
|
|
|
|
Gon.push({ experiment: { name => signature } }, true)
|
|
|
|
rescue NoMethodError
|
|
|
|
# means we're not in the request cycle, and can't add to Gon. Log a warning maybe?
|
2020-12-16 04:10:26 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def track(action, **event_args)
|
2021-02-23 04:10:45 -05:00
|
|
|
return unless should_track? # don't track events for excluded contexts
|
2020-12-16 04:10:26 -05:00
|
|
|
|
2021-02-23 04:10:45 -05:00
|
|
|
# track the event, and mix in the experiment signature data
|
2020-12-16 04:10:26 -05:00
|
|
|
Gitlab::Tracking.event(name, action.to_s, **event_args.merge(
|
|
|
|
context: (event_args[:context] || []) << SnowplowTracker::SelfDescribingJson.new(
|
2021-03-25 08:09:19 -04:00
|
|
|
'iglu:com.gitlab/gitlab_experiment/jsonschema/1-0-0', signature
|
2020-12-16 04:10:26 -05:00
|
|
|
)
|
|
|
|
))
|
|
|
|
end
|
|
|
|
|
2021-05-26 11:10:57 -04:00
|
|
|
def record!
|
|
|
|
@record = true
|
|
|
|
end
|
|
|
|
|
2021-02-24 13:11:28 -05:00
|
|
|
def exclude!
|
|
|
|
@excluded = true
|
|
|
|
end
|
|
|
|
|
2021-05-12 14:10:35 -04:00
|
|
|
def control_behavior
|
|
|
|
# define a default nil control behavior so we can omit it when not needed
|
|
|
|
end
|
|
|
|
|
2020-12-16 04:10:26 -05:00
|
|
|
private
|
|
|
|
|
2021-02-12 16:09:01 -05:00
|
|
|
def feature_flag_name
|
|
|
|
name.tr('/', '_')
|
|
|
|
end
|
|
|
|
|
2021-03-12 19:09:16 -05:00
|
|
|
def experiment_group?
|
|
|
|
Feature.enabled?(feature_flag_name, self, type: :experiment, default_enabled: :yaml)
|
2021-02-03 10:09:24 -05:00
|
|
|
end
|
2021-05-26 11:10:57 -04:00
|
|
|
|
|
|
|
def record_experiment
|
|
|
|
subject = context.value[:namespace] || context.value[:group] || context.value[:project] || context.value[:user] || context.value[:actor]
|
2021-06-03 02:10:07 -04:00
|
|
|
return unless ExperimentSubject.valid_subject?(subject)
|
2021-05-26 11:10:57 -04:00
|
|
|
|
|
|
|
variant = :experimental if @variant_name != :control
|
|
|
|
|
|
|
|
Experiment.add_subject(name, variant: variant || :control, subject: subject)
|
|
|
|
end
|
2020-12-16 04:10:26 -05:00
|
|
|
end
|