statsig 1.6.2 → 1.6.3
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 +4 -4
- data/lib/config_result.rb +3 -1
- data/lib/evaluator.rb +30 -5
- data/lib/statsig_driver.rb +9 -2
- data/lib/statsig_event.rb +2 -0
- data/lib/statsig_logger.rb +5 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9192f1c9886d3a3b18c0a2e70599e998b4784b23245e9064018ec31c98881b25
|
4
|
+
data.tar.gz: eb329d5f742ce2f77391f3f33ba4229852c2c68827643159b51fd870c1fb21d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/statsig_driver.rb
CHANGED
@@ -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
|
data/lib/statsig_logger.rb
CHANGED
@@ -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.
|
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-
|
11
|
+
date: 2021-09-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|