gitlab-experiment 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 31e4979de3006211bcd1f63882215ae9213c3a22de25e7cca8546f3fce2ef649
4
- data.tar.gz: cb865da8c87f019755194c98e073720f5f246b5a2c57e6d511c2a280d78ff996
3
+ metadata.gz: 13f170ab47c88f393041b3f4b8b69c168d8a159fcfcdf2fe7458ceca75a9b9db
4
+ data.tar.gz: 5bc7fe4a5c8a493ce14413c109ac4424bdd61d8b0c3513530963e52586bfaf5f
5
5
  SHA512:
6
- metadata.gz: 7906faeb21deaa6e0be322c94c0fd45ea200b5419ac5aacd2d2656b416ac08c21654e84f0ef3d2db5bb33c819dc73020267488a6f7f1ac045b66591ec04ae334
7
- data.tar.gz: e0f9328d5c8f1eca74681e749e01cc6ccf513d619b3c4aa522c45d08a4692d370a96d97437975285fa26dcebad0a7e0a3a8356724b980902ba1b86c8fa82f0a1
6
+ metadata.gz: bc52008aea6015b274fb7200c83b14145b355be637f1d286a8c9590df40c5d5e2c1d6da9e6f41f7f1970c576dfb13af69f43610e162eebff642d3945455e1b24
7
+ data.tar.gz: 9f16a5b7bdd2ae9ea9b624946d5055878c67d67e3f755900bccdac153c330fab77ed98d1d88b0f1a869e3bbd1b1f347366252db98207513e789c387c6fd509d0
@@ -32,20 +32,34 @@ module Gitlab
32
32
 
33
33
  @rollout = Rollout.resolve(rollout)
34
34
  end
35
+
36
+ def exclude(*filter_list, **options, &block)
37
+ build_callback(:exclusion_check, filter_list.unshift(block), **options) do |target, callback|
38
+ throw(:abort) if target.instance_variable_get(:@excluded) || callback.call(target, nil) == true
39
+ end
40
+ end
41
+
42
+ def segment(*filter_list, variant:, **options, &block)
43
+ build_callback(:segmentation_check, filter_list.unshift(block), **options) do |target, callback|
44
+ target.variant(variant) if target.instance_variable_get(:@variant_name).nil? && callback.call(target, nil)
45
+ end
46
+ end
35
47
  end
36
48
 
37
49
  def name
38
50
  [Configuration.name_prefix, @name].compact.join('_')
39
51
  end
40
52
 
41
- def use(&block)
42
- try(:control, &block)
53
+ def control(&block)
54
+ candidate(:control, &block)
43
55
  end
56
+ alias_method :use, :control
44
57
 
45
- def try(name = nil, &block)
58
+ def candidate(name = nil, &block)
46
59
  name = (name || :candidate).to_s
47
60
  behaviors[name] = block
48
61
  end
62
+ alias_method :try, :candidate
49
63
 
50
64
  def context(value = nil)
51
65
  return @context if value.blank?
@@ -59,12 +73,10 @@ module Gitlab
59
73
  return Variant.new(name: (@variant_name || :unresolved).to_s) if @variant_name || @resolving_variant
60
74
 
61
75
  if enabled?
62
- @variant_name ||= :control if excluded?
63
-
64
76
  @resolving_variant = true
65
- if (result = cache_variant(@variant_name) { resolve_variant_name }).present?
66
- @variant_name = result.to_sym
67
- end
77
+ @variant_name ||= :control if excluded?
78
+ result = cache_variant(@variant_name) { resolve_variant_name }
79
+ @variant_name = result.to_sym if result.present?
68
80
  end
69
81
 
70
82
  run_callbacks(segmentation_callback_chain) do
@@ -81,6 +93,10 @@ module Gitlab
81
93
  @rollout = Rollout.resolve(rollout)
82
94
  end
83
95
 
96
+ def exclude!
97
+ @excluded = true
98
+ end
99
+
84
100
  def run(variant_name = nil)
85
101
  @result ||= super(variant(variant_name).name)
86
102
  end
@@ -102,8 +118,7 @@ module Gitlab
102
118
  def excluded?
103
119
  return @excluded if defined?(@excluded)
