statsig 1.31.1 → 1.33.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,3 @@
1
- # typed: true
2
-
3
1
  require 'config_result'
4
2
  require 'evaluator'
5
3
  require 'network'
@@ -13,13 +11,11 @@ require 'dynamic_config'
13
11
  require 'feature_gate'
14
12
  require 'error_boundary'
15
13
  require 'layer'
16
- require 'sorbet-runtime'
14
+
17
15
  require 'diagnostics'
18
16
 
19
17
  class StatsigDriver
20
- extend T::Sig
21
18
 
22
- sig { params(secret_key: String, options: T.any(StatsigOptions, NilClass), error_callback: T.any(Method, Proc, NilClass)).void }
23
19
  def initialize(secret_key, options = nil, error_callback = nil)
24
20
  unless secret_key.start_with?('secret-')
25
21
  raise Statsig::ValueError.new('Invalid secret key provided. Provide your project secret key from the Statsig console')
@@ -47,26 +43,23 @@ class StatsigDriver
47
43
  }, caller: __method__.to_s)
48
44
  end
49
45
 
50
- sig do
51
- params(
52
- user: StatsigUser,
53
- gate_name: String,
54
- disable_log_exposure: T::Boolean,
55
- skip_evaluation: T::Boolean
56
- ).returns(FeatureGate)
57
- end
58
- def get_gate_impl(user, gate_name, disable_log_exposure: false, skip_evaluation: false)
46
+ def get_gate_impl(
47
+ user,
48
+ gate_name,
49
+ disable_log_exposure: false,
50
+ skip_evaluation: false,
51
+ disable_evaluation_details: false,
52
+ ignore_local_overrides: false
53
+ )
59
54
  if skip_evaluation
60
55
  gate = @store.get_gate(gate_name)
61
56
  return FeatureGate.new(gate_name) if gate.nil?
62
- return FeatureGate.new(gate['name'], target_app_ids: gate['targetAppIDs'])
57
+ return FeatureGate.new(gate.name, target_app_ids: gate.target_app_ids)
63
58
  end
64
59
  user = verify_inputs(user, gate_name, 'gate_name')
65
60
 
66
- res = @evaluator.check_gate(user, gate_name)
67
- if res.nil?
68
- res = Statsig::ConfigResult.new(gate_name)
69
- end
61
+ res = Statsig::ConfigResult.new(name: gate_name, disable_exposures: disable_log_exposure, disable_evaluation_details: disable_evaluation_details)
62
+ @evaluator.check_gate(user, gate_name, res, ignore_local_overrides: ignore_local_overrides)
70
63
 
71
64
  unless disable_log_exposure
