devcycle-ruby-server-sdk 2.0.1 → 2.0.3

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: fc0fd57c7d492253c2a5aed803845d028057f5075f33ed40b7cd31d6862bd7b2
4
- data.tar.gz: 3cf436a16d4ae282192e77687fccaf17d3346b1facb364a26f4ae932ed658140
3
+ metadata.gz: 960c105106387fcb10b360f0befbb77d2dda8c80dce5a51a5eed3c8c49528253
4
+ data.tar.gz: 1c9274022cece19d953ceba7adfed10cd6418e4a3097ad3305f1a539ace32e23
5
5
  SHA512:
6
- metadata.gz: 8e463d4849b50cfd4a346e252909d968f2a41ed31e3bac91de33ad968ecca3afd0ceefb1243cb3326049853894502f8979cd8574fa81bc12cbc9cf66ea34edfb
7
- data.tar.gz: f9467f2c7ad852e18b9de9bba1a96a73b55febe9ab25d64571e09e19ab9dac394a965d543f77c3aed44a4a1719368c677151d016ca8ba0c0772d2592a78489cf
6
+ metadata.gz: 67cb4a92cb5c9247bd10c838cfa0979d89d331c75c5626967af9b4602c55c30a2842f94f2c15471bb459686382be20432e43bf9951f1c27f516cbc5b2d8a504e
7
+ data.tar.gz: 802ec0ab8f6b2a7623fe58c94cd007484832c06c5742a38831bebd0991ef2c3b57cc99563ffcee89a545742c0fe1080beea95be01aab88f27983d5d808b359f1
@@ -25,8 +25,8 @@ Gem::Specification.new do |s|
25
25
 
26
26
  s.add_runtime_dependency 'typhoeus', '~> 1.0', '>= 1.0.1'
27
27
  s.add_runtime_dependency 'wasmtime', '5.0.0'
28
- s.add_runtime_dependency 'concurrent-ruby', '1.2.0'
29
- s.add_runtime_dependency 'sorbet-runtime', '0.5.10648'
28
+ s.add_runtime_dependency 'concurrent-ruby', '~> 1.2.0'
29
+ s.add_runtime_dependency 'sorbet-runtime', '~> 0.5'
30
30
  s.add_runtime_dependency 'oj', '3.13.2'
31
31
 
32
32
 
@@ -17,9 +17,9 @@ module DevCycle
17
17
  class DVCClient
18
18
  def initialize(sdkKey, dvc_options = DVCOptions.new, wait_for_init = false)
19
19
  if sdkKey.nil?
20
- raise ArgumentError('Missing SDK key!')
20
+ raise ArgumentError.new('Missing SDK key!')
21
21
  elsif !sdkKey.start_with?('server') && !sdkKey.start_with?('dvc_server')
22
- raise ArgumentError('Invalid SDK key!')
22
+ raise ArgumentError.new('Invalid SDK key!')
23
23
  end
24
24
 
25
25
  @sdkKey = sdkKey
@@ -56,13 +56,20 @@ module DevCycle
56
56
 
57
57
  @event_queue.close
58
58
  @logger.info("Closed DevCycle Client.")
59
+ nil
59
60
  end
60
61
 
61
62
  def set_client_custom_data(customdata)
62
- if @api_client.config.enable_cloud_bucketing
63
- fail ArgumentError("Client Custom Data is only available in Local bucketing mode.")
63
+ if @dvc_options.enable_cloud_bucketing
64
+ raise StandardError.new("Client Custom Data is only available in Local bucketing mode.")
65
+ end
66
+
67
+ if local_bucketing_initialized?
68
+ @localbucketing.set_client_custom_data(customdata)
69
+ else
70
+ @logger.warn("Local bucketing not initialized. Unable to set client custom data.")
64
71
  end
65
- @localbucketing.set_client_custom_data(customdata)
72
+ nil
66
73
  end
67
74
 
68
75
  def validate_model(model)
@@ -86,7 +93,7 @@ module DevCycle
86
93
  return data
87
94
  end
88
95
 
89
- if local_bucketing_initialized?
96
+ if local_bucketing_initialized? && @localbucketing.has_config
90
97
  bucketed_config = @localbucketing.generate_bucketed_config(user_data)
91
98
  bucketed_config.features
92
99
  else
@@ -169,30 +176,59 @@ module DevCycle
169
176
  return data
