statsig 1.6.3 → 1.7.0.beta.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 +4 -4
- data/lib/evaluator.rb +13 -11
- data/lib/network.rb +12 -12
- data/lib/statsig.rb +2 -2
- data/lib/statsig_driver.rb +5 -3
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cf5fda9f980ecae86129f6ea0bd4052b6af45cba14c83e38062b495cd06cfeb1
|
4
|
+
data.tar.gz: 5b1a231a8af145fec2303fc89998f3e9acf05323cbc55d9fea3850ba841ecd1e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f1c7cf9a5a549021f02c16bac3d1095143ee9231a3f4165db9040efbf9b16cef083b6955dc5f748dd5fcfe12953064e8c48874a1eb8f477c24f61d061a57890
|
7
|
+
data.tar.gz: a5f291bd14edb61286416c293eae1c14f3c519dc1c6548356fe7147667cc33ed6b327488412e2f0b5516139d71d06bacf0db3f6ee907685be9c7e8ca2cc6b119
|
data/lib/evaluator.rb
CHANGED
@@ -31,14 +31,15 @@ class Evaluator
|
|
31
31
|
private
|
32
32
|
|
33
33
|
def eval_spec(user, config)
|
34
|
+
default_rule_id = 'default'
|
35
|
+
exposures = []
|
34
36
|
if config['enabled']
|
35
|
-
exposures = []
|
36
37
|
i = 0
|
37
38
|
until i >= config['rules'].length do
|
38
39
|
rule = config['rules'][i]
|
39
40
|
result = self.eval_rule(user, rule)
|
40
41
|
return $fetch_from_server if result == $fetch_from_server
|
41
|
-
exposures = exposures + result[
|
42
|
+
exposures = exposures + result['exposures'] if result['exposures'].is_a? Array
|
42
43
|
if result['value']
|
43
44
|
pass = self.eval_pass_percent(user, rule, config['salt'])
|
44
45
|
return ConfigResult.new(
|
@@ -52,9 +53,10 @@ class Evaluator
|
|
52
53
|
|
53
54
|
i += 1
|
54
55
|
end
|
56
|
+
elsif (default_rule_id = 'disabled')
|
55
57
|
end
|
56
58
|
|
57
|
-
ConfigResult.new(config['name'], false, config['defaultValue'],
|
59
|
+
ConfigResult.new(config['name'], false, config['defaultValue'], default_rule_id, exposures)
|
58
60
|
end
|
59
61
|
|
60
62
|
def eval_rule(user, rule)
|
@@ -68,14 +70,14 @@ class Evaluator
|
|
68
70
|
end
|
69
71
|
|
70
72
|
if result.is_a?(Hash)
|
71
|
-
exposures = exposures + result[
|
72
|
-
pass = false if result[
|
73
|
+
exposures = exposures + result['exposures'] if result['exposures'].is_a? Array
|
74
|
+
pass = false if result['value'] == false
|
73
75
|
elsif result == false
|
74
76
|
pass = false
|
75
77
|
end
|
76
78
|
i += 1
|
77
79
|
end
|
78
|
-
{
|
80
|
+
{ 'value' => pass, 'exposures' => exposures }
|
79
81
|
end
|
80
82
|
|
81
83
|
def eval_condition(user, condition)
|
@@ -99,14 +101,14 @@ class Evaluator
|
|
99
101
|
|
100
102
|
gate_value = other_gate_result&.gate_value == true
|
101
103
|
new_exposure = {
|
102
|
-
|
103
|
-
|
104
|
-
|
104
|
+
'gate' => target,
|
105
|
+
'gateValue' => gate_value ? 'true' : 'false',
|
106
|
+
'ruleID' => other_gate_result&.rule_id
|
105
107
|
}
|
106
108
|
exposures = other_gate_result&.secondary_exposures&.append(new_exposure)
|
107
109
|
return {
|
108
|
-
|
109
|
-
|
110
|
+
'value' => type == 'pass_gate' ? gate_value : !gate_value,
|
111
|
+
'exposures' => exposures
|
110
112
|
}
|
111
113
|
when 'ip_based'
|
112
114
|
value = get_value_from_user(user, field) || get_value_from_ip(user, field)
|
data/lib/network.rb
CHANGED
@@ -24,14 +24,14 @@ class Network
|
|
24
24
|
}).accept(:json)
|
25
25
|
begin
|
26
26
|
res = http.post(@api + endpoint, body: body)
|
27
|
-
rescue
|
27
|
+
rescue StandardError => e
|
28
28
|
## network error retry
|
29
|
-
return nil unless retries > 0
|
29
|
+
return nil, e unless retries > 0
|
30
30
|
sleep backoff
|
31
31
|
return post_helper(endpoint, body, retries - 1, backoff * @backoff_multiplier)
|
32
32
|
end
|
33
|
-
return res unless !res.status.success?
|
34
|
-
return nil unless retries > 0 && $retry_codes.include?(res.code)
|
33
|
+
return res, nil unless !res.status.success?
|
34
|
+
return nil, StandardError.new("Got an exception when making request to #{@api + endpoint}: #{res.to_s}") unless retries > 0 && $retry_codes.include?(res.code)
|
35
35
|
## status code retry
|
36
36
|
sleep backoff
|
37
37
|
post_helper(endpoint, body, retries - 1, backoff * @backoff_multiplier)
|
@@ -40,7 +40,7 @@ class Network
|
|
40
40
|
def check_gate(user, gate_name)
|
41
41
|
begin
|
42
42
|
request_body = JSON.generate({'user' => user&.serialize(false), 'gateName' => gate_name})
|
43
|
-
response = post_helper('check_gate', request_body)
|
43
|
+
response, _ = post_helper('check_gate', request_body)
|
44
44
|
return JSON.parse(response.body) unless response.nil?
|
45
45
|
false
|
46
46
|
rescue
|
@@ -51,7 +51,7 @@ class Network
|
|
51
51
|
def get_config(user, dynamic_config_name)
|
52
52
|
begin
|
53
53
|
request_body = JSON.generate({'user' => user&.serialize(false), 'configName' => dynamic_config_name})
|
54
|
-
response = post_helper('get_config', request_body)
|
54
|
+
response, _ = post_helper('get_config', request_body)
|
55
55
|
return JSON.parse(response.body) unless response.nil?
|
56
56
|
nil
|
57
57
|
rescue
|
@@ -61,13 +61,13 @@ class Network
|
|
61
61
|
|
62
62
|
def download_config_specs
|
63
63
|
begin
|
64
|
-
response = post_helper('download_config_specs', JSON.generate({'sinceTime' => @last_sync_time}))
|
65
|
-
return nil
|
64
|
+
response, e = post_helper('download_config_specs', JSON.generate({'sinceTime' => @last_sync_time}))
|
65
|
+
return nil, e if response.nil?
|
66
66
|
json_body = JSON.parse(response.body)
|
67
67
|
@last_sync_time = json_body['time']
|
68
|
-
return json_body
|
69
|
-
rescue
|
70
|
-
return nil
|
68
|
+
return json_body, nil
|
69
|
+
rescue StandardError => e
|
70
|
+
return nil, e
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
@@ -75,7 +75,7 @@ class Network
|
|
75
75
|
Thread.new do
|
76
76
|
loop do
|
77
77
|
sleep 10
|
78
|
-
specs = download_config_specs
|
78
|
+
specs, _ = download_config_specs
|
79
79
|
unless specs.nil?
|
80
80
|
callback.call(specs)
|
81
81
|
end
|
data/lib/statsig.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
require 'statsig_driver'
|
2
2
|
|
3
3
|
module Statsig
|
4
|
-
def self.initialize(secret_key, options = nil)
|
4
|
+
def self.initialize(secret_key, options = nil, error_callback = nil)
|
5
5
|
unless @shared_instance.nil?
|
6
6
|
puts 'Statsig already initialized.'
|
7
7
|
return @shared_instance
|
8
8
|
end
|
9
9
|
|
10
|
-
@shared_instance = StatsigDriver.new(secret_key, options)
|
10
|
+
@shared_instance = StatsigDriver.new(secret_key, options, error_callback)
|
11
11
|
end
|
12
12
|
|
13
13
|
def self.check_gate(user, gate_name)
|
data/lib/statsig_driver.rb
CHANGED
@@ -8,7 +8,7 @@ require 'statsig_user'
|
|
8
8
|
require 'spec_store'
|
9
9
|
|
10
10
|
class StatsigDriver
|
11
|
-
def initialize(secret_key, options = nil)
|
11
|
+
def initialize(secret_key, options = nil, error_callback = nil)
|
12
12
|
super()
|
13
13
|
if !secret_key.is_a?(String) || !secret_key.start_with?('secret-')
|
14
14
|
raise 'Invalid secret key provided. Provide your project secret key from the Statsig console'
|
@@ -17,7 +17,7 @@ class StatsigDriver
|
|
17
17
|
raise 'Invalid options provided. Either provide a valid StatsigOptions object or nil'
|
18
18
|
end
|
19
19
|
|
20
|
-
@options = options || StatsigOptions.new
|
20
|
+
@options = options || StatsigOptions.new
|
21
21
|
@shutdown = false
|
22
22
|
@secret_key = secret_key
|
23
23
|
@net = Network.new(secret_key, @options.api_url_base)
|
@@ -27,7 +27,7 @@ class StatsigDriver
|
|
27
27
|
}
|
28
28
|
@logger = StatsigLogger.new(@net, @statsig_metadata)
|
29
29
|
|
30
|
-
downloaded_specs = @net.download_config_specs
|
30
|
+
downloaded_specs, e = @net.download_config_specs
|
31
31
|
unless downloaded_specs.nil?
|
32
32
|
@initialized = true
|
33
33
|
end
|
@@ -36,6 +36,8 @@ class StatsigDriver
|
|
36
36
|
@evaluator = Evaluator.new(@store)
|
37
37
|
|
38
38
|
@polling_thread = @net.poll_for_changes(-> (config_specs) { @store.process(config_specs) })
|
39
|
+
|
40
|
+
error_callback.call(e) unless error_callback.nil?
|
39
41
|
end
|
40
42
|
|
41
43
|
def check_gate(user, gate_name)
|
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.
|
4
|
+
version: 1.7.0.beta.1
|
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-
|
11
|
+
date: 2021-10-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -141,9 +141,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
141
141
|
version: '0'
|
142
142
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
143
|
requirements:
|
144
|
-
- - "
|
144
|
+
- - ">"
|
145
145
|
- !ruby/object:Gem::Version
|
146
|
-
version:
|
146
|
+
version: 1.3.1
|
147
147
|
requirements: []
|
148
148
|
rubygems_version: 3.2.3
|
149
149
|
signing_key:
|