statsig 1.14.0 → 1.16.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2536756538598d9f75c2b8920c90b7be1ab91ab05b416aedb5b05f325a6f5fde
4
- data.tar.gz: 045e5cc822c2355b5fd4c1cb9386425df3d85930c3f56735f96816b2242ae3a7
3
+ metadata.gz: 46c478c8efc8f7752c9c23a8396d1a8569dba062f1ad1410edc3787b3d4eae0b
4
+ data.tar.gz: b17a266497be6040ef1f02ff3cc265824089e3233ea9f64a2b2cd4127d250a2b
5
5
  SHA512:
6
- metadata.gz: 39494460ee50c89666dad6962a023dc7a954a24d386621855d219789a749e8ae58c40f19f4c8f472c46e5d3df33e28d5e3e05b9e44ccbf6569560353ae34670c
7
- data.tar.gz: 24b455140fcd7a4d628ce3780d19ee0ce7824fe41b799f39a015c8cf98f5124796d060f27ff65b353c0c9895fbadb6add845c2b09a3b0d3b2d68c3c8810a30be
6
+ metadata.gz: 00bee0caf5ee610af36f83223c865e16cbc26b4485f0b7a04e164ca57e0884e58cc61ed6a8a7353159f8e37d96a9d4427234d07e8c4162239b5cd74851b76bec
7
+ data.tar.gz: 71607b471fb6765d3aa9737f154fb5b4023b002dfc75b74298c81c40624c9cf53f58af0be49e90a0304d85090b72779fbe0c946ab4c5b39ecaf2e54dbd8a4a9e
@@ -6,6 +6,7 @@ module Statsig
6
6
  UNRECOGNIZED = "Unrecognized"
7
7
  UNINITIALIZED = "Uninitialized"
8
8
  BOOTSTRAP = "Bootstrap"
9
+ DATA_ADAPTER = "DataAdapter"
9
10
  end
10
11
 
11
12
  class EvaluationDetails
data/lib/evaluator.rb CHANGED
@@ -17,7 +17,7 @@ module Statsig
17
17
  attr_accessor :spec_store
18
18
 
19
19
  def initialize(network, options, error_callback)
20
- @spec_store = Statsig::SpecStore.new(network, error_callback, options.rulesets_sync_interval, options.idlists_sync_interval, options.bootstrap_values, options.rules_updated_callback)
20
+ @spec_store = Statsig::SpecStore.new(network, options, error_callback)
21
21
  @ua_parser = UserAgentParser::Parser.new
22
22
  CountryLookup.initialize
23
23
 
@@ -0,0 +1,18 @@
1
+ module Statsig
2
+ module Interfaces
3
+ class IDataStore
4
+ def init
5
+ end
6
+
7
+ def get(key)
8
+ nil
9
+ end
10
+
11
+ def set(key, value)
12
+ end
13
+
14
+ def shutdown
15
+ end
16
+ end
17
+ end
18
+ end
data/lib/network.rb CHANGED
@@ -19,7 +19,9 @@ module Statsig
19
19
  end
20
20
 
21
21
  def post_helper(endpoint, body, retries = 0, backoff = 1)
