statsig 1.30.0 → 1.32.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/api_config.rb +128 -0
- data/lib/client_initialize_helpers.rb +79 -108
- data/lib/config_result.rb +17 -32
- data/lib/constants.rb +60 -0
- data/lib/diagnostics.rb +21 -70
- data/lib/dynamic_config.rb +1 -24
- data/lib/error_boundary.rb +0 -5
- data/lib/evaluation_details.rb +5 -1
- data/lib/evaluation_helpers.rb +35 -3
- data/lib/evaluator.rb +332 -316
- data/lib/feature_gate.rb +0 -24
- data/lib/id_list.rb +1 -1
- data/lib/interfaces/data_store.rb +1 -1
- data/lib/interfaces/user_persistent_storage.rb +1 -1
- data/lib/layer.rb +1 -20
- data/lib/network.rb +6 -53
- data/lib/spec_store.rb +124 -115
- data/lib/statsig.rb +72 -97
- data/lib/statsig_driver.rb +73 -128
- data/lib/statsig_errors.rb +1 -1
- data/lib/statsig_event.rb +8 -8
- data/lib/statsig_logger.rb +29 -26
- data/lib/statsig_options.rb +0 -50
- data/lib/statsig_user.rb +27 -68
- data/lib/ua_parser.rb +1 -1
- data/lib/uri_helper.rb +1 -9
- data/lib/user_persistent_storage_utils.rb +0 -17
- metadata +4 -2
data/lib/statsig.rb
CHANGED
@@ -1,13 +1,9 @@
|
|
1
|
-
# typed: true
|
2
|
-
|
3
1
|
require 'statsig_driver'
|
4
|
-
|
2
|
+
|
5
3
|
require 'statsig_errors'
|
6
4
|
|
7
5
|
module Statsig
|
8
|
-
extend T::Sig
|
9
6
|
|
10
|
-
sig { params(secret_key: String, options: T.any(StatsigOptions, NilClass), error_callback: T.any(Method, Proc, NilClass)).void }
|
11
7
|
##
|
12
8
|
# Initializes the Statsig SDK.
|
13
9
|
#
|
@@ -21,46 +17,54 @@ module Statsig
|
|
21
17
|
return @shared_instance
|
22
18
|
end
|
23
19
|
|
24
|
-
self.bind_sorbet_loggers(options)
|
25
|
-
|
26
20
|
@shared_instance = StatsigDriver.new(secret_key, options, error_callback)
|
27
21
|
end
|
28
22
|
|
29
|
-
class GetGateOptions
|
30
|
-
|
31
|
-
|
23
|
+
class GetGateOptions
|
24
|
+
attr_accessor :disable_log_exposure, :skip_evaluation, :disable_evaluation_details
|
25
|
+
|
26
|
+
def initialize(disable_log_exposure: false, skip_evaluation: false, disable_evaluation_details: false)
|
27
|
+
@disable_log_exposure = disable_log_exposure
|
28
|
+
@skip_evaluation = skip_evaluation
|
29
|
+
@disable_evaluation_details = disable_evaluation_details
|
30
|
+
end
|
32
31
|
end
|
33
32
|
|
34
|
-
sig { params(user: StatsigUser, gate_name: String, options: GetGateOptions).returns(FeatureGate) }
|
35
33
|
##
|
36
34
|
# Gets the gate, evaluated against the given user. An exposure event will automatically be logged for the gate.
|
37
35
|
#
|
38
|
-
# @param user A StatsigUser object used for the evaluation
|
39
|
-
# @param gate_name The name of the gate being checked
|
40
|
-
# @param options Additional options for evaluating the gate
|
41
|
-
|
36
|
+
# @param [StatsigUser] user A StatsigUser object used for the evaluation
|
37
|
+
# @param [String] gate_name The name of the gate being checked
|
38
|
+
# @param [GetGateOptions] options Additional options for evaluating the gate
|
39
|
+
# @return [FeatureGate]
|
40
|
+
def self.get_gate(user, gate_name, options)
|
42
41
|
ensure_initialized
|
43
42
|
@shared_instance&.get_gate(user, gate_name, options)
|
44
43
|
end
|
45
44
|
|
46
|
-
class CheckGateOptions
|
47
|
-
|
45
|
+
class CheckGateOptions
|
46
|
+
attr_accessor :disable_log_exposure, :disable_evaluation_details
|
47
|
+
|
48
|
+
def initialize(disable_log_exposure: false, disable_evaluation_details: false)
|
49
|
+
@disable_log_exposure = disable_log_exposure
|
50
|
+
@disable_evaluation_details = disable_evaluation_details
|
51
|
+
end
|
48
52
|
end
|
49
53
|
|
50
|
-
sig { params(user: StatsigUser, gate_name: String, options: CheckGateOptions).returns(T::Boolean) }
|
51
54
|
##
|
52
55
|
# Gets the boolean result of a gate, evaluated against the given user. An exposure event will automatically be logged for the gate.
|
53
56
|
#
|
54
|
-
# @param user A StatsigUser object used for the evaluation
|
55
|
-
# @param gate_name The name of the gate being checked
|
56
|
-
# @param options Additional options for evaluating the gate
|
57
|
-
|
57
|
+
# @param [StatsigUser] user A StatsigUser object used for the evaluation
|
58
|
+
# @param [String] gate_name The name of the gate being checked
|
59
|
+
# @param [CheckGateOptions] options Additional options for evaluating the gate
|
60
|
+
# @return [Boolean]
|
61
|
+
def self.check_gate(user, gate_name, options = nil)
|
58
62
|
ensure_initialized
|
59
63
|
@shared_instance&.check_gate(user, gate_name, options)
|
60
64
|
end
|
61
65
|
|
62
|
-
sig { params(user: StatsigUser, gate_name: String).returns(T::Boolean) }
|
63
66
|
##
|
67
|
+
# @deprecated - use check_gate(user, gate, options) and disable_exposure_logging in options
|
64
68
|
# Gets the boolean result of a gate, evaluated against the given user.
|
65
69
|
#
|
66
70
|
# @param user A StatsigUser object used for the evaluation
|
@@ -70,7 +74,6 @@ module Statsig
|
|
70
74
|
@shared_instance&.check_gate(user, gate_name, CheckGateOptions.new(disable_log_exposure: true))
|
71
75
|
end
|
72
76
|
|
73
|
-
sig { params(user: StatsigUser, gate_name: String).void }
|
74
77
|
##
|
75
78
|
# Logs an exposure event for the gate
|
76
79
|
#
|
@@ -81,34 +84,39 @@ module Statsig
|
|
81
84
|
@shared_instance&.manually_log_gate_exposure(user, gate_name)
|
82
85
|
end
|
83
86
|
|
84
|
-
class GetConfigOptions
|
85
|
-
|
87
|
+
class GetConfigOptions
|
88
|
+
attr_accessor :disable_log_exposure, :disable_evaluation_details
|
89
|
+
|
90
|
+
def initialize(disable_log_exposure: false, disable_evaluation_details: false)
|
91
|
+
@disable_log_exposure = disable_log_exposure
|
92
|
+
@disable_evaluation_details = disable_evaluation_details
|
93
|
+
end
|
86
94
|
end
|
87
95
|
|
88
|
-
sig { params(user: StatsigUser, dynamic_config_name: String, options: GetConfigOptions).returns(DynamicConfig) }
|
89
96
|
##
|
90
97
|
# Get the values of a dynamic config, evaluated against the given user. An exposure event will automatically be logged for the dynamic config.
|
91
98
|
#
|
92
|
-
# @param user A StatsigUser object used for the evaluation
|
93
|
-
# @param dynamic_config_name The name of the dynamic config
|
94
|
-
# @param options Additional options for evaluating the config
|
95
|
-
|
99
|
+
# @param [StatsigUser] user A StatsigUser object used for the evaluation
|
100
|
+
# @param [String] dynamic_config_name The name of the dynamic config
|
101
|
+
# @param [GetConfigOptions] options Additional options for evaluating the config
|
102
|
+
# @return [DynamicConfig]
|
103
|
+
def self.get_config(user, dynamic_config_name, options = nil)
|
96
104
|
ensure_initialized
|
97
105
|
@shared_instance&.get_config(user, dynamic_config_name, options)
|
98
106
|
end
|
99
107
|
|
100
|
-
sig { params(user: StatsigUser, dynamic_config_name: String).returns(DynamicConfig) }
|
101
108
|
##
|
109
|
+
# @deprecated - use get_config(user, config, options) and disable_exposure_logging in options
|
102
110
|
# Get the values of a dynamic config, evaluated against the given user.
|
103
111
|
#
|
104
|
-
# @param user A StatsigUser object used for the evaluation
|
105
|
-
# @param dynamic_config_name The name of the dynamic config
|
112
|
+
# @param [StatsigUser] user A StatsigUser object used for the evaluation
|
113
|
+
# @param [String] dynamic_config_name The name of the dynamic config
|
114
|
+
# @return [DynamicConfig]
|
106
115
|
def self.get_config_with_exposure_logging_disabled(user, dynamic_config_name)
|
107
116
|
ensure_initialized
|
108
117
|
@shared_instance&.get_config(user, dynamic_config_name, GetConfigOptions.new(disable_log_exposure: true))
|
109
118
|
end
|
110
119
|
|
111
|
-
sig { params(user: StatsigUser, dynamic_config: String).void }
|
112
120
|
##
|
113
121
|
# Logs an exposure event for the dynamic config
|
114
122
|
#
|
@@ -119,35 +127,38 @@ module Statsig
|
|
119
127
|
@shared_instance&.manually_log_config_exposure(user, dynamic_config)
|
120
128
|
end
|
121
129
|
|
122
|
-
class GetExperimentOptions
|
123
|
-
|
124
|
-
|
130
|
+
class GetExperimentOptions
|
131
|
+
attr_accessor :disable_log_exposure, :user_persisted_values, :disable_evaluation_details
|
132
|
+
|
133
|
+
def initialize(disable_log_exposure: false, user_persisted_values: nil, disable_evaluation_details: false)
|
134
|
+
@disable_log_exposure = disable_log_exposure
|
135
|
+
@user_persisted_values = user_persisted_values
|
136
|
+
@disable_evaluation_details = disable_evaluation_details
|
137
|
+
end
|
125
138
|
end
|
126
139
|
|
127
|
-
sig { params(user: StatsigUser, experiment_name: String, options: GetExperimentOptions).returns(DynamicConfig) }
|
128
140
|
##
|
129
141
|
# Get the values of an experiment, evaluated against the given user. An exposure event will automatically be logged for the experiment.
|
130
142
|
#
|
131
|
-
# @param user A StatsigUser object used for the evaluation
|
132
|
-
# @param experiment_name The name of the experiment
|
133
|
-
# @param options Additional options for evaluating the experiment
|
134
|
-
def self.get_experiment(user, experiment_name, options =
|
143
|
+
# @param [StatsigUser] user A StatsigUser object used for the evaluation
|
144
|
+
# @param [String] experiment_name The name of the experiment
|
145
|
+
# @param [GetExperimentOptions] options Additional options for evaluating the experiment
|
146
|
+
def self.get_experiment(user, experiment_name, options = nil)
|
135
147
|
ensure_initialized
|
136
148
|
@shared_instance&.get_experiment(user, experiment_name, options)
|
137
149
|
end
|
138
150
|
|
139
|
-
sig { params(user: StatsigUser, experiment_name: String).returns(DynamicConfig) }
|
140
151
|
##
|
152
|
+
# @deprecated - use get_experiment(user, experiment, options) and disable_exposure_logging in options
|
141
153
|
# Get the values of an experiment, evaluated against the given user.
|
142
154
|
#
|
143
|
-
# @param user A StatsigUser object used for the evaluation
|
144
|
-
# @param experiment_name The name of the experiment
|
155
|
+
# @param [StatsigUser] user A StatsigUser object used for the evaluation
|
156
|
+
# @param [String] experiment_name The name of the experiment
|
145
157
|
def self.get_experiment_with_exposure_logging_disabled(user, experiment_name)
|
146
158
|
ensure_initialized
|
147
159
|
@shared_instance&.get_experiment(user, experiment_name, GetExperimentOptions.new(disable_log_exposure: true))
|
148
160
|
end
|
149
161
|
|
150
|
-
sig { params(user: StatsigUser, experiment_name: String).void }
|
151
162
|
##
|
152
163
|
# Logs an exposure event for the experiment
|
153
164
|
#
|
@@ -158,30 +169,34 @@ module Statsig
|
|
158
169
|
@shared_instance&.manually_log_config_exposure(user, experiment_name)
|
159
170
|
end
|
160
171
|
|
161
|
-
sig { params(user: StatsigUser, id_type: String).returns(UserPersistedValues) }
|
162
172
|
def self.get_user_persisted_values(user, id_type)
|
163
173
|
ensure_initialized
|
164
174
|
@shared_instance&.get_user_persisted_values(user, id_type)
|
165
175
|
end
|
166
176
|
|
167
|
-
class GetLayerOptions
|
168
|
-
|
177
|
+
class GetLayerOptions
|
178
|
+
attr_accessor :disable_log_exposure, :disable_evaluation_details
|
179
|
+
|
180
|
+
def initialize(disable_log_exposure: false, disable_evaluation_details: false)
|
181
|
+
@disable_log_exposure = disable_log_exposure
|
182
|
+
@disable_evaluation_details = disable_evaluation_details
|
183
|
+
end
|
169
184
|
end
|
170
185
|
|
171
|
-
sig { params(user: StatsigUser, layer_name: String, options: GetLayerOptions).returns(Layer) }
|
172
186
|
##
|
173
187
|
# Get the values of a layer, evaluated against the given user.
|
174
188
|
# Exposure events will be fired when get or get_typed is called on the resulting Layer class.
|
175
189
|
#
|
176
|
-
# @param user A StatsigUser object used for the evaluation
|
177
|
-
# @param layer_name The name of the layer
|
178
|
-
|
190
|
+
# @param [StatsigUser] user A StatsigUser object used for the evaluation
|
191
|
+
# @param [String] layer_name The name of the layer
|
192
|
+
# @param [GetLayerOptions] options Configuration of how this method call should behave
|
193
|
+
def self.get_layer(user, layer_name, options = nil)
|
179
194
|
ensure_initialized
|
180
195
|
@shared_instance&.get_layer(user, layer_name, options)
|
181
196
|
end
|
182
197
|
|
183
|
-
sig { params(user: StatsigUser, layer_name: String).returns(Layer) }
|
184
198
|
##
|
199
|
+
# @deprecated - use get_layer(user, gate, options) and disable_exposure_logging in options
|
185
200
|
# Get the values of a layer, evaluated against the given user.
|
186
201
|
#
|
187
202
|
# @param user A StatsigUser object used for the evaluation
|
@@ -191,7 +206,6 @@ module Statsig
|
|
191
206
|
@shared_instance&.get_layer(user, layer_name, GetLayerOptions.new(disable_log_exposure: true))
|
192
207
|
end
|
193
208
|
|
194
|
-
sig { params(user: StatsigUser, layer_name: String, parameter_name: String).void }
|
195
209
|
##
|
196
210
|
# Logs an exposure event for the parameter in the given layer
|
197
211
|
#
|
@@ -203,10 +217,6 @@ module Statsig
|
|
203
217
|
@shared_instance&.manually_log_layer_parameter_exposure(user, layer_name, parameter_name)
|
204
218
|
end
|
205
219
|
|
206
|
-
sig { params(user: StatsigUser,
|
207
|
-
event_name: String,
|
208
|
-
value: T.any(String, Integer, Float, NilClass),
|
209
|
-
metadata: T.any(T::Hash[String, T.untyped], NilClass)).void }
|
210
220
|
##
|
211
221
|
# Logs an event to Statsig with the provided values.
|
212
222
|
#
|
@@ -229,7 +239,6 @@ module Statsig
|
|
229
239
|
@shared_instance&.manually_sync_idlists
|
230
240
|
end
|
231
241
|
|
232
|
-
sig { returns(T::Array[String]) }
|
233
242
|
##
|
234
243
|
# Returns a list of all gate names
|
235
244
|
#
|
@@ -238,7 +247,6 @@ module Statsig
|
|
238
247
|
@shared_instance&.list_gates
|
239
248
|
end
|
240
249
|
|
241
|
-
sig { returns(T::Array[String]) }
|
242
250
|
##
|
243
251
|
# Returns a list of all config names
|
244
252
|
#
|
@@ -247,7 +255,6 @@ module Statsig
|
|
247
255
|
@shared_instance&.list_configs
|
248
256
|
end
|
249
257
|
|
250
|
-
sig { returns(T::Array[String]) }
|
251
258
|
##
|
252
259
|
# Returns a list of all experiment names
|
253
260
|
#
|
@@ -256,7 +263,6 @@ module Statsig
|
|
256
263
|
@shared_instance&.list_experiments
|
257
264
|
end
|
258
265
|
|
259
|
-
sig { returns(T::Array[String]) }
|
260
266
|
##
|
261
267
|
# Returns a list of all autotune names
|
262
268
|
#
|
@@ -265,7 +271,6 @@ module Statsig
|
|
265
271
|
@shared_instance&.list_autotunes
|
266
272
|
end
|
267
273
|
|
268
|
-
sig { returns(T::Array[String]) }
|
269
274
|
##
|
270
275
|
# Returns a list of all layer names
|
271
276
|
#
|
@@ -274,7 +279,6 @@ module Statsig
|
|
274
279
|
@shared_instance&.list_layers
|
275
280
|
end
|
276
281
|
|
277
|
-
sig { void }
|
278
282
|
##
|
279
283
|
# Stops all Statsig activity and flushes any pending events.
|
280
284
|
def self.shutdown
|
@@ -284,7 +288,6 @@ module Statsig
|
|
284
288
|
@shared_instance = nil
|
285
289
|
end
|
286
290
|
|
287
|
-
sig { params(gate_name: String, gate_value: T::Boolean).void }
|
288
291
|
##
|
289
292
|
# Sets a value to be returned for the given gate instead of the actual evaluated value.
|
290
293
|
#
|
@@ -295,7 +298,6 @@ module Statsig
|
|
295
298
|
@shared_instance&.override_gate(gate_name, gate_value)
|
296
299
|
end
|
297
300
|
|
298
|
-
sig { params(config_name: String, config_value: Hash).void }
|
299
301
|
##
|
300
302
|
# Sets a value to be returned for the given dynamic config/experiment instead of the actual evaluated value.
|
301
303
|
#
|
@@ -306,7 +308,6 @@ module Statsig
|
|
306
308
|
@shared_instance&.override_config(config_name, config_value)
|
307
309
|
end
|
308
310
|
|
309
|
-
sig { params(user: StatsigUser, hash: String, client_sdk_key: T.any(String, NilClass)).returns(T.any(T::Hash[String, T.untyped], NilClass)) }
|
310
311
|
##
|
311
312
|
# Gets all evaluated values for the given user.
|
312
313
|
# These values can then be given to a Statsig Client SDK via bootstrapping.
|
@@ -321,13 +322,12 @@ module Statsig
|
|
321
322
|
@shared_instance&.get_client_initialize_response(user, hash, client_sdk_key)
|
322
323
|
end
|
323
324
|
|
324
|
-
sig { returns(T::Hash[String, String]) }
|
325
325
|
##
|
326
326
|
# Internal Statsig metadata for this SDK
|
327
327
|
def self.get_statsig_metadata
|
328
328
|
{
|
329
329
|
'sdkType' => 'ruby-server',
|
330
|
-
'sdkVersion' => '1.
|
330
|
+
'sdkVersion' => '1.32.0',
|
331
331
|
'languageVersion' => RUBY_VERSION
|
332
332
|
}
|
333
333
|
end
|
@@ -340,29 +340,4 @@ module Statsig
|
|
340
340
|
end
|
341
341
|
end
|
342
342
|
|
343
|
-
|
344
|
-
def self.bind_sorbet_loggers(options)
|
345
|
-
if options&.disable_sorbet_logging_handlers == true
|
346
|
-
return
|
347
|
-
end
|
348
|
-
|
349
|
-
T::Configuration.call_validation_error_handler = lambda do |signature, opts|
|
350
|
-
puts "[Type Error] " + opts[:pretty_message]
|
351
|
-
end
|
352
|
-
|
353
|
-
T::Configuration.inline_type_error_handler = lambda do |error, opts|
|
354
|
-
puts "[Type Error] " + error.message
|
355
|
-
end
|
356
|
-
|
357
|
-
T::Configuration.sig_builder_error_handler = lambda do |error, location|
|
358
|
-
puts "[Type Error] " + error.message
|
359
|
-
end
|
360
|
-
|
361
|
-
T::Configuration.sig_validation_error_handler = lambda do |error, opts|
|
362
|
-
puts "[Type Error] " + error.message
|
363
|
-
end
|
364
|
-
|
365
|
-
return
|
366
|
-
end
|
367
|
-
|
368
|
-
end
|
343
|
+
end
|