statsig 1.6.2 → 1.6.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 325d5430e48a3d71b68d2e284e20b66b0052bf1a4d9e99e7a92a84069b680ab8
4
- data.tar.gz: b227e1fede44928035b1a03ebc8e8c006425466b50b007f89c452f6a47b51cd6
3
+ metadata.gz: 9192f1c9886d3a3b18c0a2e70599e998b4784b23245e9064018ec31c98881b25
4
+ data.tar.gz: eb329d5f742ce2f77391f3f33ba4229852c2c68827643159b51fd870c1fb21d9
5
5
  SHA512:
6
- metadata.gz: 28017886b1a5d3f5c37e36680f0dfbd300cf5a0f6e0678430af69631486bc88689a622d74a63da1687ef7d610d612227d68cb58b85a7572b7cc5cfcaee0794dd
7
- data.tar.gz: 10a66e7674df116a65351b97b8d27055bacd46f021309c3256bc5605fe3a972416e2c595135262fc9d18117e447a5038db3ebe1b89cb71495f308430fe4d2a32
6
+ metadata.gz: e8a090dc289fe6994b08578b2d2884f9196f37f4104120c546dd11b3036bc939b84a343a643f15f8e12ca01a494f920206ee01a2302de5bcb71a94efb3048b76
7
+ data.tar.gz: 995f91cb599608d0691e8f598d7bc2aa50f0f1b652ad1fac83f3afdb9e950132e21a34aaee44c57797849fb99005cc9dea9d4664f3f4f0ba13afb75dd120c251
data/lib/config_result.rb CHANGED
@@ -3,11 +3,13 @@ class ConfigResult
3
3
  attr_accessor :gate_value
4
4
  attr_accessor :json_value
5
5
  attr_accessor :rule_id
6
+ attr_accessor :secondary_exposures
6
7
 
7
- def initialize(name, gate_value = false, json_value = {}, rule_id = '')
8
+ def initialize(name, gate_value = false, json_value = {}, rule_id = '', secondary_exposures = [])
8
9
  @name = name
9
10
  @gate_value = gate_value
10
11
  @json_value = json_value
11
12
  @rule_id = rule_id
13
+ @secondary_exposures = secondary_exposures.is_a?(Array) ? secondary_exposures : []
12
14
  end
13
15
  end
data/lib/evaluator.rb CHANGED
@@ -32,18 +32,21 @@ class Evaluator
32
32
 
33
33
  def eval_spec(user, config)
34
34
  if config['enabled']
35
+ exposures = []
35
36
  i = 0
36
37
  until i >= config['rules'].length do
37
38
  rule = config['rules'][i]
38
39
  result = self.eval_rule(user, rule)
39
40
  return $fetch_from_server if result == $fetch_from_server
40
- if result
41
+ exposures = exposures + result["exposures"] if result["exposures"].is_a? Array
42
+ if result['value']
41
43
  pass = self.eval_pass_percent(user, rule, config['salt'])
42
44
  return ConfigResult.new(
43
45
  config['name'],
44
46
  pass,
45
47
  pass ? rule['returnValue'] : config['defaultValue'],
46
48
  rule['id'],
49
+ exposures
47
50
  )
48
51
  end
49
52
 
@@ -51,17 +54,28 @@ class Evaluator
51
54
  end
52
55
  end
53
56
 
54
- ConfigResult.new(config['name'], false, config['defaultValue'], 'default')
57
+ ConfigResult.new(config['name'], false, config['defaultValue'], 'default', [])
55
58
  end
56
59
 
57
60
  def eval_rule(user, rule)
61
+ exposures = []
62
+ pass = true
58
63
  i = 0
59
64
  until i >= rule['conditions'].length do
60
65
  result = self.eval_condition(user, rule['conditions'][i])
61
- return result unless result == true
66
+ if result == $fetch_from_server
67
+ return $fetch_from_server
68
+ end
69
+
70
+ if result.is_a?(Hash)
71
+ exposures = exposures + result["exposures"] if result["exposures"].is_a? Array
72
+ pass = false if result["value"] == false
73
+ elsif result == false
74
+ pass = false
75
+ end
62
76
  i += 1
63
77
  end
64
- true
78
+ { "value" => pass, "exposures" => exposures }
65
79
  end
66
80
 
67
81
  def eval_condition(user, condition)
@@ -82,7 +96,18 @@ class Evaluator
82
96
  when 'fail_gate', 'pass_gate'
83
97
  other_gate_result = self.check_gate(user, target)
84
98
  return $fetch_from_server if other_gate_result == $fetch_from_server
