devcycle-ruby-server-sdk 2.0.1 → 2.0.3

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: 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