72
65
  @logger.log_gate_exposure(
@@ -76,63 +69,82 @@ class StatsigDriver
76
69
  FeatureGate.from_config_result(res)
77
70
  end
78
71
 
79
- sig { params(user: StatsigUser, gate_name: String, options: Statsig::GetGateOptions).returns(FeatureGate) }
80
- def get_gate(user, gate_name, options = Statsig::GetGateOptions.new)
72
+ def get_gate(user, gate_name, options = nil)
81
73
  @err_boundary.capture(task: lambda {
82
74
  run_with_diagnostics(task: lambda {
83
- get_gate_impl(user, gate_name, disable_log_exposure: options.disable_log_exposure, skip_evaluation: options.skip_evaluation)
75
+ get_gate_impl(user, gate_name,
76
+ disable_log_exposure: options&.disable_log_exposure == true,
77
+ skip_evaluation: options&.skip_evaluation == true,
78
+ disable_evaluation_details: options&.disable_evaluation_details == true
79
+ )
84
80
  }, caller: __method__.to_s)
85
81
  }, recover: -> { false }, caller: __method__.to_s)
86
82
  end
87
83
 
88
- sig { params(user: StatsigUser, gate_name: String, options: Statsig::CheckGateOptions).returns(T::Boolean) }
89
- def check_gate(user, gate_name, options = Statsig::CheckGateOptions.new)
84
+ def check_gate(user, gate_name, options = nil)
90
85
  @err_boundary.capture(task: lambda {
91
86
  run_with_diagnostics(task: lambda {
92
- get_gate_impl(user, gate_name, disable_log_exposure: options.disable_log_exposure).value
87
+ get_gate_impl(
88
+ user,
89
+ gate_name,
90
+ disable_log_exposure: options&.disable_log_exposure == true,
91
+ disable_evaluation_details: options&.disable_evaluation_details == true,
92
+ ignore_local_overrides: options&.ignore_local_overrides == true
93
+ ).value
93
94
  }, caller: __method__.to_s)
94
95
  }, recover: -> { false }, caller: __method__.to_s)
95
96
  end
96
97
 
97
- sig { params(user: StatsigUser, gate_name: String).void }
98
98
  def manually_log_gate_exposure(user, gate_name)
99
99
  @err_boundary.capture(task: lambda {
100
- res = @evaluator.check_gate(user, gate_name)
101
- context = { 'is_manual_exposure' => true }
100
+ res = Statsig::ConfigResult.new(name: gate_name)
101
+ @evaluator.check_gate(user, gate_name, res)
102
+ context = { :is_manual_exposure => true }
102
103
  @logger.log_gate_exposure(user, gate_name, res.gate_value, res.rule_id, res.secondary_exposures, res.evaluation_details, context)
103
104
  })
104
105
  end
105
106
 
106
- sig { params(user: StatsigUser, dynamic_config_name: String, options: Statsig::GetConfigOptions).returns(DynamicConfig) }
107
- def get_config(user, dynamic_config_name, options = Statsig::GetConfigOptions.new)
107
+ def get_config(user, dynamic_config_name, options = nil)
108
108
  @err_boundary.capture(task: lambda {
109
109
  run_with_diagnostics(task: lambda {
110
110
  user = verify_inputs(user, dynamic_config_name, "dynamic_config_name")
111
- get_config_impl(user, dynamic_config_name, options.disable_log_exposure)
111
+ get_config_impl(
112
+ user,
113
+ dynamic_config_name,
114
+ options&.disable_log_exposure == true,
115
+ disable_evaluation_details: options&.disable_evaluation_details == true,
116
+ ignore_local_overrides: options&.ignore_local_overrides == true
117
+ )
112
118
  }, caller: __method__.to_s)
113
119
  }, recover: -> { DynamicConfig.new(dynamic_config_name) }, caller: __method__.to_s)
114
120
  end
115
121
 
116
- sig { params(user: StatsigUser, experiment_name: String, options: Statsig::GetExperimentOptions).returns(DynamicConfig) }
117
- def get_experiment(user, experiment_name, options = Statsig::GetExperimentOptions.new)
122
+ def get_experiment(user, experiment_name, options = nil)
118
123
  @err_boundary.capture(task: lambda {
119
124
  run_with_diagnostics(task: lambda {
120
125
  user = verify_inputs(user, experiment_name, "experiment_name")
121
- get_config_impl(user, experiment_name, options.disable_log_exposure, user_persisted_values: options.user_persisted_values)
126
+ get_config_impl(
127
+ user,
128
+ experiment_name,
129
+ options&.disable_log_exposure == true,
130
+ user_persisted_values: options&.user_persisted_values,
131
+ disable_evaluation_details: options&.disable_evaluation_details == true,
132
+ ignore_local_overrides: options&.ignore_local_overrides == true
133
+ )
122
134
  }, caller: __method__.to_s)
123
135
  }, recover: -> { DynamicConfig.new(experiment_name) }, caller: __method__.to_s)
124
136
  end
125
137
 
126
- sig { params(user: StatsigUser, config_name: String).void }
127
138
  def manually_log_config_exposure(user, config_name)
128
139
  @err_boundary.capture(task: lambda {
129
- res = @evaluator.get_config(user, config_name)
130
- context = { 'is_manual_exposure' => true }
140
+ res = Statsig::ConfigResult.new(name: config_name)
141
+ @evaluator.get_config(user, config_name, res)
142
+
143
+ context = { :is_manual_exposure => true }
131
144
  @logger.log_config_exposure(user, res.name, res.rule_id, res.secondary_exposures, res.evaluation_details, context)
132
145
  }, caller: __method__.to_s)
133
146
  end
134
147
 
135
- sig { params(user: StatsigUser, id_type: String).returns(Statsig::UserPersistedValues) }
136
148
  def get_user_persisted_values(user, id_type)
137
149
  @err_boundary.capture(task: lambda {
138
150
  persisted_values = @persistent_storage_utils.get_user_persisted_values(user, id_type)
@@ -142,31 +154,34 @@ class StatsigDriver
142
154
  }, caller: __method__.to_s)
143
155
  end
144
156
 
145
- sig { params(user: StatsigUser, layer_name: String, options: Statsig::GetLayerOptions).returns(Layer) }
146
- def get_layer(user, layer_name, options = Statsig::GetLayerOptions.new)
157
+ def get_layer(user, layer_name, options = nil)
147
158
  @err_boundary.capture(task: lambda {
148
159
  run_with_diagnostics(task: lambda {
149
160
  user = verify_inputs(user, layer_name, "layer_name")
150
-
151
- res = @evaluator.get_layer(user, layer_name)
152
- if res.nil?
153
- res = Statsig::ConfigResult.new(layer_name)
154
- end
155
-
156
- exposure_log_func = !options.disable_log_exposure ? lambda { |layer, parameter_name|
161
+ exposures_disabled = options&.disable_log_exposure == true
162
+ res = Statsig::ConfigResult.new(
163
+ name: layer_name,
164
+ disable_exposures: exposures_disabled,
165
+ disable_evaluation_details: options&.disable_evaluation_details == true
166
+ )
167
+ @evaluator.get_layer(user, layer_name, res)
168
+
169
+ exposure_log_func = !exposures_disabled ? lambda { |layer, parameter_name|
157
170
  @logger.log_layer_exposure(user, layer, parameter_name, res)
158
171
  } : nil
172
+
159
173
  Layer.new(res.name, res.json_value, res.rule_id, res.group_name, res.config_delegate, exposure_log_func)
160
174
  }, caller: __method__.to_s)
161
175
  }, recover: lambda { Layer.new(layer_name) }, caller: __method__.to_s)
162
176
  end
163
177
 
164
- sig { params(user: StatsigUser, layer_name: String, parameter_name: String).void }
165
178
  def manually_log_layer_parameter_exposure(user, layer_name, parameter_name)
166
179
  @err_boundary.capture(task: lambda {
167
- res = @evaluator.get_layer(user, layer_name)
180
+ res = Statsig::ConfigResult.new(name: layer_name)
181
+ @evaluator.get_layer(user, layer_name, res)
182
+
168
183
  layer = Layer.new(layer_name, res.json_value, res.rule_id, res.group_name, res.config_delegate)
169
- context = { 'is_manual_exposure' => true }
184
+ context = { :is_manual_exposure => true }
170
185
  @logger.log_layer_exposure(user, layer, parameter_name, res, context)
171
186
  }, caller: __method__.to_s)
172
187
  end
@@ -200,35 +215,30 @@ class StatsigDriver
200
215
  }, caller: __method__.to_s)
201
216
  end
202
217
 
203
- sig { returns(T::Array[String]) }
204
218
  def list_gates
205
219
  @err_boundary.capture(task: lambda {
206
220
  @evaluator.list_gates
207
221
  }, caller: __method__.to_s)
208
222
  end
209
223
 
210
- sig { returns(T::Array[String]) }
211
224
  def list_configs
212
225
  @err_boundary.capture(task: lambda {
213
226
  @evaluator.list_configs
214
227
  }, caller: __method__.to_s)
215
228
  end
216
229
 
217
- sig { returns(T::Array[String]) }
218
230
  def list_experiments
219
231
  @err_boundary.capture(task: lambda {
220
232
  @evaluator.list_experiments
221
233
  }, caller: __method__.to_s)
222
234
  end
223
235
 
224
- sig { returns(T::Array[String]) }
225
236
  def list_autotunes
226
237
  @err_boundary.capture(task: lambda {
227
238
  @evaluator.list_autotunes
228
239
  }, caller: __method__.to_s)
229
240
  end
230
241
 
231
- sig { returns(T::Array[String]) }
232
242
  def list_layers
233
243
  @err_boundary.capture(task: lambda {
234
244
  @evaluator.list_layers
@@ -249,20 +259,45 @@ class StatsigDriver
249
259
  }, caller: __method__.to_s)
250
260
  end
251
261
 
262
+ def remove_gate_override(gate_name)
263
+ @err_boundary.capture(task: lambda {
264
+ @evaluator.remove_gate_override(gate_name)
265
+ }, caller: __method__.to_s)
266
+ end
267
+
268
+ def clear_gate_overrides
269
+ @err_boundary.capture(task: lambda {
270
+ @evaluator.clear_gate_overrides
271
+ }, caller: __method__.to_s)
272
+ end
273
+
252
274
  def override_config(config_name, config_value)
253
275
  @err_boundary.capture(task: lambda {
254
276
  @evaluator.override_config(config_name, config_value)
255
277
  }, caller: __method__.to_s)
256
278
  end
257
279
 
280
+ def remove_config_override(config_name)
281
+ @err_boundary.capture(task: lambda {
282
+ @evaluator.remove_config_override(config_name)
283
+ }, caller: __method__.to_s)
284
+ end
285
+
286
+ def clear_config_overrides
287
+ @err_boundary.capture(task: lambda {
288
+ @evaluator.clear_config_overrides
289
+ }, caller: __method__.to_s)
290
+ end
291
+
258
292
  # @param [StatsigUser] user
259
293
  # @param [String | nil] client_sdk_key
294
+ # @param [Boolean] include_local_overrides
260
295
  # @return [Hash]
261
- def get_client_initialize_response(user, hash, client_sdk_key)
296
+ def get_client_initialize_response(user, hash, client_sdk_key, include_local_overrides)
262
297
  @err_boundary.capture(task: lambda {
263
298
  validate_user(user)
264
299
  normalize_user(user)
265
- @evaluator.get_client_initialize_response(user, hash, client_sdk_key)
300
+ @evaluator.get_client_initialize_response(user, hash, client_sdk_key, include_local_overrides)
266
301
  }, recover: -> { nil }, caller: __method__.to_s)
267
302
  end
268
303
 
@@ -297,7 +332,6 @@ class StatsigDriver
297
332
  return res
298
333
  end
299
334
 
300
- sig { params(user: StatsigUser, config_name: String, variable_name: String).returns(StatsigUser) }
301
335
  def verify_inputs(user, config_name, variable_name)
302
336
  validate_user(user)
303
337
  if !config_name.is_a?(String) || config_name.empty?
@@ -309,19 +343,13 @@ class StatsigDriver
309
343
  normalize_user(user)
310
344
  end
311
345
 
312
- sig do
313
- params(
314
- user: StatsigUser,
315
- config_name: String,
316
- disable_log_exposure: T::Boolean,
317
- user_persisted_values: T.nilable(Statsig::UserPersistedValues)
318
- ).returns(DynamicConfig)
319
- end
320
- def get_config_impl(user, config_name, disable_log_exposure, user_persisted_values: nil)
321
- res = @evaluator.get_config(user, config_name, user_persisted_values: user_persisted_values)
322
- if res.nil?
323
- res = Statsig::ConfigResult.new(config_name)
324
- end
346
+ def get_config_impl(user, config_name, disable_log_exposure, user_persisted_values: nil, disable_evaluation_details: false, ignore_local_overrides: false)
347
+ res = Statsig::ConfigResult.new(
348
+ name: config_name,
349
+ disable_exposures: disable_log_exposure,
350
+ disable_evaluation_details: disable_evaluation_details
351
+ )
352
+ @evaluator.get_config(user, config_name, res, user_persisted_values: user_persisted_values, ignore_local_overrides: ignore_local_overrides)
325
353
 
326
354
  unless disable_log_exposure
327
355
  @logger.log_config_exposure(user, res.name, res.rule_id, res.secondary_exposures, res.evaluation_details)
@@ -1,4 +1,4 @@
1
- # typed: true
1
+
2
2
  module Statsig
3
3
  class UninitializedError < StandardError
4
4
  def initialize(msg="Must call initialize first.")
data/lib/statsig_event.rb CHANGED
@@ -1,4 +1,4 @@
1
- # typed: true
1
+
2
2
  class StatsigEvent
3
3
  attr_accessor :value, :metadata, :statsig_metadata, :secondary_exposures
4
4
  attr_reader :user
@@ -21,13 +21,13 @@ class StatsigEvent
21
21
 
22
22
  def serialize
23
23
  {
24
- 'eventName' => @event_name,
25
- 'metadata' => @metadata,
26
- 'value' => @value,
27
- 'user' => @user,
28
- 'time' => @time,
29
- 'statsigMetadata' => @statsig_metadata,
30
- 'secondaryExposures' => @secondary_exposures
24
+ :eventName => @event_name,
25
+ :metadata => @metadata,
26
+ :value => @value,
27
+ :user => @user,
28
+ :time => @time,
29
+ :statsigMetadata => @statsig_metadata,
30
+ :secondaryExposures => @secondary_exposures
31
31
  }
32
32
  end
33
33
  end
@@ -1,4 +1,4 @@
1
- # typed: true
1
+ require 'constants'
2
2
  require 'statsig_event'
3
3
  require 'concurrent-ruby'
4
4
 
@@ -6,7 +6,7 @@ $gate_exposure_event = 'statsig::gate_exposure'
6
6
  $config_exposure_event = 'statsig::config_exposure'
7
7
  $layer_exposure_event = 'statsig::layer_exposure'
8
8
  $diagnostics_event = 'statsig::diagnostics'
9
- $ignored_metadata_keys = ['serverTime', 'configSyncTime', 'initTime', 'reason']
9
+ $ignored_metadata_keys = [:serverTime, :configSyncTime, :initTime, :reason]
10
10
  module Statsig
11
11
  class StatsigLogger
12
12
  def initialize(network, options, error_boundary)
@@ -41,9 +41,9 @@ module Statsig
41
41
  event = StatsigEvent.new($gate_exposure_event)
42
42
  event.user = user
43
43
  metadata = {
44
- 'gate' => gate_name,
45
- 'gateValue' => value.to_s,
46
- 'ruleID' => rule_id,
44
+ gate: gate_name,
45
+ gateValue: value.to_s,
46
+ ruleID: rule_id || Statsig::Const::EMPTY_STR,
47
47
  }
48
48
  return false if not is_unique_exposure(user, $gate_exposure_event, metadata)
49
49
  event.metadata = metadata
@@ -59,8 +59,8 @@ module Statsig
59
59
  event = StatsigEvent.new($config_exposure_event)
60
60
  event.user = user
61
61
  metadata = {
62
- 'config' => config_name,
63
- 'ruleID' => rule_id,
62
+ config: config_name,
63
+ ruleID: rule_id || Statsig::Const::EMPTY_STR,
64
64
  }
65
65
  return false if not is_unique_exposure(user, $config_exposure_event, metadata)
66
66
  event.metadata = metadata
@@ -72,8 +72,8 @@ module Statsig
72
72
  end
73
73
 
74
74
  def log_layer_exposure(user, layer, parameter_name, config_evaluation, context = nil)
75
- exposures = config_evaluation.undelegated_sec_exps
76
- allocated_experiment = ''
75
+ exposures = config_evaluation.undelegated_sec_exps || []
76
+ allocated_experiment = Statsig::Const::EMPTY_STR
77
77
  is_explicit = (config_evaluation.explicit_parameters&.include? parameter_name) || false
78
78
  if is_explicit
79
79
  allocated_experiment = config_evaluation.config_delegate
@@ -83,13 +83,13 @@ module Statsig
83
83
  event = StatsigEvent.new($layer_exposure_event)
84
84
  event.user = user
85
85
  metadata = {
86
- 'config' => layer.name,
87
- 'ruleID' => layer.rule_id,
88
- 'allocatedExperiment' => allocated_experiment,
89
- 'parameterName' => parameter_name,
90
- 'isExplicitParameter' => String(is_explicit),
86
+ config: layer.name,
87
+ ruleID: layer.rule_id || Statsig::Const::EMPTY_STR,
88
+ allocatedExperiment: allocated_experiment,
89
+ parameterName: parameter_name,
90
+ isExplicitParameter: String(is_explicit)
91
91
  }