85
- return type == 'pass_gate' ? other_gate_result.gate_value : !other_gate_result.gate_value
99
+
100
+ gate_value = other_gate_result&.gate_value == true
101
+ new_exposure = {
102
+ "gate" => target,
103
+ "gateValue" => gate_value ? "true" : "false",
104
+ "ruleID" => other_gate_result&.rule_id
105
+ }
106
+ exposures = other_gate_result&.secondary_exposures&.append(new_exposure)
107
+ return {
108
+ "value" => type == 'pass_gate' ? gate_value : !gate_value,
109
+ "exposures" => exposures
110
+ }
86
111
  when 'ip_based'
87
112
  value = get_value_from_user(user, field) || get_value_from_ip(user, field)
88
113
  return $fetch_from_server if value == $fetch_from_server
@@ -58,7 +58,7 @@ class StatsigDriver
58
58
  res = check_gate_fallback(user, gate_name)
59
59
  # exposure logged by the server
60
60
  else
61
- @logger.log_gate_exposure(user, res.name, res.gate_value, res.rule_id)
61
+ @logger.log_gate_exposure(user, res.name, res.gate_value, res.rule_id, res.secondary_exposures)
62
62
  end
63
63
 
64
64
  res.gate_value
@@ -84,12 +84,19 @@ class StatsigDriver
84
84
  res = get_config_fallback(user, dynamic_config_name)
85
85
  # exposure logged by the server
86
86
  else
87
- @logger.log_config_exposure(user, res.name, res.rule_id)
87
+ @logger.log_config_exposure(user, res.name, res.rule_id, res.secondary_exposures)
88
88
  end
89
89
 
90
90
  DynamicConfig.new(res.name, res.json_value, res.rule_id)
91
91
  end
92
92
 
93
+ def get_experiment(user, experiment_name)
94
+ if !experiment_name.is_a?(String) || experiment_name.empty?
95
+ raise "Invalid experiment_name provided"
96
+ end
97
+ get_config(user, experiment_name)
98
+ end
99
+
93
100
  def log_event(user, event_name, value = nil, metadata = nil)
94
101
  if !user.nil? && !user.instance_of?(StatsigUser)
95
102
  raise 'Must provide a valid StatsigUser or nil'
data/lib/statsig_event.rb CHANGED
@@ -2,6 +2,7 @@ class StatsigEvent
2
2
  attr_accessor :value
3
3
  attr_accessor :metadata
4
4
  attr_accessor :statsig_metadata
5
+ attr_accessor :secondary_exposures
5
6
  attr_reader :user
6
7
 
7
8
  def initialize(event_name)
@@ -23,6 +24,7 @@ class StatsigEvent
23
24
  'user' => @user,
24
25
  'time' => @time,
25
26
  'statsigMetadata' => @statsig_metadata,
27
+ 'secondaryExposures' => @secondary_exposures
26
28
  }
27
29
  end
28
30
  end
@@ -21,7 +21,7 @@ class StatsigLogger
21
21
  end
22
22
  end
23
23
 
24
- def log_gate_exposure(user, gate_name, value, rule_id)
24
+ def log_gate_exposure(user, gate_name, value, rule_id, secondary_exposures)
25
25
  event = StatsigEvent.new($gate_exposure_event)
26
26
  event.user = user
27
27
  event.metadata = {
@@ -30,10 +30,11 @@ class StatsigLogger
30
30
  'ruleID' => rule_id
31
31
  }
32
32
  event.statsig_metadata = @statsig_metadata
33
+ event.secondary_exposures = secondary_exposures.is_a?(Array) ? secondary_exposures : []
33
34
  log_event(event)
34
35
  end
35
36
 
36
- def log_config_exposure(user, config_name, rule_id)
37
+ def log_config_exposure(user, config_name, rule_id, secondary_exposures)
37
38
  event = StatsigEvent.new($config_exposure_event)
38
39
  event.user = user
39
40
  event.metadata = {
@@ -41,6 +42,7 @@ class StatsigLogger
41
42
  'ruleID' => rule_id
42
43
  }
43
44
  event.statsig_metadata = @statsig_metadata
45
+ event.secondary_exposures = secondary_exposures.is_a?(Array) ? secondary_exposures : []
44
46
  log_event(event)
45
47
  end
46
48
 
@@ -51,7 +53,7 @@ class StatsigLogger
51
53
  if @events.length == 0
52
54
  return
53
55
  end
54
- flush_events = @events.map { |e| e.serialize() }
56
+ flush_events = @events.map { |e| e.serialize }
55
57
  @events = []
56
58
 
57
59
  @network.post_logs(flush_events, @statsig_metadata)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: statsig
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.2
4
+ version: 1.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Statsig, Inc
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-14 00:00:00.000000000 Z
11
+ date: 2021-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler