devcycle-ruby-server-sdk 2.7.0 → 3.0.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: 339be985589c9cf266b4407fd9a5204427a15d65ecb038e82ad4d9ecb691d92b
4
- data.tar.gz: 17f111831f10133475bc0823e63c043f2e264eaa2fd824a6041892da1986f2d8
3
+ metadata.gz: 2f9dd2899f5a8f286a66a667fa27623331572f5c35dec9ad363ab0be2e191296
4
+ data.tar.gz: e0971e7a1bdafc366b2021df303dbfc0f30f230d1c353e435d810805026ab866
5
5
  SHA512:
6
- metadata.gz: b02d9c440efd5eaf673a50dd94b71ed14edf4fcd8d08c0ee21d68626470664a9c0c3daf1fb6c0f01478da66b7195bba0b474a4264a91df50a7ead0ad7f1dc5fd
7
- data.tar.gz: 13079629f20070367b1bbb87b84b3d1579bce357e2255857cae86707c4fb205d6f9a13f7d56daeaaf278c6a82b82411bc72e5855d455575b4c21dfcda1b5b6d2
6
+ metadata.gz: 0c2d2b26b6ef08f548c58ecfbca13b2a09ab5643184f2018f9ede3e41ca1a115f17024f577e84ce12c27a23161be3cb7dc0d717569d23f4698b1f0398847dfdf
7
+ data.tar.gz: 1bfe5568cc56cf86566c9fe9d7480ffb6b3f7edf6907544a3305e99fbe64a163a867aa8f713015172591673889bd688fd81971efd4fbb91ef152433c59637b61
data/Gemfile CHANGED
@@ -1,7 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
- gem 'sorbet-runtime'
4
+ gem 'sorbet-runtime', '0.5.11481'
5
5
  gem 'oj'
6
6
  gem 'wasmtime'
7
7
  gem 'concurrent-ruby'
@@ -21,12 +21,12 @@ Gem::Specification.new do |s|
21
21
  s.summary = "DevCycle Bucketing API Ruby Gem"
22
22
  s.description = "DevCycle Ruby Server SDK, for interacting with feature flags created with the DevCycle platform."
23
23
  s.license = "MIT"
24
- s.required_ruby_version = ">= 2.4"
24
+ s.required_ruby_version = ">= 3.1"
25
25
 
26
26
  s.add_runtime_dependency 'typhoeus', '~> 1.0', '>= 1.0.1'
27
- s.add_runtime_dependency 'wasmtime', '13.0.0'
27
+ s.add_runtime_dependency 'wasmtime', '20.0.2'
28
28
  s.add_runtime_dependency 'concurrent-ruby', '~> 1.2.0'
29
- s.add_runtime_dependency 'sorbet-runtime', '~> 0.5'
29
+ s.add_runtime_dependency 'sorbet-runtime', '>= 0.5.11481'
30
30
  s.add_runtime_dependency 'oj', '~> 3.0'
31
31
  s.add_runtime_dependency 'google-protobuf', '~> 3.22'
32
32
 
@@ -158,13 +158,13 @@ module DevCycle
158
158
  end
159
159
 
160
160
  # Get variable by key for user data
161
- # @param user [User]
161
+ # @param user [DevCycle::User]
162
162
  # @param key [String] Variable key
163
163
  # @param default Default value for variable if none is retrieved
164
164
  # @param [Hash] opts the optional parameters
165
165
  # @return [Variable]
166
166
  def variable(user, key, default, opts = {})
167
- if !user.is_a?(DevCycle::User)
167
+ unless user.is_a?(DevCycle::User)
168
168
  fail ArgumentError, "user param must be an instance of DevCycle::User!"
169
169
  end
170
170
 
@@ -4,6 +4,7 @@ require 'sorbet-runtime'
4
4
  require 'concurrent-ruby'
5
5
  require 'typhoeus'
6
6
  require 'json'
7
+ require 'time'
7
8
 
8
9
  module DevCycle
9
10
  class ConfigManager
@@ -19,13 +20,14 @@ module DevCycle
19
20
  @local_bucketing = local_bucketing
20
21
  @sdkKey = sdkKey
21
22
  @config_e_tag = ""
23
+ @config_last_modified = ""
22
24
  @logger = local_bucketing.options.logger
23
25
  @polling_enabled = true
24
26
  @max_config_retries = 2
25
27
 
26
28
  @config_poller = Concurrent::TimerTask.new({
27
- execution_interval: @local_bucketing.options.config_polling_interval_ms.fdiv(1000)
28
- }) do |task|
29
+ execution_interval: @local_bucketing.options.config_polling_interval_ms.fdiv(1000)
30
+ }) do |task|
29
31
  fetch_config