92
- return false if not is_unique_exposure(user, $layer_exposure_event, metadata)
92
+ return false unless is_unique_exposure(user, $layer_exposure_event, metadata)
93
93
  event.metadata = metadata
94
94
  event.secondary_exposures = exposures.is_a?(Array) ? exposures : []
95
95
 
@@ -167,10 +167,10 @@ module Statsig
167
167
  return
168
168
  end
169
169
 
170
- event.metadata['reason'] = eval_details.reason
171
- event.metadata['configSyncTime'] = eval_details.config_sync_time
172
- event.metadata['initTime'] = eval_details.init_time
173
- event.metadata['serverTime'] = eval_details.server_time
170
+ event.metadata[:reason] = eval_details.reason
171
+ event.metadata[:configSyncTime] = eval_details.config_sync_time
172
+ event.metadata[:initTime] = eval_details.init_time
173
+ event.metadata[:serverTime] = eval_details.server_time
174
174
  end
175
175
 
176
176
  def safe_add_exposure_context(context, event)
@@ -178,8 +178,8 @@ module Statsig
178
178
  return
179
179
  end
180
180
 
181
- if context['is_manual_exposure']
182
- event.metadata['isManualExposure'] = 'true'
181
+ if context[:is_manual_exposure]
182
+ event.metadata[:isManualExposure] = 'true'
183
183
  end
184
184
  end
185
185
 
@@ -1,142 +1,92 @@
1
- # typed: true
2
-
3
- require 'sorbet-runtime'
4
1
  require_relative 'interfaces/data_store'
5
2
  require_relative 'interfaces/user_persistent_storage'
6
3
 
7
4
  ##
8
5
  # Configuration options for the Statsig SDK.
9
6
  class StatsigOptions
10
- extend T::Sig
11
7
 
12
- sig { returns(T.any(T::Hash[String, String], NilClass)) }
13
8
  # Hash you can use to set environment variables that apply to all of your users in
14
9
  # the same session and will be used for targeting purposes.
15
10
  # eg. { "tier" => "development" }
16
11
  attr_accessor :environment
17
12
 
18
- sig { returns(String) }
19
13
  # The base url used to make network calls to Statsig.
20
14
  # default: https://statsigapi.net/v1
21
15
  attr_accessor :api_url_base
22
16
 
23
17
  # The base url used specifically to call download_config_specs.
24
18
  # Takes precedence over api_url_base
25
- sig { returns(String) }
26
19
  attr_accessor :api_url_download_config_specs
27
20
 
28
- sig { returns(T.any(Float, Integer)) }
29
21
  # The interval (in seconds) to poll for changes to your Statsig configuration
30
22
  # default: 10s
31
23
  attr_accessor :rulesets_sync_interval
32
24
 
33
- sig { returns(T.any(Float, Integer)) }
34
25
  # The interval (in seconds) to poll for changes to your id lists
35
26
  # default: 60s
36
27
  attr_accessor :idlists_sync_interval
37
28
 
38
29
  # Disable background syncing for rulesets
39
- sig { returns(T::Boolean) }
40
30
  attr_accessor :disable_rulesets_sync
41
31
 
42
32
  # Disable background syncing for id lists
43
- sig { returns(T::Boolean) }
44
33
  attr_accessor :disable_idlists_sync
45
34
 
46
- sig { returns(T.any(Float, Integer)) }
47
35
  # How often to flush logs to Statsig
48
36
  # default: 60s
49
37
  attr_accessor :logging_interval_seconds
50
38
 
51
- sig { returns(Integer) }
52
39
  # The maximum number of events to batch before flushing logs to the server
53
40
  # default: 1000
54
41
  attr_accessor :logging_max_buffer_size
55
42
 
56
- sig { returns(T::Boolean) }
57
43
  # Restricts the SDK to not issue any network requests and only respond with default values (or local overrides)
58
44
  # default: false
59
45
  attr_accessor :local_mode
60
46
 
61
- sig { returns(T.any(String, NilClass)) }
62
47
  # A string that represents all rules for all feature gates, dynamic configs and experiments.
