statsig 1.29.0.pre.beta.1 → 1.29.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e279228e9eb701b7bcf06ac68ada05a4403f1d046c4ddc3343c87cf86d6be049
4
- data.tar.gz: 3b110f44f460c9924aa909c1e9723094189a0fe4a20c6f7572c997cf40968e29
3
+ metadata.gz: '093cc05e0b8f3bb7e2f0f019cf36ad33e5abc4c4349d2fb1faa056c1ff5aa341'
4
+ data.tar.gz: d66640f8b0c317ca018ff4ccc77d1d370af89b1c84416508631deb610236d519
5
5
  SHA512:
6
- metadata.gz: a4871a883213685bc1d6c537367f4de78cacc81b0cec6929853b57c80439895e0ed49d797ef5bb7733c5dce73df9c0bb1aa5ef4b8c3563351468b557f3e473b4
7
- data.tar.gz: fbdc2952ed68a92640268c6931b59521e641d22448c2c8a897521637951d7c20ea6f0f6d4354252c184a8a1c0b9e03861f9b047c9634165998f6a9218660e7e6
6
+ metadata.gz: f634575320cd1ababfa25816ee8ac5fe27e34c761895b4ba6b20957363e487c295767d65e123ab7d306aa1ce2f535f55cc58570f8767790948d2647ab321150b
7
+ data.tar.gz: d563727b175a23afa50cb68cbaf91eb49435bae46b1a48b72d9bf0ff38febeefa86b886c34cc2632f37e357c44f96a1e2586050b41e9ac156697f4105c4f9f0b
@@ -42,7 +42,7 @@ module ClientInitializeHelpers
42
42
  target_app_id = @evaluator.spec_store.get_app_id_for_sdk_key(@client_sdk_key)
43
43
  config_target_apps = config_spec['targetAppIDs']
44
44
 
45
- unless target_app_id.nil? || config_target_apps.nil? || config_target_apps.include?(target_app_id)
45
+ unless target_app_id.nil? || (!config_target_apps.nil? && config_target_apps.include?(target_app_id))
46
46
  return nil
47
47
  end
48
48
 
data/lib/config_result.rb CHANGED
@@ -25,7 +25,7 @@ module Statsig
25
25
  json_value = {},
26
26
  rule_id = '',
27
27
  secondary_exposures = [],
28
- config_delegate = '',
28
+ config_delegate = nil,
29
29
  explicit_parameters = [],
30
30
  is_experiment_group: false,
31
31
  evaluation_details: nil,
data/lib/layer.rb CHANGED
@@ -17,11 +17,25 @@ class Layer
17
17
  sig { returns(String) }
18
18
  attr_accessor :rule_id
19
19
 
20
- sig { params(name: String, value: T::Hash[String, T.untyped], rule_id: String, exposure_log_func: T.any(Method, Proc, NilClass)).void }
21
- def initialize(name, value = {}, rule_id = '', exposure_log_func = nil)
20
+ sig { returns(String) }
21
+ attr_accessor :group_name
22
+
23
+ sig do
24
+ params(
25
+ name: String,
26
+ value: T::Hash[String, T.untyped],
27
+ rule_id: String,
28
+ group_name: T.nilable(String),
29
+ allocated_experiment: T.nilable(String),
30
+ exposure_log_func: T.any(Method, Proc, NilClass)
31
+ ).void
32
+ end
33
+ def initialize(name, value = {}, rule_id = '', group_name = nil, allocated_experiment = nil, exposure_log_func = nil)
22
34
  @name = name
23
35
  @value = value
24
36
  @rule_id = rule_id
37
+ @group_name = group_name
38
+ @allocated_experiment = allocated_experiment
25
39
  @exposure_log_func = exposure_log_func
26
40
  end
27
41
 
@@ -58,4 +72,4 @@ class Layer
58
72
 
59
73
  @value[index]
60
74
  end
61
- end
75
+ end
data/lib/network.rb CHANGED
@@ -53,11 +53,42 @@ module Statsig
53
53
  end
54
54
  end
55
55
 
56
+ sig do
57
+ params(since_time: Integer)
58
+ .returns([T.any(HTTP::Response, NilClass), T.any(StandardError, NilClass)])
59
+ end
60
+ def download_config_specs(since_time)
61
+ get("download_config_specs/#{@server_secret}.json?sinceTime=#{since_time}")
62
+ end
63
+
64
+ class HttpMethod < T::Enum
65
+ enums do
66
+ GET = new
67
+ POST = new
68
+ end
69
+ end
70
+
71
+ sig do
72
+ params(endpoint: String, retries: Integer, backoff: Integer)
73
+ .returns([T.any(HTTP::Response, NilClass), T.any(StandardError, NilClass)])
74
+ end
75
+ def get(endpoint, retries = 0, backoff = 1)
76
+ request(HttpMethod::GET, endpoint, nil, retries, backoff)
77
+ end
78
+
56
79
  sig do
57
80
  params(endpoint: String, body: String, retries: Integer, backoff: Integer)
58
81
  .returns([T.any(HTTP::Response, NilClass), T.any(StandardError, NilClass)])
