statsig 1.9.1 → 1.11.0
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/dynamic_config.rb +6 -0
- data/lib/evaluator.rb +2 -2
- data/lib/layer.rb +11 -0
- data/lib/spec_store.rb +4 -4
- data/lib/statsig.rb +2 -2
- data/lib/statsig_driver.rb +10 -4
- data/lib/statsig_logger.rb +7 -5
- data/lib/statsig_options.rb +15 -1
- metadata +11 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8f1e2b0340c9bbeb49888f54d13505bc7b89c8a70d33e5adaed1e4b95568798
|
4
|
+
data.tar.gz: f70a5060da61c965bbe7e93d0ee7a42cbb30fd0504228959aba7d5ca894278a2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cadde7dcab3590b3d9a3d44bc3856f847b5cb50e9b8f365c1287ebad6bff59a5f82aeaef74e8ab958fb6e8e489ee811df9998cf86f1c18b588389f6194f2f2c0
|
7
|
+
data.tar.gz: 879e6ee89157ee4e86032d0d28c6588f21236b3503955150f6e702d06feaac503a8572696c82fe40b086a1e6df17900952c7b08e35f46162df8c50938e0f1225
|
data/lib/dynamic_config.rb
CHANGED
@@ -13,4 +13,10 @@ class DynamicConfig
|
|
13
13
|
return default_value if @value.nil? || !@value.key?(index)
|
14
14
|
@value[index]
|
15
15
|
end
|
16
|
+
|
17
|
+
def get_typed(index, default_value)
|
18
|
+
return default_value if @value.nil? || !@value.key?(index)
|
19
|
+
return default_value if @value[index].class != default_value.class and default_value.class != TrueClass and default_value.class != FalseClass
|
20
|
+
@value[index]
|
21
|
+
end
|
16
22
|
end
|
data/lib/evaluator.rb
CHANGED
@@ -12,8 +12,8 @@ $type_dynamic_config = 'dynamic_config'
|
|
12
12
|
|
13
13
|
module Statsig
|
14
14
|
class Evaluator
|
15
|
-
def initialize(network, error_callback)
|
16
|
-
@spec_store = Statsig::SpecStore.new(network, error_callback)
|
15
|
+
def initialize(network, options, error_callback)
|
16
|
+
@spec_store = Statsig::SpecStore.new(network, error_callback, options.rulesets_sync_interval, options.idlists_sync_interval)
|
17
17
|
@ua_parser = UserAgentParser::Parser.new
|
18
18
|
CountryLookup.initialize
|
19
19
|
@initialized = true
|
data/lib/layer.rb
CHANGED
@@ -18,4 +18,15 @@ class Layer
|
|
18
18
|
|
19
19
|
@value[index]
|
20
20
|
end
|
21
|
+
|
22
|
+
def get_typed(index, default_value)
|
23
|
+
return default_value if @value.nil? || !@value.key?(index)
|
24
|
+
return default_value if @value[index].class != default_value.class and default_value.class != TrueClass and default_value.class != FalseClass
|
25
|
+
|
26
|
+
if @exposure_log_func.is_a? Proc
|
27
|
+
@exposure_log_func.call(self, index)
|
28
|
+
end
|
29
|
+
|
30
|
+
@value[index]
|
31
|
+
end
|
21
32
|
end
|
data/lib/spec_store.rb
CHANGED
@@ -5,10 +5,10 @@ require 'id_list'
|
|
5
5
|
|
6
6
|
module Statsig
|
7
7
|
class SpecStore
|
8
|
-
def initialize(network, error_callback = nil,
|
8
|
+
def initialize(network, error_callback = nil, rulesets_sync_interval = 10, id_lists_sync_interval = 60)
|
9
9
|
@network = network
|
10
10
|
@last_sync_time = 0
|
11
|
-
@
|
11
|
+
@rulesets_sync_interval = rulesets_sync_interval
|
12
12
|
@id_lists_sync_interval = id_lists_sync_interval
|
13
13
|
@store = {
|
14
14
|
:gates => {},
|
@@ -65,7 +65,7 @@ module Statsig
|
|
65
65
|
def sync_config_specs
|
66
66
|
Thread.new do
|
67
67
|
loop do
|
68
|
-
sleep @
|
68
|
+
sleep @rulesets_sync_interval
|
69
69
|
download_config_specs
|
70
70
|
end
|
71
71
|
end
|
@@ -145,7 +145,7 @@ module Statsig
|
|
145
145
|
next
|
146
146
|
end
|
147
147
|
|
148
|
-
#
|
148
|
+
# reset local list if server list returns a newer file
|
149
149
|
if server_list.file_id != local_list.file_id && server_list.creation_time >= local_list.creation_time
|
150
150
|
local_list = IDList.new(list)
|
151
151
|
local_list.size = 0
|
data/lib/statsig.rb
CHANGED
@@ -30,7 +30,7 @@ module Statsig
|
|
30
30
|
@shared_instance&.get_layer(user, layer_name)
|
31
31
|
end
|
32
32
|
|
33
|
-
def self.log_event(user, event_name, value, metadata)
|
33
|
+
def self.log_event(user, event_name, value = nil, metadata = nil)
|
34
34
|
ensure_initialized
|
35
35
|
@shared_instance&.log_event(user, event_name, value, metadata)
|
36
36
|
end
|
@@ -45,7 +45,7 @@ module Statsig
|
|
45
45
|
def self.get_statsig_metadata
|
46
46
|
{
|
47
47
|
'sdkType' => 'ruby-server',
|
48
|
-
'sdkVersion' => '1.
|
48
|
+
'sdkVersion' => '1.11.0',
|
49
49
|
}
|
50
50
|
end
|
51
51
|
|
data/lib/statsig_driver.rb
CHANGED
@@ -23,8 +23,8 @@ class StatsigDriver
|
|
23
23
|
@shutdown = false
|
24
24
|
@secret_key = secret_key
|
25
25
|
@net = Statsig::Network.new(secret_key, @options.api_url_base)
|
26
|
-
@logger = Statsig::StatsigLogger.new(@net)
|
27
|
-
@evaluator = Statsig::Evaluator.new(@net, error_callback)
|
26
|
+
@logger = Statsig::StatsigLogger.new(@net, @options)
|
27
|
+
@evaluator = Statsig::Evaluator.new(@net, @options, error_callback)
|
28
28
|
end
|
29
29
|
|
30
30
|
def check_gate(user, gate_name)
|
@@ -127,8 +127,14 @@ class StatsigDriver
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def validate_user(user)
|
130
|
-
if user.nil? ||
|
131
|
-
|
130
|
+
if user.nil? ||
|
131
|
+
!user.instance_of?(StatsigUser) ||
|
132
|
+
(
|
133
|
+
# user_id is nil and custom_ids is not a hash with entries
|
134
|
+
!user.user_id.is_a?(String) &&
|
135
|
+
(!user.custom_ids.is_a?(Hash) || user.custom_ids.size == 0)
|
136
|
+
)
|
137
|
+
raise 'Must provide a valid StatsigUser with a user_id or at least a custom ID. See https://docs.statsig.com/messages/serverRequiredUserID/ for more details.'
|
132
138
|
end
|
133
139
|
end
|
134
140
|
|
data/lib/statsig_logger.rb
CHANGED
@@ -6,15 +6,16 @@ $layer_exposure_event = 'statsig::layer_exposure'
|
|
6
6
|
|
7
7
|
module Statsig
|
8
8
|
class StatsigLogger
|
9
|
-
def initialize(network)
|
9
|
+
def initialize(network, options)
|
10
10
|
@network = network
|
11
11
|
@events = []
|
12
12
|
@background_flush = periodic_flush
|
13
|
+
@options = options
|
13
14
|
end
|
14
15
|
|
15
16
|
def log_event(event)
|
16
17
|
@events.push(event)
|
17
|
-
if @events.length >=
|
18
|
+
if @events.length >= @options.logging_max_buffer_size
|
18
19
|
flush
|
19
20
|
end
|
20
21
|
end
|
@@ -47,7 +48,7 @@ module Statsig
|
|
47
48
|
def log_layer_exposure(user, layer, parameter_name, config_evaluation)
|
48
49
|
exposures = config_evaluation.undelegated_sec_exps
|
49
50
|
allocated_experiment = ''
|
50
|
-
is_explicit = config_evaluation.explicit_parameters
|
51
|
+
is_explicit = (config_evaluation.explicit_parameters&.include? parameter_name) || false
|
51
52
|
if is_explicit
|
52
53
|
allocated_experiment = config_evaluation.config_delegate
|
53
54
|
exposures = config_evaluation.secondary_exposures
|
@@ -70,7 +71,7 @@ module Statsig
|
|
70
71
|
def periodic_flush
|
71
72
|
Thread.new do
|
72
73
|
loop do
|
73
|
-
sleep
|
74
|
+
sleep @options.logging_interval_seconds
|
74
75
|
flush
|
75
76
|
end
|
76
77
|
end
|
@@ -83,8 +84,9 @@ module Statsig
|
|
83
84
|
if @events.length == 0
|
84
85
|
return
|
85
86
|
end
|
86
|
-
|
87
|
+
events_clone = @events
|
87
88
|
@events = []
|
89
|
+
flush_events = events_clone.map { |e| e.serialize }
|
88
90
|
|
89
91
|
@network.post_logs(flush_events)
|
90
92
|
end
|
data/lib/statsig_options.rb
CHANGED
@@ -1,9 +1,23 @@
|
|
1
1
|
class StatsigOptions
|
2
2
|
attr_reader :environment
|
3
3
|
attr_reader :api_url_base
|
4
|
+
attr_reader :rulesets_sync_interval
|
5
|
+
attr_reader :idlists_sync_interval
|
6
|
+
attr_reader :logging_interval_seconds
|
7
|
+
attr_reader :logging_max_buffer_size
|
4
8
|
|
5
|
-
def initialize(
|
9
|
+
def initialize(
|
10
|
+
environment=nil,
|
11
|
+
api_url_base='https://statsigapi.net/v1',
|
12
|
+
rulesets_sync_interval: 10,
|
13
|
+
idlists_sync_interval: 60,
|
14
|
+
logging_interval_seconds: 60,
|
15
|
+
logging_max_buffer_size: 1000)
|
6
16
|
@environment = environment.is_a?(Hash) ? environment : nil
|
7
17
|
@api_url_base = api_url_base
|
18
|
+
@rulesets_sync_interval = rulesets_sync_interval
|
19
|
+
@idlists_sync_interval = idlists_sync_interval
|
20
|
+
@logging_interval_seconds = logging_interval_seconds
|
21
|
+
@logging_max_buffer_size = [logging_max_buffer_size, 1000].min
|
8
22
|
end
|
9
23
|
end
|
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.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Statsig, Inc
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-08-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -84,16 +84,22 @@ dependencies:
|
|
84
84
|
name: http
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - "
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '4.4'
|
90
|
+
- - "<"
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '6.0'
|
90
93
|
type: :runtime
|
91
94
|
prerelease: false
|
92
95
|
version_requirements: !ruby/object:Gem::Requirement
|
93
96
|
requirements:
|
94
|
-
- - "
|
97
|
+
- - ">="
|
95
98
|
- !ruby/object:Gem::Version
|
96
99
|
version: '4.4'
|
100
|
+
- - "<"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '6.0'
|
97
103
|
- !ruby/object:Gem::Dependency
|
98
104
|
name: ip3country
|
99
105
|
requirement: !ruby/object:Gem::Requirement
|
@@ -147,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
153
|
- !ruby/object:Gem::Version
|
148
154
|
version: '0'
|
149
155
|
requirements: []
|
150
|
-
rubygems_version: 3.3.
|
156
|
+
rubygems_version: 3.3.11
|
151
157
|
signing_key:
|
152
158
|
specification_version: 4
|
153
159
|
summary: Statsig server SDK for Ruby
|