104
120
 
105
- @excluded = !@context.trackable? || # adhere to DNT headers
106
- !run_callbacks(:exclusion_check) { :not_excluded } # didn't pass exclusion check
121
+ @excluded = !run_callbacks(:exclusion_check) { :not_excluded }
107
122
  end
108
123
 
109
124
  def experiment_group?
@@ -111,7 +126,7 @@ module Gitlab
111
126
  end
112
127
 
113
128
  def should_track?
114
- enabled? && !excluded?
129
+ enabled? && @context.trackable? && !excluded?
115
130
  end
116
131
 
117
132
  def signature
@@ -125,7 +140,7 @@ module Gitlab
125
140
  protected
126
141
 
127
142
  def segmentation_callback_chain
128
- return :segmentation_check if !variant_assigned? && enabled? && !excluded?
143
+ return :segmentation_check if @variant_name.nil? && enabled? && !excluded?
129
144
 
130
145
  :unsegmented
131
146
  end
@@ -4,13 +4,9 @@ module Gitlab
4
4
  class Experiment
5
5
  module BaseInterface
6
6
  extend ActiveSupport::Concern
7
-
8
- # don't `include` here so we don't override the default scientist class
9
- Scientist::Experiment.send(:append_features, self) # rubocop:disable GitlabSecurity/PublicSend
7
+ include Scientist::Experiment
10
8
 
11
9
  class_methods do
12
- include Scientist::Experiment::RaiseOnMismatch
13
-
14
10
  def configure
15
11
  yield Configuration
16
12
  end
@@ -72,8 +68,8 @@ module Gitlab
72
68
 
73
69
  protected
74
70
 
75
- def variant_assigned?
76
- !@variant_name.nil?
71
+ def raise_on_mismatches?
72
+ false
77
73
  end
78
74
 
79
75
  def generate_result(variant_name)
@@ -15,28 +15,17 @@ module Gitlab
15
15
  end
16
16
 
17
17
  class_methods do
18
- def exclude(*filter_list, **options, &block)
19
- filters = filter_list.unshift(block).compact.map do |filter|
20
- result_lambda = ActiveSupport::Callbacks::CallTemplate.build(filter, self).make_lambda
21
- lambda do |target|
22
- throw(:abort) if target.instance_variable_get(:'@excluded') || result_lambda.call(target, nil) == true
23
- end
24
- end
25
-
26
- raise ArgumentError, 'no filters provided' if filters.empty?
27
-
28
- set_callback(:exclusion_check, :before, *filters, options)
29
- end
18
+ private
30
19
 
31
- def segment(*filter_list, variant:, **options, &block)
32
- filters = filter_list.unshift(block).compact.map do |filter|
20
+ def build_callback(chain, filters, **options)
21
+ filters = filters.compact.map do |filter|
33
22
  result_lambda = ActiveSupport::Callbacks::CallTemplate.build(filter, self).make_lambda
34
- ->(target) { target.variant(variant) if !target.variant_assigned? && result_lambda.call(target, nil) }
23
+ ->(target) { yield(target, result_lambda) }
35
24
  end
36
25
 
37
26
  raise ArgumentError, 'no filters provided' if filters.empty?
38
27
 
39
- set_callback(:segmentation_check, :before, *filters, options)
28
+ set_callback(chain, *filters, **options)
40
29
  end
41
30
  end
42
31
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Gitlab
4
4
  class Experiment
5
- VERSION = '0.5.0'
5
+ VERSION = '0.5.1'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-experiment
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitLab
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-11 00:00:00.000000000 Z
11
+ date: 2021-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -30,20 +30,20 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.5'
33
+ version: '1.6'
34
34
  - - ">="
35
35
  - !ruby/object:Gem::Version
36
- version: 1.5.0
36
+ version: 1.6.0
37
37
  type: :runtime
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
40
40
  requirements:
41
41
  - - "~>"
42
42
  - !ruby/object:Gem::Version
43
- version: '1.5'
43
+ version: '1.6'
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
- version: 1.5.0
46
+ version: 1.6.0
47
47
  description:
48
48
  email:
49
49
  - gitlab_rubygems@gitlab.com