59
82
  end
60
- def post_helper(endpoint, body, retries = 0, backoff = 1)
83
+ def post(endpoint, body, retries = 0, backoff = 1)
84
+ request(HttpMethod::POST, endpoint, body, retries, backoff)
85
+ end
86
+
87
+ sig do
88
+ params(method: HttpMethod, endpoint: String, body: T.nilable(String), retries: Integer, backoff: Integer)
89
+ .returns([T.any(HTTP::Response, NilClass), T.any(StandardError, NilClass)])
90
+ end
91
+ def request(method, endpoint, body, retries = 0, backoff = 1)
61
92
  if @local_mode
62
93
  return nil, nil
63
94
  end
@@ -73,14 +104,20 @@ module Statsig
73
104
  url = URIHelper.build_url(endpoint)
74
105
  begin
75
106
  res = @connection_pool.with do |conn|
76
- conn.headers('STATSIG-CLIENT-TIME' => (Time.now.to_f * 1000).to_i.to_s).post(url, body: body)
107
+ request = conn.headers('STATSIG-CLIENT-TIME' => (Time.now.to_f * 1000).to_i.to_s)
108
+ case method
109
+ when HttpMethod::GET
110
+ request.get(url)
111
+ when HttpMethod::POST
112
+ request.post(url, body: body)
113
+ end
77
114
  end
78
115
  rescue StandardError => e
79
116
  ## network error retry
80
117
  return nil, e unless retries.positive?
81
118
 
82
119
  sleep backoff_adjusted
83
- return post_helper(endpoint, body, retries - 1, backoff * @backoff_multiplier)
120
+ return request(method, endpoint, body, retries - 1, backoff * @backoff_multiplier)
84
121
  end
85
122
  return res, nil if res.status.success?
86
123
 
@@ -91,12 +128,12 @@ module Statsig
91
128
 
92
129
  ## status code retry
93
130
  sleep backoff_adjusted
94
- post_helper(endpoint, body, retries - 1, backoff * @backoff_multiplier)
131
+ request(method, endpoint, body, retries - 1, backoff * @backoff_multiplier)
95
132
  end
96
133
 
97
134
  def check_gate(user, gate_name)
98
135
  request_body = JSON.generate({ 'user' => user&.serialize(false), 'gateName' => gate_name })
99
- response, = post_helper('check_gate', request_body)
136
+ response, = post('check_gate', request_body)
100
137
  return JSON.parse(response.body) unless response.nil?
101
138
 
102
139
  false
@@ -106,7 +143,7 @@ module Statsig
106
143
 
107
144
  def get_config(user, dynamic_config_name)
108
145
  request_body = JSON.generate({ 'user' => user&.serialize(false), 'configName' => dynamic_config_name })
109
- response, = post_helper('get_config', request_body)
146
+ response, = post('get_config', request_body)
110
147
  return JSON.parse(response.body) unless response.nil?
111
148
 
112
149
  nil
@@ -116,7 +153,7 @@ module Statsig
116
153
 
117
154
  def post_logs(events)
118
155
  json_body = JSON.generate({ 'events' => events, 'statsigMetadata' => Statsig.get_statsig_metadata })
119
- post_helper('log_event', json_body, @post_logs_retry_limit)
156
+ post('log_event', json_body, @post_logs_retry_limit)
120
157
  rescue StandardError
121
158
 
122
159
  end
data/lib/spec_store.rb CHANGED
@@ -238,7 +238,7 @@ module Statsig
238
238
 
239
239
  error = nil
240
240
  begin
241
- response, e = @network.post_helper('download_config_specs', JSON.generate({ 'sinceTime' => @last_config_sync_time }))
241
+ response, e = @network.download_config_specs(@last_config_sync_time)
242
242
  code = response&.status.to_i
243
243
  if e.is_a? NetworkError
244
244
  code = e.http_code
@@ -334,7 +334,7 @@ module Statsig
334
334
 
335
335
  def get_id_lists_from_network
336
336
  tracker = @diagnostics.track('get_id_list_sources', 'network_request')
337
- response, e = @network.post_helper('get_id_lists', JSON.generate({ 'statsigMetadata' => Statsig.get_statsig_metadata }))
337
+ response, e = @network.post('get_id_lists', JSON.generate({ 'statsigMetadata' => Statsig.get_statsig_metadata }))
338
338
  code = response&.status.to_i
339
339
  if e.is_a? NetworkError
340
340
  code = e.http_code
data/lib/statsig.rb CHANGED
@@ -265,7 +265,7 @@ module Statsig
265
265
  def self.get_statsig_metadata
266
266
  {
267
267
  'sdkType' => 'ruby-server',
268
- 'sdkVersion' => '1.29.0-beta.1',
268
+ 'sdkVersion' => '1.29.0',
269
269
  }
270
270
  end
271
271
 
@@ -130,7 +130,7 @@ class StatsigDriver
130
130
  end
131
131
 
132
132
  if res == $fetch_from_server
133
- if res.config_delegate.empty?
133
+ if res.config_delegate.nil?
134
134
  return Layer.new(layer_name)