63
48
  # It can be provided to bootstrap the Statsig server SDK at initialization in case your server runs
64
49
  # into network issue or Statsig is down temporarily.
65
50
  attr_accessor :bootstrap_values
66
51
 
67
- sig { returns(T.any(Method, Proc, NilClass)) }
68
52
  # A callback function that will be called anytime the rulesets are updated.
69
53
  attr_accessor :rules_updated_callback
70
54
 
71
- sig { returns(T.any(Statsig::Interfaces::IDataStore, NilClass)) }
72
55
  # A class that extends IDataStore. Can be used to provide values from a
73
56
  # common data store (like Redis) to initialize the Statsig SDK.
74
57
  attr_accessor :data_store
75
58
 
76
- sig { returns(Integer) }
77
59
  # The number of threads allocated to syncing IDLists.
78
60
  # default: 3
79
61
  attr_accessor :idlist_threadpool_size
80
62
 
81
- sig { returns(Integer) }
82
63
  # The number of threads allocated to posting event logs.
83
64
  # default: 3
84
65
  attr_accessor :logger_threadpool_size
85
66
 
86
- sig { returns(T::Boolean) }
87
67
  # Should diagnostics be logged. These include performance metrics for initialize.
88
68
  # default: false
89
69
  attr_accessor :disable_diagnostics_logging
90
70
 
91
- sig { returns(T::Boolean) }
92
71
  # Statsig utilizes Sorbet (https://sorbet.org) to ensure type safety of the SDK. This includes logging
93
72
  # to console when errors are detected. You can disable this logging by setting this flag to true.
94
73
  # default: false
95
74
  attr_accessor :disable_sorbet_logging_handlers
96
75
 
97
- sig { returns(T.any(Integer, NilClass)) }
98
76
  # Number of seconds before a network call is timed out
99
77
  attr_accessor :network_timeout
100
78
 
101
- sig { returns(Integer) }
102
79
  # Number of times to retry sending a batch of failed log events
103
80
  attr_accessor :post_logs_retry_limit
104
81
 
105
- sig { returns(T.any(Method, Proc, Integer, NilClass)) }
106
82
  # The number of seconds, or a function that returns the number of seconds based on the number of retries remaining
107
83
  # which overrides the default backoff time between retries
108
84
  attr_accessor :post_logs_retry_backoff
109
85
 
110
- sig { returns(T.any(Statsig::Interfaces::IUserPersistentStorage, NilClass)) }
111
86
  # A storage adapter for persisted values. Can be used for sticky bucketing users in experiments.
112
87
  # Implements Statsig::Interfaces::IUserPersistentStorage.
113
88
  attr_accessor :user_persistent_storage
114
89
 
115
- sig do
116
- params(
117
- environment: T.any(T::Hash[String, String], NilClass),
118
- api_url_base: T.nilable(String),
119
- api_url_download_config_specs: T.any(String, NilClass),
120
- rulesets_sync_interval: T.any(Float, Integer),
121
- idlists_sync_interval: T.any(Float, Integer),
122
- disable_rulesets_sync: T::Boolean,
123
- disable_idlists_sync: T::Boolean,
124
- logging_interval_seconds: T.any(Float, Integer),
125
- logging_max_buffer_size: Integer,
126
- local_mode: T::Boolean,
127
- bootstrap_values: T.any(String, NilClass),
128
- rules_updated_callback: T.any(Method, Proc, NilClass),
129
- data_store: T.any(Statsig::Interfaces::IDataStore, NilClass),
130
- idlist_threadpool_size: Integer,
131
- logger_threadpool_size: Integer,
132
- disable_diagnostics_logging: T::Boolean,
133
- disable_sorbet_logging_handlers: T::Boolean,
134
- network_timeout: T.any(Integer, NilClass),
135
- post_logs_retry_limit: Integer,
136
- post_logs_retry_backoff: T.any(Method, Proc, Integer, NilClass),
137
- user_persistent_storage: T.any(Statsig::Interfaces::IUserPersistentStorage, NilClass)
138
- ).void
139
- end
140
90
  def initialize(
141
91
  environment = nil,
142
92
  api_url_base = nil,