22
- return nil unless !@local_mode
22
+ if @local_mode
23
+ return nil, nil
24
+ end
23
25
  http = HTTP.headers(
24
26
  {"STATSIG-API-KEY" => @server_secret,
25
27
  "STATSIG-CLIENT-TIME" => (Time.now.to_f * 1000).to_i.to_s,
data/lib/spec_store.rb CHANGED
@@ -1,23 +1,27 @@
1
1
  require 'net/http'
2
2
  require 'uri'
3
-
4
3
  require 'evaluation_details'
5
4
  require 'id_list'
6
5
 
7
6
  module Statsig
8
7
  class SpecStore
8
+
9
+ CONFIG_SPECS_KEY = "statsig.cache"
10
+
9
11
  attr_accessor :last_config_sync_time
10
12
  attr_accessor :initial_config_sync_time
11
13
  attr_accessor :init_reason
12
14
 
13
- def initialize(network, error_callback = nil, rulesets_sync_interval = 10, id_lists_sync_interval = 60, bootstrap_values = nil, rules_updated_callback = nil)
15
+ def initialize(network, options, error_callback)
14
16
  @init_reason = EvaluationReason::UNINITIALIZED
15
17
  @network = network
18
+ @options = options
19
+ @error_callback = error_callback
16
20
  @last_config_sync_time = 0
17
21
  @initial_config_sync_time = 0
18
- @rulesets_sync_interval = rulesets_sync_interval
19
- @id_lists_sync_interval = id_lists_sync_interval
20
- @rules_updated_callback = rules_updated_callback
22
+ @rulesets_sync_interval = options.rulesets_sync_interval
23
+ @id_lists_sync_interval = options.idlists_sync_interval
24
+ @rules_updated_callback = options.rules_updated_callback
21
25
  @specs = {
22
26
  :gates => {},
23
27
  :configs => {},
@@ -26,9 +30,11 @@ module Statsig
26
30
  :experiment_to_layer => {}
27
31
  }
28
32
 
29
- unless bootstrap_values.nil?
33
+ unless @options.bootstrap_values.nil?
30
34
  begin
31
- if process(JSON.parse(bootstrap_values))
35
+ if !@options.data_store.nil?
36
+ puts 'data_store gets priority over bootstrap_values. bootstrap_values will be ignored'
37
+ elsif process(options.bootstrap_values)
32
38
  @init_reason = EvaluationReason::BOOTSTRAP
33
39
  end
34
40
  rescue
@@ -36,7 +42,11 @@ module Statsig
36
42
  end
37
43
  end
38
44
 
39
- @error_callback = error_callback
45
+ unless @options.data_store.nil?
46
+ @options.data_store.init
47
+ load_from_storage_adapter
48
+ end
49
+
40
50
  download_config_specs
41
51
  @initial_config_sync_time = @last_config_sync_time == 0 ? -1 : @last_config_sync_time
42
52
  get_id_lists
@@ -52,6 +62,9 @@ module Statsig
52
62
  def shutdown
53
63
  @config_sync_thread&.exit
54
64
  @id_lists_sync_thread&.exit
65
+ unless @options.data_store.nil?
66
+ @options.data_store.shutdown
67
+ end
55
68
  end
56
69
 
57
70
  def has_gate?(gate_name)
@@ -100,10 +113,26 @@ module Statsig
100
113
 
101
114
  private
102
115
 
116
+ def load_from_storage_adapter
117
+ cached_values = @options.data_store.get(CONFIG_SPECS_KEY)
118
+ if cached_values.nil?
119
+ return
120
+ end
121
+ process(cached_values, true)
122
+ @init_reason = EvaluationReason::DATA_ADAPTER
123
+ end
124
+
125
+ def save_to_storage_adapter(specs_string)
126
+ if @options.data_store.nil?
127
+ return
128
+ end
129
+ @options.data_store.set(CONFIG_SPECS_KEY, specs_string)
130
+ end
131
+
103
132
  def sync_config_specs
104
133
  Thread.new do
105
134
  loop do
106
- sleep @rulesets_sync_interval
135
+ sleep @options.rulesets_sync_interval
107
136
  download_config_specs
108
137
  end
109
138
  end
@@ -127,7 +156,7 @@ module Statsig
127
156
  begin
128
157
  response, e = @network.post_helper('download_config_specs', JSON.generate({ 'sinceTime' => @last_config_sync_time }))
129
158
  if e.nil?
130
- if process(JSON.parse(response.body))
159
+ if !response.nil? and process(response.body)
131
160
  @init_reason = EvaluationReason::NETWORK
132
161
  @rules_updated_callback.call(response.body.to_s, @last_config_sync_time) unless response.body.nil? or @rules_updated_callback.nil?
133
162
  end
@@ -140,13 +169,15 @@ module Statsig
140
169
  end
141
170
  end
142
171
 
143
- def process(specs_json)
144
- if specs_json.nil?
172
+ def process(specs_string, from_adapter = false)
173
+ if specs_string.nil?
145
174
  return false
146
175
  end
147
176
 
148
- @last_config_sync_time = specs_json['time'] || @last_config_sync_time
177
+ specs_json = JSON.parse(specs_string)
178
+ return false unless specs_json.is_a? Hash
149
179
 
180
+ @last_config_sync_time = specs_json['time'] || @last_config_sync_time
150
181
  return false unless specs_json['has_updates'] == true &&
151
182
  !specs_json['feature_gates'].nil? &&
152
183
  !specs_json['dynamic_configs'].nil? &&
@@ -171,6 +202,10 @@ module Statsig
171
202
  @specs[:configs] = new_configs
172
203
  @specs[:layers] = new_layers
173
204
  @specs[:experiment_to_layer] = new_exp_to_layer
205
+
206
+ unless from_adapter
207
+ save_to_storage_adapter(specs_string)
208
+ end
174
209
  true
175
210
  end
176
211
 
@@ -253,7 +288,7 @@ module Statsig
253
288
  line = li.strip
254
289
  next if line.length <= 1
255
290
  op = line[0]
256
- id = line[1..]
291
+ id = line[1..line.length]
257
292
  if op == '+'
258
293
  ids_clone.add(id)
259
294
  elsif op == '-'
data/lib/statsig.rb CHANGED
@@ -61,7 +61,7 @@ module Statsig
61
61
  def self.get_statsig_metadata
62
62
  {
63
63
  'sdkType' => 'ruby-server',
64
- 'sdkVersion' => '1.14.0',
64
+ 'sdkVersion' => '1.16.0',
65
65
  }
66
66
  end
67
67
 
@@ -8,6 +8,7 @@ class StatsigOptions
8
8
  attr_accessor :local_mode
9
9
  attr_accessor :bootstrap_values
10
10
  attr_accessor :rules_updated_callback
11
+ attr_accessor :data_store
11
12
 
12
13
  def initialize(
13
14
  environment=nil,
@@ -18,7 +19,8 @@ class StatsigOptions
18
19
  logging_max_buffer_size: 1000,
19
20
  local_mode: false,
20
21
  bootstrap_values: nil,
21
- rules_updated_callback: nil)
22
+ rules_updated_callback: nil,
23
+ data_store: nil)
22
24
  @environment = environment.is_a?(Hash) ? environment : nil
23
25
  @api_url_base = api_url_base
24
26
  @rulesets_sync_interval = rulesets_sync_interval
@@ -28,5 +30,6 @@ class StatsigOptions
28
30
  @local_mode = local_mode
29
31
  @bootstrap_values = bootstrap_values
30
32
  @rules_updated_callback = rules_updated_callback
33
+ @data_store = data_store
31
34
  end
32
35
  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.14.0
4
+ version: 1.16.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-09-27 00:00:00.000000000 Z
11
+ date: 2022-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -104,16 +104,16 @@ dependencies:
104
104
  name: ip3country
105
105
  requirement: !ruby/object:Gem::Requirement
106
106
  requirements:
107
- - - "~>"
107
+ - - '='
108
108
  - !ruby/object:Gem::Version
109
- version: '0.1'
109
+ version: 0.1.1
110
110
  type: :runtime
111
111
  prerelease: false
112
112
  version_requirements: !ruby/object:Gem::Requirement
113
113
  requirements:
114
- - - "~>"
114
+ - - '='
115
115
  - !ruby/object:Gem::Version
116
- version: '0.1'
116
+ version: 0.1.1
117
117
  description: Statsig server SDK for feature gates and experimentation in Ruby
118
118
  email: support@statsig.com
119
119
  executables: []
@@ -127,6 +127,7 @@ files:
127
127
  - lib/evaluation_helpers.rb
128
128
  - lib/evaluator.rb
129
129
  - lib/id_list.rb
130
+ - lib/interfaces/data_store.rb
130
131
  - lib/layer.rb
131
132
  - lib/network.rb
132
133
  - lib/spec_store.rb
@@ -148,7 +149,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
148
149
  requirements:
149
150
  - - ">="
150
151
  - !ruby/object:Gem::Version
151
- version: '0'
152
+ version: 2.5.9
152
153
  required_rubygems_version: !ruby/object:Gem::Requirement
153
154
  requirements:
154
155
  - - ">="