135
135
  end
136
136
  res = get_config_fallback(user, res.config_delegate)
@@ -140,7 +140,7 @@ class StatsigDriver
140
140
  exposure_log_func = !options.disable_log_exposure ? lambda { |layer, parameter_name|
141
141
  @logger.log_layer_exposure(user, layer, parameter_name, res)
142
142
  } : nil
143
- Layer.new(res.name, res.json_value, res.rule_id, exposure_log_func)
143
+ Layer.new(res.name, res.json_value, res.rule_id, res.group_name, res.config_delegate, exposure_log_func)
144
144
  }, caller: __method__.to_s)
145
145
  }, recover: lambda { Layer.new(layer_name) }, caller: __method__.to_s)
146
146
  end
@@ -149,7 +149,7 @@ class StatsigDriver
149
149
  def manually_log_layer_parameter_exposure(user, layer_name, parameter_name)
150
150
  @err_boundary.capture(task: lambda {
151
151
  res = @evaluator.get_layer(user, layer_name)
152
- layer = Layer.new(layer_name, res.json_value, res.rule_id)
152
+ layer = Layer.new(layer_name, res.json_value, res.rule_id, res.group_name, res.config_delegate)
153
153
  context = { 'is_manual_exposure' => true }
154
154
  @logger.log_layer_exposure(user, layer, parameter_name, res, context)
155
155
  }, caller: __method__.to_s)
@@ -22,7 +22,7 @@ class StatsigOptions
22
22
 
23
23
  # The base url used specifically to call download_config_specs.
24
24
  # Takes precedence over api_url_base
25
- sig { returns(T.any(String, NilClass)) }
25
+ sig { returns(String) }
26
26
  attr_accessor :api_url_download_config_specs
27
27
 
28
28
  sig { returns(T.any(Float, Integer)) }
@@ -115,7 +115,7 @@ class StatsigOptions
115
115
  sig do
116
116
  params(
117
117
  environment: T.any(T::Hash[String, String], NilClass),
118
- api_url_base: String,
118
+ api_url_base: T.nilable(String),
119
119
  api_url_download_config_specs: T.any(String, NilClass),
120
120
  rulesets_sync_interval: T.any(Float, Integer),
121
121
  idlists_sync_interval: T.any(Float, Integer),
@@ -137,10 +137,9 @@ class StatsigOptions
137
137
  user_persistent_storage: T.any(Statsig::Interfaces::IUserPersistentStorage, NilClass)
138
138
  ).void
139
139
  end
140
-
141
140
  def initialize(
142
141
  environment = nil,
143
- api_url_base = 'https://statsigapi.net/v1',
142
+ api_url_base = nil,
144
143
  api_url_download_config_specs: nil,
145
144
  rulesets_sync_interval: 10,
146
145
  idlists_sync_interval: 60,
@@ -162,8 +161,8 @@ class StatsigOptions
162
161
  user_persistent_storage: nil
163
162
  )
164
163
  @environment = environment.is_a?(Hash) ? environment : nil
165
- @api_url_base = api_url_base
166
- @api_url_download_config_specs = api_url_download_config_specs
164
+ @api_url_base = api_url_base || 'https://statsigapi.net/v1'
165
+ @api_url_download_config_specs = api_url_download_config_specs || api_url_base || 'https://api.statsigcdn.com/v1'
167
166
  @rulesets_sync_interval = rulesets_sync_interval
168
167
  @idlists_sync_interval = idlists_sync_interval
169
168
  @disable_rulesets_sync = disable_rulesets_sync
data/lib/uri_helper.rb CHANGED
@@ -17,7 +17,7 @@ class URIHelper
17
17
  sig { params(endpoint: String).returns(String) }
18
18
  def build_url(endpoint)
19
19
  api = @options.api_url_base
20
- if endpoint == 'download_config_specs' && !@options.api_url_download_config_specs.nil?
20
+ if endpoint.include?('download_config_specs')
21
21
  api = T.must(@options.api_url_download_config_specs)
22
22
  end
23
23
  unless api.end_with?('/')
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.29.0.pre.beta.1
4
+ version: 1.29.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Statsig, Inc
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-11 00:00:00.000000000 Z
11
+ date: 2023-12-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -351,7 +351,7 @@ homepage: https://rubygems.org/gems/statsig
351
351
  licenses:
352
352
  - ISC
353
353
  metadata: {}
354
- post_install_message:
354
+ post_install_message:
355
355
  rdoc_options: []
356
356
  require_paths:
357
357
  - lib
@@ -362,12 +362,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
362
362
  version: 2.5.0
363
363
  required_rubygems_version: !ruby/object:Gem::Requirement
364
364
  requirements:
365
- - - ">"
365
+ - - ">="
366
366
  - !ruby/object:Gem::Version
367
- version: 1.3.1
367
+ version: '0'
368
368
  requirements: []
369
- rubygems_version: 3.3.7
370
- signing_key:
369
+ rubygems_version: 3.2.33
370
+ signing_key:
371
371
  specification_version: 4
372
372
  summary: Statsig server SDK for Ruby
373
373
  test_files: []