diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-20 23:50:22 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-20 23:50:22 +0000 |
commit | 9dc93a4519d9d5d7be48ff274127136236a3adb3 (patch) | |
tree | 70467ae3692a0e35e5ea56bcb803eb512a10bedb /app/experiments | |
parent | 4b0f34b6d759d6299322b3a54453e930c6121ff0 (diff) | |
download | gitlab-ce-9dc93a4519d9d5d7be48ff274127136236a3adb3.tar.gz |
Add latest changes from gitlab-org/gitlab@13-11-stable-eev13.11.0-rc43
Diffstat (limited to 'app/experiments')
-rw-r--r-- | app/experiments/application_experiment.rb | 2 | ||||
-rw-r--r-- | app/experiments/members/invite_email_experiment.rb | 77 | ||||
-rw-r--r-- | app/experiments/strategy/round_robin.rb | 78 |
3 files changed, 77 insertions, 80 deletions
diff --git a/app/experiments/application_experiment.rb b/app/experiments/application_experiment.rb index ed0d146af8c..01105f6cec4 100644 --- a/app/experiments/application_experiment.rb +++ b/app/experiments/application_experiment.rb @@ -27,7 +27,7 @@ class ApplicationExperiment < Gitlab::Experiment # rubocop:disable Gitlab/Namesp # track the event, and mix in the experiment signature data Gitlab::Tracking.event(name, action.to_s, **event_args.merge( context: (event_args[:context] || []) << SnowplowTracker::SelfDescribingJson.new( - 'iglu:com.gitlab/gitlab_experiment/jsonschema/0-3-0', signature + 'iglu:com.gitlab/gitlab_experiment/jsonschema/1-0-0', signature ) )) end diff --git a/app/experiments/members/invite_email_experiment.rb b/app/experiments/members/invite_email_experiment.rb index a0f4dee2866..6a7d2b110d3 100644 --- a/app/experiments/members/invite_email_experiment.rb +++ b/app/experiments/members/invite_email_experiment.rb @@ -8,7 +8,82 @@ module Members INVITE_TYPE = 'initial_email' def resolve_variant_name - Strategy::RoundRobin.new(feature_flag_name, %i[avatar permission_info control]).execute + RoundRobin.new(feature_flag_name, %i[avatar permission_info control]).execute + end + end + + class RoundRobin + CacheError = Class.new(StandardError) + + COUNTER_EXPIRE_TIME = 86400 # one day + + def initialize(key, variants) + @key = key + @variants = variants + end + + def execute + increment_counter + resolve_variant_name + end + + # When the counter would expire + # + # @api private Used internally by SRE and debugging purpose + # @return [Integer] Number in seconds until expiration or false if never + def counter_expires_in + Gitlab::Redis::SharedState.with do |redis| + redis.ttl(key) + end + end + + # Return the actual counter value + # + # @return [Integer] value + def counter_value + Gitlab::Redis::SharedState.with do |redis| + (redis.get(key) || 0).to_i + end + end + + # Reset the counter + # + # @private Used internally by SRE and debugging purpose + # @return [Boolean] whether reset was a success + def reset! + redis_cmd do |redis| + redis.del(key) + end + end + + private + + attr_reader :key, :variants + + # Increase the counter + # + # @return [Boolean] whether operation was a success + def increment_counter + redis_cmd do |redis| + redis.incr(key) + redis.expire(key, COUNTER_EXPIRE_TIME) + end + end + + def resolve_variant_name + remainder = counter_value % variants.size + + variants[remainder] + end + + def redis_cmd + Gitlab::Redis::SharedState.with { |redis| yield(redis) } + + true + rescue CacheError => e + Gitlab::AppLogger.warn("GitLab: An unexpected error occurred in writing to Redis: #{e}") + + false end end end diff --git a/app/experiments/strategy/round_robin.rb b/app/experiments/strategy/round_robin.rb deleted file mode 100644 index 7b80c0e984d..00000000000 --- a/app/experiments/strategy/round_robin.rb +++ /dev/null @@ -1,78 +0,0 @@ -# frozen_string_literal: true - -module Strategy - class RoundRobin - CacheError = Class.new(StandardError) - - COUNTER_EXPIRE_TIME = 86400 # one day - - def initialize(key, variants) - @key = key - @variants = variants - end - - def execute - increment_counter - resolve_variant_name - end - - # When the counter would expire - # - # @api private Used internally by SRE and debugging purpose - # @return [Integer] Number in seconds until expiration or false if never - def counter_expires_in - Gitlab::Redis::SharedState.with do |redis| - redis.ttl(key) - end - end - - # Return the actual counter value - # - # @return [Integer] value - def counter_value - Gitlab::Redis::SharedState.with do |redis| - (redis.get(key) || 0).to_i - end - end - - # Reset the counter - # - # @private Used internally by SRE and debugging purpose - # @return [Boolean] whether reset was a success - def reset! - redis_cmd do |redis| - redis.del(key) - end - end - - private - - attr_reader :key, :variants - - # Increase the counter - # - # @return [Boolean] whether operation was a success - def increment_counter - redis_cmd do |redis| - redis.incr(key) - redis.expire(key, COUNTER_EXPIRE_TIME) - end - end - - def resolve_variant_name - remainder = counter_value % variants.size - - variants[remainder] - end - - def redis_cmd - Gitlab::Redis::SharedState.with { |redis| yield(redis) } - - true - rescue CacheError => e - Gitlab::AppLogger.warn("GitLab: An unexpected error occurred in writing to Redis: #{e}") - - false - end - end -end |