170
177
  end
171
178
 
172
- if local_bucketing_initialized?
179
+ if local_bucketing_initialized? && @localbucketing.has_config
173
180
  bucketed_config = @localbucketing.generate_bucketed_config(user_data)
174
181
  variable_json = bucketed_config.variables[key]
175
182
  if variable_json == nil
183
+ @logger.warn("No variable found for key #{key}, returning default value")
176
184
  variable_event = Event.new({ type: DevCycle::EventTypes[:agg_variable_defaulted], target: key })
177
185
  @event_queue.queue_aggregate_event(variable_event, bucketed_config)
178
186
 
179
- return Variable.new({ key: key, value: default, isDefaulted: true })
187
+ return Variable.new({
188
+ key: key,
189
+ type: determine_variable_type(default),
190
+ value: default,
191
+ defaultValue: default,
192
+ isDefaulted: true
193
+ })
180
194
  end
195
+ default_type = determine_variable_type(default)
196
+ variable_type = variable_json['type']
197
+ if default_type != variable_type
198
+ @logger.warn("Type mismatch for variable #{key}, returning default value")
199
+ variable_event = Event.new({ type: DevCycle::EventTypes[:agg_variable_defaulted], target: key })
200
+ @event_queue.queue_aggregate_event(variable_event, bucketed_config)
181
201
 
202
+ return Variable.new({
203
+ key: key,
204
+ type: default_type,
205
+ value: default,
206
+ defaultValue: default,
207
+ isDefaulted: true
208
+ })
209
+ end
182
210
  variable_event = Event.new({ type: DevCycle::EventTypes[:agg_variable_evaluated], target: key })
183
211
  @event_queue.queue_aggregate_event(variable_event, bucketed_config)
184
212
 
185
213
  Variable.new({
186
- key: key,
187
- type: variable_json['type'],
188
- value: variable_json['value'],
189
- isDefaulted: false
190
- })
214
+ key: key,
215
+ type: variable_type,
216
+ value: variable_json['value'],
217
+ defaultValue: default,
218
+ isDefaulted: false
219
+ })
191
220
  else
221
+ @logger.warn("Local bucketing not initialized, returning default value for variable #{key}")
192
222
  variable_event = Event.new({ type: DevCycle::EventTypes[:agg_variable_defaulted], target: key })
193
223
  @event_queue.queue_aggregate_event(variable_event, bucketed_config)
194
224
 
195
- Variable.new({ key: key, value: default, isDefaulted: true })
225
+ Variable.new({
226
+ key: key,
227
+ type: determine_variable_type(default),
228
+ value: default,
229
+ defaultValue: default,
230
+ isDefaulted: true
231
+ })
196
232
  end
197
233
  end
198
234
 
@@ -283,7 +319,7 @@ module DevCycle
283
319
  return data
284
320
  end
285
321
 
286
- if local_bucketing_initialized?
322
+ if local_bucketing_initialized? && @localbucketing.has_config
287
323
  bucketed_config = @localbucketing.generate_bucketed_config(user_data)
288
324
  bucketed_config.variables
289
325
  else
@@ -452,5 +488,19 @@ module DevCycle
452
488
  def local_bucketing_initialized?
453
489
  !@localbucketing.nil? && @localbucketing.initialized
454
490
  end
491
+
492
+ def determine_variable_type(variable_value)
493
+ if variable_value.is_a?(String)
494
+ 'String'
495
+ elsif variable_value.is_a?(TrueClass) || variable_value.is_a?(FalseClass)
496
+ 'Boolean'
497
+ elsif variable_value.is_a?(Integer) || variable_value.is_a?(Float)
498
+ 'Number'
499
+ elsif variable_value.is_a?(Hash)
500
+ 'JSON'
501
+ else
502
+ raise ArgumentError, "Invalid type for variable: #{variable_value}"
503
+ end
504
+ end
455
505
  end
456
506
  end
@@ -20,20 +20,33 @@ module DevCycle
20
20
  @sdkKey = sdkKey
21
21
  @config_e_tag = ""
22
22
  @logger = local_bucketing.options.logger
23
+ @polling_enabled = true
24
+ @max_config_retries = 2
23
25
 