30
32
  end
31
33
 
@@ -53,22 +55,43 @@ module DevCycle
53
55
  Accept: "application/json",
54
56
  })
55
57
 
58
+ begin
59
+ Date.parse(@config_last_modified)
60
+ if @config_last_modified != ""
61
+ req.options[:headers]["If-Modified-Since"] = Time.httpdate(@config_last_modified)
62
+ end
63
+ rescue
64
+ end
65
+
66
+
56
67
  if @config_e_tag != ""
57
68
  req.options[:headers]['If-None-Match'] = @config_e_tag
58
69
  end
59
70
 
60
71
  @max_config_retries.times do
61
- @logger.debug("Requesting new config from #{get_config_url}, current etag: #{@config_e_tag}")
72
+ @logger.debug("Requesting new config from #{get_config_url}, current etag: #{@config_e_tag}, last modified: #{@config_last_modified}")
62
73
  resp = req.run
63
74
  @logger.debug("Config request complete, status: #{resp.code}")
64
75
  case resp.code
65
76
  when 304
66
- @logger.debug("Config not modified, using cache, etag: #{@config_e_tag}")
77
+ @logger.debug("Config not modified, using cache, etag: #{@config_e_tag}, last modified: #{@config_last_modified}")
67
78
  break
68
79
  when 200
69
- @logger.debug("New config received, etag: #{resp.headers['Etag']}")
70
- set_config(resp.body, resp.headers['Etag'])
71
- @logger.debug("New config stored, etag: #{@config_e_tag}")
80
+ @logger.debug("New config received, etag: #{resp.headers['Etag']} LM:#{resp.headers['Last-Modified']}")
81
+ lm_header = resp.headers['Last-Modified']
82
+ begin
83
+ lm_timestamp = Time.rfc2822(lm_header)
84
+ current_lm = Time.rfc2822(@config_last_modified)
85
+ if lm_timestamp == "" && @config_last_modified == "" || (current_lm.utc < lm_timestamp.utc)
86
+ set_config(resp.body, resp.headers['Etag'], lm_header)
87
+ @logger.debug("New config stored, etag: #{@config_e_tag}, last modified: #{lm_header}")
88
+ else
89
+ @logger.warn("Config response was an older config than currently stored config.")
90
+ end
91
+ rescue
92
+ @logger.warn("Failed to parse last modified header, setting config.")
93
+ set_config(resp.body, resp.headers['Etag'], lm_header)
94
+ end
72
95
  break
73
96
  when 403
74
97
  stop_polling
@@ -91,13 +114,14 @@ module DevCycle
91
114
  nil
92
115
  end
93
116
 
94
- def set_config(config, etag)
117
+ def set_config(config, etag, lastmodified)
95
118
  if !JSON.parse(config).is_a?(Hash)
96
119
  raise("Invalid JSON body parsed from Config Response")
97
120
  end
98
121
 
99
122
  @local_bucketing.store_config(config)
100
123
  @config_e_tag = etag
124
+ @config_last_modified = lastmodified
101
125
  @local_bucketing.has_config = true
102
126
  end
103
127
 
@@ -1,6 +1,8 @@
1
1
  require 'typhoeus'
2
2
  require 'sorbet-runtime'
3
3
  require 'concurrent-ruby'
4
+ require 'securerandom'
5
+
4
6
 
5
7
  module DevCycle
6
8
  class EventQueue
@@ -9,6 +11,7 @@ module DevCycle
9
11
  sig { params(sdkKey: String, options: EventQueueOptions, local_bucketing: LocalBucketing).void }
10
12
  def initialize(sdkKey, options, local_bucketing)
11
13
  @sdkKey = sdkKey
14
+ @client_uuid = SecureRandom.uuid
12
15
  @events_api_uri = options.events_api_uri
13
16
  @logger = options.logger
14
17
  @event_flush_interval_ms = options.event_flush_interval_ms
@@ -22,7 +25,7 @@ module DevCycle
22
25
  @flush_timer_task.execute
23
26
  @flush_mutex = Mutex.new
24
27
  @local_bucketing = local_bucketing
25
- @local_bucketing.init_event_queue(options)
28
+ @local_bucketing.init_event_queue(@client_uuid, options)
26
29
  end
27
30
 
28
31
  def close
@@ -32,6 +32,7 @@ module DevCycle
32
32
  .inherit_stderr
33
33
  .set_argv(ARGV)
34
34
  .set_env(ENV)
