2021-02-22 17:27:13 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2022-04-04 11:22:00 +05:30
|
|
|
class ApplicationExperiment < Gitlab::Experiment
|
2021-04-17 20:07:23 +05:30
|
|
|
def publish(_result = nil)
|
2021-09-30 23:02:18 +05:30
|
|
|
super
|
2021-04-17 20:07:23 +05:30
|
|
|
|
2021-10-27 15:23:28 +05:30
|
|
|
publish_to_client
|
2021-09-04 01:27:46 +05:30
|
|
|
end
|
|
|
|
|
2021-09-30 23:02:18 +05:30
|
|
|
def publish_to_client
|
2021-10-27 15:23:28 +05:30
|
|
|
return unless should_track?
|
|
|
|
|
2021-09-04 01:27:46 +05:30
|
|
|
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?
|
2021-02-22 17:27:13 +05:30
|
|
|
end
|
|
|
|
|
2021-09-30 23:02:18 +05:30
|
|
|
def publish_to_database
|
2022-01-26 12:08:38 +05:30
|
|
|
ActiveSupport::Deprecation.warn('publish_to_database is deprecated and should not be used for reporting anymore')
|
|
|
|
|
2021-10-27 15:23:28 +05:30
|
|
|
return unless should_track?
|
|
|
|
|
2021-09-30 23:02:18 +05:30
|
|
|
# if the context contains a namespace, group, project, user, or actor
|
|
|
|
value = context.value
|
|
|
|
subject = value[:namespace] || value[:group] || value[:project] || value[:user] || value[:actor]
|
|
|
|
return unless ExperimentSubject.valid_subject?(subject)
|
2021-02-22 17:27:13 +05:30
|
|
|
|
2022-01-26 12:08:38 +05:30
|
|
|
variant_name = :experimental if variant&.name != 'control'
|
|
|
|
Experiment.add_subject(name, variant: variant_name || :control, subject: subject)
|
2021-09-04 01:27:46 +05:30
|
|
|
end
|
|
|
|
|
2021-06-08 01:23:25 +05:30
|
|
|
def control_behavior
|
|
|
|
# define a default nil control behavior so we can omit it when not needed
|
|
|
|
end
|
|
|
|
|
2021-09-30 23:02:18 +05:30
|
|
|
# TODO: remove
|
|
|
|
# This is deprecated logic as of v0.6.0 and should eventually be removed, but
|
|
|
|
# needs to stay intact for actively running experiments. The new strategy
|
|
|
|
# utilizes Digest::SHA2, a secret seed, and generates a 64-byte string.
|
|
|
|
def key_for(source, seed = name)
|
|
|
|
source = source.keys + source.values if source.is_a?(Hash)
|
|
|
|
|
|
|
|
ingredients = Array(source).map { |v| identify(v) }
|
|
|
|
ingredients.unshift(seed)
|
|
|
|
|
|
|
|
Digest::MD5.hexdigest(ingredients.join('|'))
|
|
|
|
end
|
|
|
|
|
2022-01-26 12:08:38 +05:30
|
|
|
def nest_experiment(other)
|
|
|
|
instance_exec(:nested, { label: other.name }, &Configuration.tracking_behavior)
|
|
|
|
end
|
|
|
|
|
2021-02-22 17:27:13 +05:30
|
|
|
private
|
|
|
|
|
2022-04-04 11:22:00 +05:30
|
|
|
def tracking_context(event_args)
|
2022-01-26 12:08:38 +05:30
|
|
|
{
|
|
|
|
namespace: context.try(:namespace) || context.try(:group),
|
|
|
|
project: context.try(:project),
|
|
|
|
user: user_or_actor
|
2022-04-04 11:22:00 +05:30
|
|
|
}.merge(event_args)
|
2022-01-26 12:08:38 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
def user_or_actor
|
|
|
|
actor = context.try(:actor)
|
|
|
|
actor.respond_to?(:id) ? actor : context.try(:user)
|
|
|
|
end
|
2021-02-22 17:27:13 +05:30
|
|
|
end
|