24
- @config_poller = Concurrent::TimerTask.new(
25
- {
26
- execution_interval: @local_bucketing.options.config_polling_interval_ms.fdiv(1000),
27
- run_now: true
26
+ @config_poller = Concurrent::TimerTask.new({
27
+ execution_interval: @local_bucketing.options.config_polling_interval_ms.fdiv(1000)
28
28
  }) do |task|
29
- fetch_config(false, task)
29
+ fetch_config
30
30
  end
31
31
 
32
- t = Thread.new { fetch_config(false, nil) }
32
+ t = Thread.new { initialize_config }
33
33
  t.join if wait_for_init
34
34
  end
35
35
 
36
- def fetch_config(retrying, task)
36
+ def initialize_config
37
+ begin
38
+ fetch_config
39
+ @config_poller.execute if @polling_enabled
40
+ rescue => e
41
+ @logger.error("DVC Error Initializing Config: #{e.message}")
42
+ ensure
43
+ @local_bucketing.initialized = true
44
+ end
45
+ end
46
+
47
+ def fetch_config
48
+ return unless @polling_enabled
49
+
37
50
  req = Typhoeus::Request.new(
38
51
  get_config_url,
39
52
  headers: {
@@ -44,25 +57,26 @@ module DevCycle
44
57
  req.options[:headers]['If-None-Match'] = @config_e_tag
45
58
  end
46
59
 
47
- resp = req.run
48
-
49
- case resp.code
50
- when 304
51
- return nil
52
- when 200
53
- return set_config(resp.body, resp.headers['Etag'])
54
- when 403
55
- raise("Failed to download DevCycle config; Invalid SDK Key.")
56
- when 500...599
57
- if !retrying
58
- return fetch_config(true, task)
60
+ @max_config_retries.times do
61
+ resp = req.run
62
+ case resp.code
63
+ when 304
64
+ @logger.debug("Config not modified, using cache, etag: #{this.configEtag}")
65
+ return
66
+ when 200
67
+ set_config(resp.body, resp.headers['Etag'])
68
+ return
69
+ when 403
70
+ stop_polling
71
+ @logger.error("Failed to download DevCycle config; Invalid SDK Key.")
72
+ return
73
+ when 500...599
74
+ @logger.error("Failed to download DevCycle config. Status: #{resp.code}")
75
+ else
76
+ stop_polling
77
+ @logger.error("Unexpected response code - DevCycle Response: #{Oj.dump(resp)}")
78
+ return
59
79
  end
60
- @logger.warn("Failed to download DevCycle config. Status: #{resp.code}")
61
- else
62
- if task != nil
63
- task.shutdown
64
- end
65
- raise("Unexpected response code - DevCycle Response: #{Oj.dump(resp)}")
66
80
  end
67
81
 
68
82
  nil
@@ -73,15 +87,9 @@ module DevCycle
73
87
  raise("Invalid JSON body parsed from Config Response")
74
88
  end
75
89
 
76
- @local_bucketing.store_config(@sdkKey, config)
90
+ @local_bucketing.store_config(config)
77
91
  @config_e_tag = etag
78
-
79
- if @first_load
80
- @logger.info("Config Set. Client Initialized.")
81
- @first_load = false
82
- @local_bucketing.initialized = true
83
- @config_poller.execute
84
- end
92
+ @local_bucketing.has_config = true
85
93
  end
86
94
 
87
95
  def get_config_url
@@ -89,8 +97,13 @@ module DevCycle
89
97
  "#{configBasePath}/config/#{@config_version}/server/#{@sdkKey}.json"
90
98
  end
91
99
 
100
+ def stop_polling
101
+ @polling_enabled = false
102
+ @config_poller.shutdown if @config_poller.running?
103
+ end
104
+
92
105
  def close
93
- @config_poller.shutdown
106
+ @config_poller.shutdown if @config_poller.running?
94
107
  nil
95
108
  end
96
109
  end
@@ -12,15 +12,16 @@ module DevCycle
12
12
 
13
13
  def initialize(
14
14
  enable_cloud_bucketing: false,
15
- event_flush_interval_ms: 10 * 1000,
15
+ event_flush_interval_ms: 10_000,
16
16
  disable_custom_event_logging: false,
17
17
  disable_automatic_event_logging: false,
18
- config_polling_interval_ms: 10000,
19
- request_timeout_ms: 5000,
20
- max_event_queue_size: 2000,
21
- flush_event_queue_size: 1000,
18
+ config_polling_interval_ms: 10_000,
19
+ request_timeout_ms: 5_000,
20
+ max_event_queue_size: 2_000,
21
+ flush_event_queue_size: 1_000,
22
22
  event_request_chunk_size: 100,
23
23
  logger: nil,
24
+ config_cdn_uri: 'https://config-cdn.devcycle.com',
24
25
  events_api_uri: 'https://events.devcycle.com',
25
26
  enable_edge_db: false
26
27
  )
@@ -34,8 +35,7 @@ module DevCycle
34
35
  end
35
36
 
36
37
  if config_polling_interval_ms < 1000
37
- @logger.warn('config_polling_interval cannot be less than 1000ms, defaulting to 10000ms')
38
- config_polling_interval_ms = 10000
38
+ raise ArgumentError.new('config_polling_interval cannot be less than 1000ms')
39
39
  end
40
40
  @config_polling_interval_ms = config_polling_interval_ms
41
41
 
@@ -51,15 +51,21 @@ module DevCycle
51
51
  @event_flush_interval_ms = event_flush_interval_ms
52
52
 
53
53
  if flush_event_queue_size >= max_event_queue_size
54
- raise ArgumentError.new("flush_event_queue_size: #{flush_event_queue_size} must be " +
55
- "smaller than max_event_queue_size: #{@max_event_queue_size}")
54
+ raise ArgumentError.new(
55
+ "flush_event_queue_size: #{flush_event_queue_size} must be " +
56
+ "smaller than max_event_queue_size: #{@max_event_queue_size}"
57
+ )
56
58
  elsif flush_event_queue_size < event_request_chunk_size || max_event_queue_size < event_request_chunk_size
57
- throw ArgumentError.new("flush_event_queue_size: #{flush_event_queue_size} and " +
59
+ throw ArgumentError.new(
60
+ "flush_event_queue_size: #{flush_event_queue_size} and " +
58
61
  "max_event_queue_size: #{max_event_queue_size} " +
59
- "must be larger than event_request_chunk_size: #{event_request_chunk_size}")
62
+ "must be larger than event_request_chunk_size: #{event_request_chunk_size}"
63
+ )
60
64
  elsif flush_event_queue_size > 20000 || max_event_queue_size > 20000
61
- raise ArgumentError.new("flush_event_queue_size: #{flush_event_queue_size} or " +
62
- "max_event_queue_size: #{max_event_queue_size} must be smaller than 20,000")
65
+ raise ArgumentError.new(
66
+ "flush_event_queue_size: #{flush_event_queue_size} or " +
67
+ "max_event_queue_size: #{max_event_queue_size} must be smaller than 20,000"
68
+ )
63
69
  end
64
70
  @flush_event_queue_size = flush_event_queue_size
65
71
  @max_event_queue_size = max_event_queue_size
@@ -67,7 +73,7 @@ module DevCycle
67
73
 
68
74
  @disable_custom_event_logging = disable_custom_event_logging
69
75
  @disable_automatic_event_logging = disable_automatic_event_logging
70
- @config_cdn_uri = "https://config-cdn.devcycle.com"
76
+ @config_cdn_uri = config_cdn_uri
71
77
  @events_api_uri = events_api_uri
72
78
  @bucketing_api_uri = "https://bucketing-api.devcyle.com"
73
79
  end
@@ -14,21 +14,15 @@ module DevCycle
14
14
  @event_flush_interval_ms = options.event_flush_interval_ms
15
15
  @flush_event_queue_size = options.flush_event_queue_size
16
16
  @max_event_queue_size = options.max_event_queue_size
17
-
18
17
  @flush_timer_task = Concurrent::TimerTask.new(
19
- execution_interval: @event_flush_interval_ms.fdiv(1000),
20
- run_now: true
18
+ execution_interval: @event_flush_interval_ms.fdiv(1000)
21
19
  ) {
22
20
  flush_events
23
21
  }
24
22
  @flush_timer_task.execute
25
- @flush_timer_task.add_observer(FlushTimerTaskObserver.new)
26
-
23
+ @flush_mutex = Mutex.new
27
24
  @local_bucketing = local_bucketing
28
25
  @local_bucketing.init_event_queue(options)
29
-
30
- @flush_mutex = Mutex.new
31
- nil
32
26
  end
33
27
 
34
28
  def close
@@ -50,7 +44,7 @@ module DevCycle
50
44
  begin
51
45
  response = Typhoeus.post(
52
46
  @events_api_uri + '/v1/events/batch',
53
- headers: { 'Authorization': @sdkKey },
47
+ headers: { 'Authorization': @sdkKey, 'Content-Type': 'application/json' },
54
48
  body: { 'batch': payload.records }.to_json
55
49
  )
56
50
  if response.code != 201
@@ -104,17 +98,4 @@ module DevCycle
104
98
  false
105
99
  end
106
100
  end
107
-
108
- # Todo: remove when done testing
109
- class FlushTimerTaskObserver
110
- def update(time, result, ex)
111
- return if ex.nil?
112
-
113
- if ex.is_a?(Concurrent::TimeoutError)
114
- print("DVC FlushTimerTaskObserver: Execution timed out")
115
- else
116
- print("DVC FlushTimerTaskObserver: Execution failed with error: #{ex}")
117
- end
118
- end
119
- end
120
101
  end
@@ -14,6 +14,7 @@ module DevCycle
14
14
 
15
15
  attr_reader :options
16
16
  attr_accessor :initialized
17
+ attr_accessor :has_config
17
18
 
18
19
  @@rand = Random.new(seed = Random.new_seed)
19
20
  @@engine = Wasmtime::Engine.new
@@ -86,28 +87,29 @@ module DevCycle
86
87
  ).void }
87
88
  def initialize(sdkkey, options, wait_for_init)
88
89
  @initialized = false
90
+ @has_config = false
89
91
  @sdkkey = sdkkey
90
92
  @options = options
91
93
  @logger = options.logger
92
-
94
+ set_sdk_key_internal(sdkkey)
93
95
  platform_data = PlatformData.new('server', VERSION, RUBY_VERSION, nil, 'Ruby', Socket.gethostname)
94
96
  set_platform_data(platform_data)
95
- @configmanager = ConfigManager.new(@sdkkey, self, wait_for_init)
97
+ @config_manager = ConfigManager.new(@sdkkey, self, wait_for_init)
96
98
  end
97
99
 
98
100
  def close
99
- @configmanager.close
100
- @configmanager = nil
101
+ @config_manager.close
102
+ @config_manager = nil
101
103
  end
102
104
 
103
105
  sig { params(user: UserData).returns(BucketedUserConfig) }
104
106
  def generate_bucketed_config(user)
105
- sdkkey_addr = malloc_asc_string(@sdkkey)
106
107
  user_addr = malloc_asc_string(user.to_json)
107
108
  @@stack_tracer = lambda { |message| raise message }
108
- config_addr = @@instance.invoke("generateBucketedConfigForUser", sdkkey_addr, user_addr)
109
+ config_addr = @@instance.invoke("generateBucketedConfigForUser", @sdkKeyAddr, user_addr)
109
110
  bucketed_config_json = read_asc_string(config_addr)
110
111
  bucketed_config_hash = Oj.load(bucketed_config_json)
112
+
111
113
  BucketedUserConfig.new(bucketed_config_hash['project'],
112
114
  bucketed_config_hash['environment'],
113
115
  bucketed_config_hash['features'],
@@ -119,9 +121,8 @@ module DevCycle
119
121
 
120
122
  sig { returns(T::Array[EventsPayload]) }
121
123
  def flush_event_queue
122
- sdkkey_addr = malloc_asc_string(@sdkkey)
123
124
  @@stack_tracer = lambda { |message| raise message }
124
- payload_addr = @@instance.invoke("flushEventQueue", sdkkey_addr)
125
+ payload_addr = @@instance.invoke("flushEventQueue", @sdkKeyAddr)
125
126
  raw_json = read_asc_string(payload_addr)
126
127
  raw_payloads = Oj.load(raw_json)
127
128
 
@@ -133,66 +134,69 @@ module DevCycle
133
134
 
134
135
  sig { returns(Integer) }
135
136
  def check_event_queue_size
136
- sdkkey_addr = malloc_asc_string(@sdkkey)
137
137
  @@stack_tracer = lambda { |message| raise message }
138
- @@instance.invoke("eventQueueSize", sdkkey_addr)
138
+ @@instance.invoke("eventQueueSize", @sdkKeyAddr)
139
139
  end
140
140
 
141
141
  sig { params(payload_id: String).returns(NilClass) }
142
142
  def on_payload_success(payload_id)
143
- sdkkey_addr = malloc_asc_string(@sdkkey)
144
143
  payload_addr = malloc_asc_string(payload_id)
145
144
  @@stack_tracer = lambda { |message| raise message }
146
- @@instance.invoke("onPayloadSuccess", sdkkey_addr, payload_addr)
145
+ @@instance.invoke("onPayloadSuccess", @sdkKeyAddr, payload_addr)
147
146
  end
148
147
 
149
148
  sig { params(user: UserData, event: Event).returns(NilClass) }
150
149
  def queue_event(user, event)
151
- sdkkey_addr = malloc_asc_string(@sdkkey)
152
- user_addr = malloc_asc_string(Oj.dump(user))
153
- event_addr = malloc_asc_string(Oj.dump(event))
154
- @@stack_tracer = lambda { |message| raise message }
155
- @@instance.invoke("queueEvent", sdkkey_addr, user_addr, event_addr)
150
+ begin
151
+ user_addr = malloc_asc_string(Oj.dump(user))
152
+ asc_pin(user_addr)
153
+ event_addr = malloc_asc_string(Oj.dump(event))
154
+ @@stack_tracer = lambda { |message| raise message }
155
+ @@instance.invoke("queueEvent", @sdkKeyAddr, user_addr, event_addr)
156
+ ensure
157
+ asc_unpin(user_addr)
158
+ end
156
159
  end
157
160
 
158
161
  sig { params(event: Event, bucketeduser: T.nilable(BucketedUserConfig)).returns(NilClass) }
159
162
  def queue_aggregate_event(event, bucketeduser)
160
- sdkkey_addr = malloc_asc_string(@sdkkey)
161
- variable_variation_map =
162
- if !bucketeduser.nil?
163
- bucketeduser.variable_variation_map
164
- else
165
- {}
163
+ begin
164
+ variable_variation_map =
165
+ if !bucketeduser.nil?
166
+ bucketeduser.variable_variation_map
167
+ else
168
+ {}
169
+ end
170
+ varmap_addr = malloc_asc_string(Oj.dump(variable_variation_map))
171
+ asc_pin(varmap_addr)
172
+ event_addr = malloc_asc_string(Oj.dump(event))
173
+ @@stack_tracer = lambda { |message| raise message }
174
+ @@instance.invoke("queueAggregateEvent", @sdkKeyAddr, event_addr, varmap_addr)
175
+ ensure
176
+ asc_unpin(varmap_addr)
166
177
  end
167
- varmap_addr = malloc_asc_string(Oj.dump(variable_variation_map))
168
- event_addr = malloc_asc_string(Oj.dump(event))
169
- @@stack_tracer = lambda { |message| raise message }
170
- @@instance.invoke("queueAggregateEvent", sdkkey_addr, event_addr, varmap_addr)
171
178
  end
172
179
 
173
180
  sig { params(payload_id: String, retryable: Object).returns(NilClass) }
174
181
  def on_payload_failure(payload_id, retryable)
175
- sdkkey_addr = malloc_asc_string(@sdkkey)
176
182
  payload_addr = malloc_asc_string(payload_id)
177
183
  @@stack_tracer = lambda { |message| raise message }
178
- @@instance.invoke("onPayloadFailure", sdkkey_addr, payload_addr, retryable ? 1 : 0)
184
+ @@instance.invoke("onPayloadFailure", @sdkKeyAddr, payload_addr, retryable ? 1 : 0)
179
185
  end
180
186
 
181
- sig { params(sdkkey: String, config: String).returns(NilClass) }
182
- def store_config(sdkkey, config)
183
- sdkkey_addr = malloc_asc_string(sdkkey)
187
+ sig { params(config: String).returns(NilClass) }
188
+ def store_config(config)
184
189
  config_addr = malloc_asc_string(config)
185
190
  @@stack_tracer = lambda { |message| raise message }
186
- @@instance.invoke("setConfigData", sdkkey_addr, config_addr)
191
+ @@instance.invoke("setConfigData", @sdkKeyAddr, config_addr)
187
192
  end
188
193
 
189
194
  sig { params(options: EventQueueOptions).returns(NilClass) }
190
195
  def init_event_queue(options)
191
196
  options_json = Oj.dump(options)
192
- sdkkey_addr = malloc_asc_string(@sdkkey)
193
197
  options_addr = malloc_asc_string(options_json)
194
198
  @@stack_tracer = lambda { |message| raise message }
195
- @@instance.invoke("initEventQueue", sdkkey_addr, options_addr)
199
+ @@instance.invoke("initEventQueue", @sdkKeyAddr, options_addr)
196
200
  end
197
201
 
198
202
  sig { params(customdata: Hash).returns(NilClass) }
@@ -213,6 +217,20 @@ module DevCycle
213
217
  @@instance.invoke("setPlatformData", platformdata_addr)
214
218
  end
215
219
 
220
+ def set_sdk_key_internal(sdkKey)
221
+ addr = malloc_asc_string(sdkKey)
222
+ @sdkKeyAddr = addr
223
+ asc_pin(addr)
224
+ end
225
+
226
+ def asc_pin(addr)
227
+ @@instance.invoke("__pin", addr)
228
+ end
229
+
230
+ def asc_unpin(addr)
231
+ @@instance.invoke("__unpin", addr)
232
+ end
233
+
216
234
  # @param [String] string utf8 string to allocate
217
235
  # @return [Integer] address to WASM String
218
236
  sig { params(string: String).returns(Integer) }
@@ -220,7 +238,7 @@ module DevCycle
220
238
  wasm_object_id = 1
221
239
  @@stack_tracer = lambda { |message| raise message }
222
240
  wasm_new = @@instance.export("__new").to_func
223
- utf8_bytes = string.encode("iso-8859-1").force_encoding("utf-8").bytes
241
+ utf8_bytes = string.bytes
224
242
  byte_len = utf8_bytes.length
225
243
 
226
244
  start_addr = wasm_new.call(byte_len * 2, wasm_object_id)
@@ -27,6 +27,8 @@ module DevCycle
27
27
  # Set to true if the Variable could not be fetched
28
28
  attr_accessor :isDefaulted
29
29
 
30
+ attr_accessor :defaultValue
31
+
30
32
  class EnumAttributeValidator
31
33
  attr_reader :datatype
32
34
  attr_reader :allowable_values
@@ -55,6 +57,7 @@ module DevCycle
55
57
  :'key' => :'key',
56
58
  :'type' => :'type',
57
59
  :'value' => :'value',
60
+ :'defaultValue' => :'defaultValue',
58
61
  :'isDefaulted' => :'isDefaulted'
59
62
  }
60
63
  end
@@ -70,6 +73,7 @@ module DevCycle
70
73
  :'key' => :'String',
71
74
  :'type' => :'String',
72
75
  :'value' => :'Object',
76
+ :'defaultValue' => :'Object',
73
77
  :'isDefaulted' => :'Boolean'
74
78
  }
75
79
  end
@@ -112,6 +116,10 @@ module DevCycle
112
116
  else
113
117
  self.isDefaulted = false
114
118
  end
119
+
120
+ if attributes.key?(:'defaultValue')
121
+ self.defaultValue = attributes[:'defaultValue']
122
+ end
115
123
  end
116
124
 
117
125
  # Show invalid properties with the reasons. Usually used together with valid?
@@ -296,7 +304,5 @@ module DevCycle
296
304
  value
297
305
  end
298
306
  end
299
-
300
307
  end
301
-
302
308
  end
@@ -11,5 +11,5 @@ OpenAPI Generator version: 5.3.0
11
11
  =end
12
12
 
13
13
  module DevCycle
14
- VERSION = '2.0.1'
14
+ VERSION = '2.0.3'
15
15
  end
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.0.1
4
+ version: 2.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - DevCycleHQ
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-24 00:00:00.000000000 Z
11
+ date: 2023-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: typhoeus
@@ -48,30 +48,30 @@ dependencies:
48
48
  name: concurrent-ruby
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - '='
51
+ - - "~>"
52
52
  - !ruby/object:Gem::Version
53
53
  version: 1.2.0
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - '='
58
+ - - "~>"
59
59
  - !ruby/object:Gem::Version
60
60
  version: 1.2.0
61
61
  - !ruby/object:Gem::Dependency
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.10648
67
+ version: '0.5'
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.10648
74
+ version: '0.5'
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: oj
77
77
  requirement: !ruby/object:Gem::Requirement