35
+ .build
35
36
  @@store = Wasmtime::Store.new(@@engine, wasi_ctx: @@wasi_ctx)
36
37
  @@linker = Wasmtime::Linker.new(@@engine, wasi: true)
37
38
 
@@ -245,13 +246,14 @@ module DevCycle
245
246
  end
246
247
  end
247
248
 
248
- sig { params(options: EventQueueOptions).returns(NilClass) }
249
- def init_event_queue(options)
249
+ sig { params(client_uuid: String, options: EventQueueOptions).returns(NilClass) }
250
+ def init_event_queue(client_uuid, options)
250
251
  @wasm_mutex.synchronize do
251
252
  options_json = Oj.dump(options)
253
+ client_uuid_addr = malloc_asc_string(client_uuid)
252
254
  options_addr = malloc_asc_string(options_json)
253
255
  @@stack_tracer = @@stack_tracer_raise
254
- @@instance.invoke("initEventQueue", @sdkKeyAddr, options_addr)
256
+ @@instance.invoke("initEventQueue", @sdkKeyAddr, client_uuid_addr, options_addr)
255
257
  end
256
258
  end
257
259
 
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+ BUCKETING_LIB_VERSION="1.24.2"
3
+ WAT_DOWNLOAD=0
4
+ rm bucketing-lib.release.wasm
5
+ wget "https://unpkg.com/@devcycle/bucketing-assembly-script@$BUCKETING_LIB_VERSION/build/bucketing-lib.release.wasm"
@@ -11,5 +11,5 @@ OpenAPI Generator version: 5.3.0
11
11
  =end
12
12
 
13
13
  module DevCycle
14
- VERSION = '2.7.0'
14
+ VERSION = '3.0.0'
15
15
  end
@@ -93,7 +93,7 @@ describe 'DevCycle::Client' do
93
93
  it 'should work' do
94
94
  result = @api_instance.all_variables(@user)
95
95
 
96
- expect(result.length).to eq 1
96
+ expect(result.length).to eq 5
97
97
  end
98
98
  end
99
99
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devcycle-ruby-server-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - DevCycleHQ
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-15 00:00:00.000000000 Z
11
+ date: 2024-07-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: typhoeus
@@ -36,14 +36,14 @@ dependencies:
36
36
  requirements:
37
37
  - - '='
38
38
  - !ruby/object:Gem::Version
39
- version: 13.0.0
39
+ version: 20.0.2
40
40
  type: :runtime
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - '='
45
45
  - !ruby/object:Gem::Version
46
- version: 13.0.0
46
+ version: 20.0.2
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: concurrent-ruby
49
49
  requirement: !ruby/object:Gem::Requirement
@@ -62,16 +62,16 @@ dependencies:
62
62
  name: sorbet-runtime
63
63
  requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
- - - "~>"
65
+ - - ">="
66
66
  - !ruby/object:Gem::Version
67
- version: '0.5'
67
+ version: 0.5.11481
68
68
  type: :runtime
69
69
  prerelease: false
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
- - - "~>"
72
+ - - ">="
73
73
  - !ruby/object:Gem::Version
74
- version: '0.5'
74
+ version: 0.5.11481
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: oj
77
77
  requirement: !ruby/object:Gem::Requirement
@@ -149,6 +149,7 @@ files:
149
149
  - lib/devcycle-ruby-server-sdk/localbucketing/proto/helpers.rb
150
150
  - lib/devcycle-ruby-server-sdk/localbucketing/proto/variableForUserParams.proto
151
151
  - lib/devcycle-ruby-server-sdk/localbucketing/proto/variableForUserParams_pb.rb
152
+ - lib/devcycle-ruby-server-sdk/localbucketing/update_wasm.sh
152
153
  - lib/devcycle-ruby-server-sdk/models/error_response.rb
153
154
  - lib/devcycle-ruby-server-sdk/models/event.rb
154
155
  - lib/devcycle-ruby-server-sdk/models/feature.rb
@@ -173,14 +174,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
173
174
  requirements:
174
175
  - - ">="
175
176
  - !ruby/object:Gem::Version
176
- version: '2.4'
177
+ version: '3.1'
177
178
  required_rubygems_version: !ruby/object:Gem::Requirement
178
179
  requirements:
179
180
  - - ">="
180
181
  - !ruby/object:Gem::Version
181
182
  version: '0'
182
183
  requirements: []
183
- rubygems_version: 3.2.33
184
+ rubygems_version: 3.4.1
184
185
  signing_key:
185
186
  specification_version: 4
186
187
  summary: DevCycle Bucketing API Ruby Gem