configcat 6.0.0 → 7.0.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: ce490d2a3a5e6bc5762305dbd0740f2658b5e316a514306a7ab2061ccafe4382
4
- data.tar.gz: c4ed8386bb8644fa723f82a677f64fe60c7dab44aa03eacceeec965231402d82
3
+ metadata.gz: 4e0dc6578b7a148dda7c630d560098fb295eb139f237362db056b235d0feaa7e
4
+ data.tar.gz: e9f97b6d5f0af6fa72288bfeac3b13c6354bb1726af129349653b9365a10e665
5
5
  SHA512:
6
- metadata.gz: 0f80a0a78a5d0023de47a59eafc4fbb18ba40cbab7302bd260cd54b6b383113039a1a087b74cf72657e49bfcc1af84afd9d76d220c9696807f600dd4c393d1a4
7
- data.tar.gz: 134cf29821feeb9f23debde30ede59545a45da81c8d8a0100a4684d01909c84f67c48d5029ca5734a618d226e55411f35fc6f412710b668b6b62f1ca15f82635
6
+ metadata.gz: a895b147c9238dbeb7e2f02d5021002032b47e023214842fb4528bdfabdf5c6c729bc746ff630f1f5cfb325442ba70ae71e7e3ee2257b3d81cfc8cf60ad06dee
7
+ data.tar.gz: 95d70831f41b93bcfa3306e9af41de05eb27ce80df4b734c0f1a6f7f98f83da468ed8abacbd4b252c105cd807bd21859b2cd4f19699b5a426c689bf6b15eedd7
@@ -28,8 +28,9 @@ module ConfigCat
28
28
  client = @@instances[sdk_key]
29
29
  if client
30
30
  if options
31
- client.log.warn("Client for sdk_key `#{sdk_key}` is already created and will be reused; " +
32
- "options passed are being ignored.")
31
+ client.log.warn(3000, "There is an existing client instance for the specified SDK Key. " \
32
+ "No new client instance will be created and the specified options are ignored. " \
33
+ "Returning the existing client instance. SDK Key: '#{sdk_key}'.")
33
34
  end
34
35
  return client
35
36
  end
@@ -105,9 +106,8 @@ module ConfigCat
105
106
  def get_value(key, default_value, user = nil)
106
107
  settings, fetch_time = _get_settings()
107
108
  if settings.nil?
108
- message = "Evaluating get_value('%s') failed. Cache is empty. " \
109
- "Returning default_value in your get_value call: [%s]." % [key, default_value.to_s]
110
- @log.error(message)
109
+ message = "Config JSON is not present when evaluating setting '#{key}'. Returning the `default_value` parameter that you specified in your application: '#{default_value}'."
110
+ @log.error(1000, message)
111
111
  @hooks.invoke_on_flag_evaluated(EvaluationDetails.from_error(key, default_value, error: message))
112
112
  return default_value
113
113
  end
@@ -124,11 +124,11 @@ module ConfigCat
124
124
  def get_value_details(key, default_value, user = nil)
125
125
  settings, fetch_time = _get_settings()
126
126
  if settings.nil?
127
- message = "Evaluating get_value_details('%s') failed. Cache is empty. " \
128
- "Returning default_value in your get_value_details call: [%s]." % [key, default_value.to_s]
129
- @log.error(message)
130
- @hooks.invoke_on_flag_evaluated(EvaluationDetails.from_error(key, default_value, error: message))
131
- return default_value
127
+ message = "Config JSON is not present when evaluating setting '#{key}'. Returning the `default_value` parameter that you specified in your application: '#{default_value}'."
128
+ @log.error(1000, message)
129
+ details = EvaluationDetails.from_error(key, default_value, error: message)
130
+ @hooks.invoke_on_flag_evaluated(details)
131
+ return details
132
132
  end
133
133
  details = _evaluate(key, user, default_value, nil, settings, fetch_time)
134
134
  return details
@@ -140,54 +140,12 @@ module ConfigCat
140
140
  def get_all_keys
141
141
  settings, _ = _get_settings()
142
142
  if settings === nil
143
+ @log.error(1000, "Config JSON is not present. Returning empty list.")
143
144
  return []
144
145
  end
145
146
  return settings.keys
146
147
  end
147
148
 
148
- # Gets the Variation ID (analytics) of a feature flag or setting based on it's key.
149
- #
150
- # :param key [String] the identifier of the feature flag or setting.
151
- # :param default_variation_id in case of any failure, this value will be returned.
152
- # :param user [User] the user object to identify the caller.
153
- # :return the variation ID.
154
- def get_variation_id(key, default_variation_id, user = nil)
155
- @log.warn("get_variation_id is deprecated and will be removed in a future major version. "\
156
- "Please use [get_value_details] instead.")
157
-
158
- settings, fetch_time = _get_settings()
159
- if settings === nil
160
- message = "Evaluating get_variation_id('%s') failed. Cache is empty. "\
161
- "Returning default_variation_id in your get_variation_id call: [%s]." %
162
- [key, default_variation_id.to_s]
163
- @log.error(message)
164
- @hooks.invoke_on_flag_evaluated(EvaluationDetails.from_error(key, nil, error: message,
165
- variation_id: default_variation_id))
166
- return default_variation_id
167
- end
168
- details = _evaluate(key, user, nil, default_variation_id, settings, fetch_time)
169
- return details.variation_id
170
- end
171
-
172
- # Gets the Variation IDs (analytics) of all feature flags or settings.
173
- #
174
- # :param user [User] the user object to identify the caller.
175
- # :return list of variation IDs
176
- def get_all_variation_ids(user = nil)
177
- @log.warn("get_all_variation_ids is deprecated and will be removed in a future major version. "\
178
- "Please use [get_value_details] instead.")
179
-
180
- keys = get_all_keys()
181
- variation_ids = []
182
- for key in keys
183
- variation_id = get_variation_id(key, nil, user)
184
- if !variation_id.equal?(nil)
185
- variation_ids.push(variation_id)
186
- end
187
- end
188
- return variation_ids
189
- end
190
-
191
149
  # Gets the key of a setting, and it's value identified by the given Variation ID (analytics)
192
150
  #
193
151
  # :param variation_id [String] variation ID
@@ -195,7 +153,7 @@ module ConfigCat
195
153
  def get_key_and_value(variation_id)
196
154
  settings, _ = _get_settings()
197
155
  if settings === nil
198
- @log.warn("Evaluating get_key_and_value('%s') failed. Cache is empty. Returning nil." % variation_id)
156
+ @log.error(1000, "Config JSON is not present. Returning nil.")
199
157
  return nil
200
158
  end
201
159
 
@@ -219,7 +177,7 @@ module ConfigCat
219
177
  end
220
178
  end
221
179
 
222
- @log.error("Could not find the setting for the given variation_id: " + variation_id)
180
+ @log.error(2011, "Could not find the setting for the specified variation ID: '#{variation_id}'.")
223
181
  end
224
182
 
225
183
  # Evaluates and returns the values of all feature flags and settings.
@@ -227,9 +185,14 @@ module ConfigCat
227
185
  # :param user [User] the user object to identify the caller.
228
186
  # :return dictionary of values
229
187
  def get_all_values(user = nil)
230
- keys = get_all_keys()
188
+ settings, _ = _get_settings()
189
+ if settings === nil
190
+ @log.error(1000, "Config JSON is not present. Returning empty dictionary.")
191
+ return {}
192
+ end
193
+
231
194
  all_values = {}
232
- for key in keys
195
+ for key in settings.keys
233
196
  value = get_value(key, nil, user)
234
197
  if !value.equal?(nil)
235
198
  all_values[key] = value
@@ -245,7 +208,7 @@ module ConfigCat
245
208
  def get_all_value_details(user = nil)
246
209
  settings, fetch_time = _get_settings()
247
210
  if settings.nil?
248
- @log.error("Evaluating get_all_value_details() failed. Cache is empty. Returning empty list.")
211
+ @log.error(1000, "Config JSON is not present. Returning empty list.")
249
212
  return []
250
213
  end
251
214
 
@@ -282,14 +245,16 @@ module ConfigCat
282
245
 
283
246
  # Configures the SDK to allow HTTP requests.
284
247
  def set_online
285
- @_config_service.set_online if @_config_service
286
- @log.debug('Switched to ONLINE mode.')
248
+ if @_config_service
249
+ @_config_service.set_online
250
+ else
251
+ @log.warn(3202, "Client is configured to use the `LOCAL_ONLY` override behavior, thus `set_online()` has no effect.")
252
+ end
287
253
  end
288
254
 
289
255
  # Configures the SDK to not initiate HTTP requests and work only from its cache.
290
256
  def set_offline
291
257
  @_config_service.set_offline if @_config_service
292
- @log.debug('Switched to OFFLINE mode.')
293
258
  end
294
259
 
295
260
  # Returns true when the SDK is configured not to initiate HTTP requests, otherwise false.
@@ -339,10 +304,6 @@ module ConfigCat
339
304
  return @_config_service.get_settings()
340
305
  end
341
306
 
342
- def _get_cache_key
343
- return Digest::SHA1.hexdigest("ruby_" + CONFIG_FILE_NAME + "_" + @_sdk_key)
344
- end
345
-
346
307
  def _evaluate(key, user, default_value, default_variation_id, settings, fetch_time)
347
308
  user = user || @_default_user
348
309
  value, variation_id, rule, percentage_rule, error = @_rollout_evaluator.evaluate(
@@ -5,20 +5,20 @@ module ConfigCat
5
5
  end
6
6
 
7
7
  def debug(message)
8
- ConfigCat.logger.debug(message)
8
+ ConfigCat.logger.debug("[0] " + message)
9
9
  end
10
10
 
11
- def info(message)
12
- ConfigCat.logger.info(message)
11
+ def info(event_id, message)
12
+ ConfigCat.logger.info("[" + event_id.to_s + "] " + message)
13
13
  end
14
14
 
15
- def warn(message)
16
- ConfigCat.logger.warn(message)
15
+ def warn(event_id, message)
16
+ ConfigCat.logger.warn("[" + event_id.to_s + "] " + message)
17
17
  end
18
18
 
19
- def error(message)
19
+ def error(event_id, message)
20
20
  @hooks.invoke_on_error(message)
21
- ConfigCat.logger.error(message)
21
+ ConfigCat.logger.error("[" + event_id.to_s + "] " + message)
22
22
  end
23
23
  end
24
24
  end
@@ -2,37 +2,50 @@ require 'configcat/utils'
2
2
 
3
3
  module ConfigCat
4
4
  class ConfigEntry
5
- CONFIG = 'config'
6
- ETAG = 'etag'
7
- FETCH_TIME = 'fetch_time'
5
+ attr_accessor :config, :etag, :config_json_string, :fetch_time
8
6
 
9
- attr_accessor :config, :etag, :fetch_time
10
-
11
- def initialize(config = {}, etag = '', fetch_time = Utils::DISTANT_PAST)
7
+ def initialize(config = {}, etag = '', config_json_string = '{}', fetch_time = Utils::DISTANT_PAST)
12
8
  @config = config
13
9
  @etag = etag
10
+ @config_json_string = config_json_string
14
11
  @fetch_time = fetch_time
15
12
  end
16
13
 
17
- def self.create_from_json(json)
18
- return ConfigEntry::EMPTY if json.nil?
19
- return ConfigEntry.new(
20
- config = json.fetch(CONFIG, {}),
21
- etag = json.fetch(ETAG, ''),
22
- fetch_time = json.fetch(FETCH_TIME, Utils::DISTANT_PAST)
23
- )
24
- end
25
-
26
14
  def empty?
27
15
  self == ConfigEntry::EMPTY
28
16
  end
29
17
 
30
- def to_json
31
- {
32
- CONFIG => config,
33
- ETAG => etag,
34
- FETCH_TIME => fetch_time
35
- }
18
+ def serialize
19
+ "#{(fetch_time * 1000).floor}\n#{etag}\n#{config_json_string}"
20
+ end
21
+
22
+ def self.create_from_string(string)
23
+ return ConfigEntry.empty if string.nil? || string.empty?
24
+
25
+ fetch_time_index = string.index("\n")
26
+ etag_index = string.index("\n", fetch_time_index + 1)
27
+ if fetch_time_index.nil? || etag_index.nil?
28
+ raise 'Number of values is fewer than expected.'
29
+ end
30
+
31
+ begin
32
+ fetch_time = Float(string[0...fetch_time_index])
33
+ rescue ArgumentError
34
+ raise "Invalid fetch time: #{string[0...fetch_time_index]}"
35
+ end
36
+
37
+ etag = string[fetch_time_index + 1...etag_index]
38
+ if etag.nil? || etag.empty?
39
+ raise 'Empty eTag value'
40
+ end
41
+ begin
42
+ config_json = string[etag_index + 1..-1]
43
+ config = JSON.parse(config_json)
44
+ rescue => e
45
+ raise "Invalid config JSON: #{config_json}. #{e.message}"
46
+ end
47
+
48
+ ConfigEntry.new(config, etag, config_json, fetch_time / 1000.0)
36
49
  end
37
50
 
38
51
  EMPTY = ConfigEntry.new(etag: 'empty')
@@ -140,12 +140,13 @@ module ConfigCat
140
140
  # Try to download again with the new url
141
141
 
142
142
  if redirect == RedirectMode::SHOULD_REDIRECT
143
- @log.warn("Your data_governance parameter at ConfigCatClient initialization is not in sync with your preferences on the ConfigCat Dashboard: https://app.configcat.com/organization/data-governance. Only Organization Admins can set this preference.")
143
+ @log.warn(3002, "The `dataGovernance` parameter specified at the client initialization is not in sync with the preferences on the ConfigCat Dashboard. " \
144
+ "Read more: https://configcat.com/docs/advanced/data-governance/")
144
145
  end
145
146
 
146
147
  # To prevent loops we check if we retried at least 3 times with the new base_url
147
148
  if retries >= 2
148
- @log.error("Redirect loop during config.json fetch. Please contact support@configcat.com.")
149
+ @log.error(1104, "Redirection loop encountered while trying to fetch config JSON. Please contact us at https://configcat.com/support/")
149
150
  return fetch_response
150
151
  end
151
152
 
@@ -178,27 +179,27 @@ module ConfigCat
178
179
  response_etag = ""
179
180
  end
180
181
  config = JSON.parse(response.body)
181
- return FetchResponse.success(ConfigEntry.new(config, response_etag, Utils.get_utc_now_seconds_since_epoch))
182
+ return FetchResponse.success(ConfigEntry.new(config, response_etag, response.body, Utils.get_utc_now_seconds_since_epoch))
182
183
  when Net::HTTPNotModified
183
184
  return FetchResponse.not_modified
184
185
  when Net::HTTPNotFound, Net::HTTPForbidden
185
- error = "Double-check your SDK Key at https://app.configcat.com/sdkkey. Received unexpected response: #{response}"
186
- @log.error(error)
186
+ error = "Your SDK Key seems to be wrong. You can find the valid SDK Key at https://app.configcat.com/sdkkey. Received unexpected response: #{response}"
187
+ @log.error(1100, error)
187
188
  return FetchResponse.failure(error, false)
188
189
  else
189
190
  raise Net::HTTPError.new("", response)
190
191
  end
191
192
  rescue Net::HTTPError => e
192
- error = "Unexpected HTTP response was received: #{e}"
193
- @log.error(error)
193
+ error = "Unexpected HTTP response was received while trying to fetch config JSON: #{e}"
194
+ @log.error(1101, error)
194
195
  return FetchResponse.failure(error, true)
195
196
  rescue Timeout::Error => e
196
- error = "Request timed out. Timeout values: [connect: #{get_open_timeout()}s, read: #{get_read_timeout()}s]"
197
- @log.error(error)
197
+ error = "Request timed out while trying to fetch config JSON. Timeout values: [connect: #{get_open_timeout()}s, read: #{get_read_timeout()}s]"
198
+ @log.error(1102, error)
198
199
  return FetchResponse.failure(error, true)
199
200
  rescue Exception => e
200
- error = "An exception occurred during fetching: #{e}"
201
- @log.error(error)
201
+ error = "Unexpected error occurred while trying to fetch config JSON: #{e}"
202
+ @log.error(1103, error)
202
203
  return FetchResponse.failure(error, true)
203
204
  end
204
205
  end
@@ -7,14 +7,13 @@ require 'configcat/refreshresult'
7
7
  module ConfigCat
8
8
  class ConfigService
9
9
  def initialize(sdk_key, polling_mode, hooks, config_fetcher, log, config_cache, is_offline)
10
- @sdk_key = sdk_key
11
10
  @cached_entry = ConfigEntry::EMPTY
12
11
  @cached_entry_string = ''
13
12
  @polling_mode = polling_mode
14
13
  @log = log
15
14
  @config_cache = config_cache
16
15
  @hooks = hooks
17
- @cache_key = Digest::SHA1.hexdigest("ruby_#{CONFIG_FILE_NAME}_#{@sdk_key}")
16
+ @cache_key = ConfigService.get_cache_key(sdk_key)
18
17
  @config_fetcher = config_fetcher
19
18
  @is_offline = is_offline
20
19
  @response_future = nil
@@ -24,7 +23,7 @@ module ConfigCat
24
23
  @fetch_finished = Concurrent::Event.new
25
24
  @start_time = Utils.get_utc_now_seconds_since_epoch
26
25
 
27
- if @polling_mode.is_a?(AutoPollingMode)
26
+ if @polling_mode.is_a?(AutoPollingMode) && !@is_offline
28
27
  start_poll
29
28
  else
30
29
  set_initialized
@@ -34,7 +33,10 @@ module ConfigCat
34
33
  def get_settings
35
34
  if @polling_mode.is_a?(LazyLoadingMode)
36
35
  entry, _ = fetch_if_older(Utils.get_utc_now_seconds_since_epoch - @polling_mode.cache_refresh_interval_seconds)
37
- return entry.config[FEATURE_FLAGS], entry.fetch_time
36
+ return !entry.empty? ?
37
+ [entry.config.fetch(FEATURE_FLAGS, {}), entry.fetch_time] :
38
+ [nil, Utils::DISTANT_PAST]
39
+
38
40
  elsif @polling_mode.is_a?(AutoPollingMode) && !@initialized.set?
39
41
  elapsed_time = Utils.get_utc_now_seconds_since_epoch - @start_time # Elapsed time in seconds
40
42
  if elapsed_time < @polling_mode.max_init_wait_time_seconds
@@ -43,13 +45,17 @@ module ConfigCat
43
45
  # Max wait time expired without result, notify subscribers with the cached config.
44
46
  if !@initialized.set?
45
47
  set_initialized
46
- return @cached_entry.config[FEATURE_FLAGS], @cached_entry.fetch_time
48
+ return !@cached_entry.empty? ?
49
+ [@cached_entry.config.fetch(FEATURE_FLAGS, {}), @cached_entry.fetch_time] :
50
+ [nil, Utils::DISTANT_PAST]
47
51
  end
48
52
  end
49
53
  end
50
54
 
51
55
  entry, _ = fetch_if_older(Utils::DISTANT_PAST, prefer_cache: true)
52
- return entry.config[FEATURE_FLAGS], entry.fetch_time
56
+ return !entry.empty? ?
57
+ [entry.config.fetch(FEATURE_FLAGS, {}), entry.fetch_time] :
58
+ [nil, Utils::DISTANT_PAST]
53
59
  end
54
60
 
55
61
  # :return [RefreshResult]
@@ -68,7 +74,7 @@ module ConfigCat
68
74
  if @polling_mode.is_a?(AutoPollingMode)
69
75
  start_poll
70
76
  end
71
- @log.debug('Switched to ONLINE mode.')
77
+ @log.info(5200, 'Switched to ONLINE mode.')
72
78
  end
73
79
  end
74
80
 
@@ -84,7 +90,7 @@ module ConfigCat
84
90
  @thread.join
85
91
  end
86
92
 
87
- @log.debug('Switched to OFFLINE mode.')
93
+ @log.info(5200, 'Switched to OFFLINE mode.')
88
94
  end
89
95
  end
90
96
 
@@ -100,6 +106,10 @@ module ConfigCat
100
106
 
101
107
  private
102
108
 
109
+ def self.get_cache_key(sdk_key)
110
+ Digest::SHA1.hexdigest("#{sdk_key}_#{CONFIG_FILE_NAME}.json_#{SERIALIZATION_FORMAT_VERSION}")
111
+ end
112
+
103
113
  # :return [ConfigEntry, String] Returns the ConfigEntry object and error message in case of any error.
104
114
  def fetch_if_older(time, prefer_cache: false)
105
115
  # Sync up with the cache and use it when it's not expired.
@@ -127,8 +137,8 @@ module ConfigCat
127
137
 
128
138
  # If we are in offline mode we are not allowed to initiate fetch.
129
139
  if @is_offline
130
- offline_warning = 'The SDK is in offline mode, it can not initiate HTTP calls.'
131
- @log.warn(offline_warning)
140
+ offline_warning = "Client is in offline mode, it cannot initiate HTTP calls."
141
+ @log.warn(3200, offline_warning)
132
142
  return @cached_entry, offline_warning
133
143
  end
134
144
  end
@@ -194,18 +204,18 @@ module ConfigCat
194
204
  end
195
205
 
196
206
  @cached_entry_string = json_string
197
- return ConfigEntry.create_from_json(JSON.parse(json_string))
207
+ return ConfigEntry.create_from_string(json_string)
198
208
  rescue Exception => e
199
- @log.error("An error occurred during the cache read. #{e}")
209
+ @log.error(2200, "Error occurred while reading the cache. #{e}")
200
210
  return ConfigEntry::EMPTY
201
211
  end
202
212
  end
203
213
 
204
214
  def write_cache(config_entry)
205
215
  begin
206
- @config_cache.set(@cache_key, config_entry.to_json.to_json)
216
+ @config_cache.set(@cache_key, config_entry.serialize)
207
217
  rescue Exception => e
208
- @log.error("An error occurred during the cache write. #{e}")
218
+ @log.error(2201, "Error occurred while writing the cache. #{e}")
209
219
  end
210
220
  end
211
221
  end
@@ -1,5 +1,6 @@
1
1
  module ConfigCat
2
2
  CONFIG_FILE_NAME = "config_v5"
3
+ SERIALIZATION_FORMAT_VERSION = "v2"
3
4
 
4
5
  PREFERENCES = "p"
5
6
  BASE_URL = "u"
@@ -19,7 +19,7 @@ module ConfigCat
19
19
  super(override_behaviour)
20
20
  @log = log
21
21
  if !File.exists?(file_path)
22
- @log.error("The file '%s' does not exists." % file_path)
22
+ @log.error(1300, "Cannot find the local config file '#{file_path}'. This is a path that your application provided to the ConfigCat SDK by passing it to the `LocalFileFlagOverrides.new()` method. Read more: https://configcat.com/docs/sdk-reference/ruby/#json-file")
23
23
  end
24
24
  @_file_path = file_path
25
25
  @_settings = nil
@@ -51,9 +51,9 @@ module ConfigCat
51
51
  end
52
52
  end
53
53
  rescue JSON::ParserError => e
54
- @log.error("Could not decode json from file %s. %s" % [@_file_path, e.to_s])
54
+ @log.error(2302, "Failed to decode JSON from the local config file '#{@_file_path}'. #{e}")
55
55
  rescue Exception => e
56
- @log.error("Could not read the content of the file %s. %s" % [@_file_path, e.to_s])
56
+ @log.error(1302, "Failed to read the local config file '#{@_file_path}'. #{e}")
57
57
  end
58
58
  end
59
59
  end
@@ -15,25 +15,30 @@ module ConfigCat
15
15
  def evaluate(key:, user:, default_value:, default_variation_id:, settings:)
16
16
  setting_descriptor = settings[key]
17
17
  if setting_descriptor === nil
18
- error = "Evaluating get_value('%s') failed. Value not found for key '%s'. Returning default_value: [%s]. Here are the available keys: %s" % [key, key, default_value.to_s, settings.keys.join(", ")]
19
- @log.error(error)
18
+ error = "Failed to evaluate setting '#{key}' (the key was not found in config JSON). " \
19
+ "Returning the `default_value` parameter that you specified in your application: '#{default_value}'. " \
20
+ "Available keys: [#{settings.keys.map { |s| "'#{s}'" }.join(", ")}]."
21
+ @log.error(1001, error)
20
22
  return default_value, default_variation_id, nil, nil, error
21
23
  end
22
24
 
23
25
  rollout_rules = setting_descriptor.fetch(ROLLOUT_RULES, [])
24
26
  rollout_percentage_items = setting_descriptor.fetch(ROLLOUT_PERCENTAGE_ITEMS, [])
25
27
 
26
- if !user.equal?(nil) && !user.class.equal?(User)
27
- @log.warn("Evaluating get_value('%s'). User Object is not an instance of User type." % key)
28
+ user_has_invalid_type = !user.equal?(nil) && !user.class.equal?(User)
29
+ if user_has_invalid_type
30
+ @log.warn(4001, "Cannot evaluate targeting rules and % options for setting '#{key}' (User Object is not an instance of User type).")
28
31
  user = nil
29
32
  end
30
33
  if user === nil
31
- if rollout_rules.size > 0 || rollout_percentage_items.size > 0
32
- @log.warn("Evaluating get_value('%s'). UserObject missing! You should pass a UserObject to get_value(), in order to make targeting work properly. Read more: https://configcat.com/docs/advanced/user-object/" % key)
34
+ if !user_has_invalid_type && (rollout_rules.size > 0 || rollout_percentage_items.size > 0)
35
+ @log.warn(3001, "Cannot evaluate targeting rules and % options for setting '#{key}' (User Object is missing). " \
36
+ "You should pass a User Object to the evaluation methods like `get_value()` in order to make targeting work properly. " \
37
+ "Read more: https://configcat.com/docs/advanced/user-object/")
33
38
  end
34
39
  return_value = setting_descriptor.fetch(VALUE, default_value)
35
40
  return_variation_id = setting_descriptor.fetch(VARIATION_ID, default_variation_id)
36
- @log.info("Returning [%s]" % return_value.to_s)
41
+ @log.info(5000, "Returning [#{return_value}]")
37
42
  return return_value, return_variation_id, nil, nil, nil
38
43
  end
39
44
 
@@ -94,7 +99,7 @@ module ConfigCat
94
99
  end
95
100
  rescue ArgumentError => e
96
101
  message = format_validation_error_rule(comparison_attribute, user_value, comparator, comparison_value, e.to_s)
97
- @log.warn(message)
102
+ @log.warn(0, message)
98
103
  log_entries.push(message)
99
104
  next
100
105
  end
@@ -112,7 +117,7 @@ module ConfigCat
112
117
  end
113
118
  rescue ArgumentError => e
114
119
  message = format_validation_error_rule(comparison_attribute, user_value, comparator, comparison_value, e.to_s)
115
- @log.warn(message)
120
+ @log.warn(0, message)
116
121
  log_entries.push(message)
117
122
  next
118
123
  end
@@ -131,7 +136,7 @@ module ConfigCat
131
136
  end
132
137
  rescue Exception => e
133
138
  message = format_validation_error_rule(comparison_attribute, user_value, comparator, comparison_value, e.to_s)
134
- @log.warn(message)
139
+ @log.warn(0, message)
135
140
  log_entries.push(message)
136
141
  next
137
142
  end
@@ -171,7 +176,7 @@ module ConfigCat
171
176
  log_entries.push("Returning %s" % return_value)
172
177
  return return_value, return_variation_id, nil, nil, nil
173
178
  ensure
174
- @log.info(log_entries.join("\n"))
179
+ @log.info(5000, log_entries.join("\n"))
175
180
  end
176
181
  end
177
182
 
@@ -1,3 +1,3 @@
1
1
  module ConfigCat
2
- VERSION = "6.0.0"
2
+ VERSION = "7.0.0"
3
3
  end
data/lib/configcat.rb CHANGED
@@ -24,164 +24,4 @@ module ConfigCat
24
24
  def ConfigCat.close_all
25
25
  ConfigCatClient.close_all
26
26
  end
27
-
28
- def ConfigCat.create_client(sdk_key, data_governance: DataGovernance::GLOBAL)
29
- #
30
- # Create an instance of ConfigCatClient and setup Auto Poll mode with default options
31
- #
32
- # :param sdk_key: ConfigCat SDK Key to access your configuration.
33
- # :param data_governance:
34
- # Default: Global. Set this parameter to be in sync with the Data Governance preference on the Dashboard:
35
- # https://app.configcat.com/organization/data-governance
36
- # (Only Organization Admins have access)
37
- #
38
- return create_client_with_auto_poll(sdk_key, data_governance: data_governance)
39
- end
40
-
41
- # Create an instance of ConfigCatClient and setup Auto Poll mode with custom options
42
- #
43
- # :param sdk_key: ConfigCat SDK Key to access your configuration.
44
- # :param poll_interval_seconds: The client's poll interval in seconds. Default: 60 seconds.
45
- # :param on_configuration_changed_callback: You can subscribe to configuration changes with this callback
46
- # :param max_init_wait_time_seconds: maximum waiting time for first configuration fetch in polling mode.
47
- # :param config_cache: If you want to use custom caching instead of the client's default,
48
- # You can provide an implementation of ConfigCache.
49
- # :param base_url: You can set a base_url if you want to use a proxy server between your application and ConfigCat
50
- # :param proxy_address: Proxy address
51
- # :param proxy_port: Proxy port
52
- # :param proxy_user: username for proxy authentication
53
- # :param proxy_pass: password for proxy authentication
54
- # :param open_timeout_seconds: The number of seconds to wait for the server to make the initial connection. Default: 10 seconds.
55
- # :param read_timeout_seconds: The number of seconds to wait for the server to respond before giving up. Default: 30 seconds.
56
- # :param flag_overrides: A FlagOverrides implementation used to override feature flags & settings.
57
- # :param data_governance:
58
- # Default: Global. Set this parameter to be in sync with the Data Governance preference on the Dashboard:
59
- # https://app.configcat.com/organization/data-governance
60
- # (Only Organization Admins have access)
61
- def ConfigCat.create_client_with_auto_poll(sdk_key,
62
- poll_interval_seconds: 60,
63
- max_init_wait_time_seconds: 5,
64
- on_configuration_changed_callback: nil,
65
- config_cache: nil,
66
- base_url: nil,
67
- proxy_address: nil,
68
- proxy_port: nil,
69
- proxy_user: nil,
70
- proxy_pass: nil,
71
- open_timeout_seconds: 10,
72
- read_timeout_seconds: 30,
73
- flag_overrides: nil,
74
- data_governance: DataGovernance::GLOBAL)
75
- options = ConfigCatOptions.new(
76
- base_url: base_url,
77
- polling_mode: PollingMode.auto_poll(poll_interval_seconds: poll_interval_seconds, max_init_wait_time_seconds: max_init_wait_time_seconds),
78
- config_cache: config_cache,
79
- proxy_address: proxy_address,
80
- proxy_port: proxy_port,
81
- proxy_user: proxy_user,
82
- proxy_pass: proxy_pass,
83
- open_timeout_seconds: open_timeout_seconds,
84
- read_timeout_seconds: read_timeout_seconds,
85
- flag_overrides: flag_overrides,
86
- data_governance: data_governance
87
- )
88
- client = ConfigCatClient.get(sdk_key, options)
89
- client.hooks.add_on_config_changed(on_configuration_changed_callback) if on_configuration_changed_callback
90
- client.log.warn('create_client_with_auto_poll is deprecated. Create the ConfigCat Client as a Singleton object with `configcatclient.get()` instead')
91
- return client
92
- end
93
-
94
- # Create an instance of ConfigCatClient and setup Lazy Load mode with custom options
95
- #
96
- # :param sdk_key: ConfigCat SDK Key to access your configuration.
97
- # :param cache_time_to_live_seconds: The cache TTL.
98
- # :param config_cache: If you want to use custom caching instead of the client's default,
99
- # You can provide an implementation of ConfigCache.
100
- # :param base_url: You can set a base_url if you want to use a proxy server between your application and ConfigCat
101
- # :param proxy_address: Proxy address
102
- # :param proxy_port: Proxy port
103
- # :param proxy_user: username for proxy authentication
104
- # :param proxy_pass: password for proxy authentication
105
- # :param open_timeout_seconds: The number of seconds to wait for the server to make the initial connection. Default: 10 seconds.
106
- # :param read_timeout_seconds: The number of seconds to wait for the server to respond before giving up. Default: 30 seconds.
107
- # :param flag_overrides: A FlagOverrides implementation used to override feature flags & settings.
108
- # :param data_governance:
109
- # Default: Global. Set this parameter to be in sync with the Data Governance preference on the Dashboard:
110
- # https://app.configcat.com/organization/data-governance
111
- # (Only Organization Admins have access)
112
- def ConfigCat.create_client_with_lazy_load(sdk_key,
113
- cache_time_to_live_seconds: 60,
114
- config_cache: nil,
115
- base_url: nil,
116
- proxy_address: nil,
117
- proxy_port: nil,
118
- proxy_user: nil,
119
- proxy_pass: nil,
120
- open_timeout_seconds: 10,
121
- read_timeout_seconds: 30,
122
- flag_overrides: nil,
123
- data_governance: DataGovernance::GLOBAL)
124
- options = ConfigCatOptions.new(
125
- base_url: base_url,
126
- polling_mode: PollingMode.lazy_load(cache_refresh_interval_seconds: cache_time_to_live_seconds),
127
- config_cache: config_cache,
128
- proxy_address: proxy_address,
129
- proxy_port: proxy_port,
130
- proxy_user: proxy_user,
131
- proxy_pass: proxy_pass,
132
- open_timeout_seconds: open_timeout_seconds,
133
- read_timeout_seconds: read_timeout_seconds,
134
- flag_overrides: flag_overrides,
135
- data_governance: data_governance
136
- )
137
- client = ConfigCatClient.get(sdk_key, options)
138
- client.log.warn('create_client_with_lazy_load is deprecated. Create the ConfigCat Client as a Singleton object with `configcatclient.get()` instead')
139
- return client
140
- end
141
-
142
- # Create an instance of ConfigCatClient and setup Manual Poll mode with custom options
143
- #
144
- # :param sdk_key: ConfigCat SDK Key to access your configuration.
145
- # :param config_cache: If you want to use custom caching instead of the client's default,
146
- # You can provide an implementation of ConfigCache.
147
- # :param base_url: You can set a base_url if you want to use a proxy server between your application and ConfigCat
148
- # :param proxy_address: Proxy address
149
- # :param proxy_port: Proxy port
150
- # :param proxy_user: username for proxy authentication
151
- # :param proxy_pass: password for proxy authentication
152
- # :param open_timeout_seconds: The number of seconds to wait for the server to make the initial connection. Default: 10 seconds.
153
- # :param read_timeout_seconds: The number of seconds to wait for the server to respond before giving up. Default: 30 seconds.
154
- # :param flag_overrides: A FlagOverrides implementation used to override feature flags & settings.
155
- # :param data_governance:
156
- # Default: Global. Set this parameter to be in sync with the Data Governance preference on the Dashboard:
157
- # https://app.configcat.com/organization/data-governance
158
- # (Only Organization Admins have access)
159
- def ConfigCat.create_client_with_manual_poll(sdk_key,
160
- config_cache: nil,
161
- base_url: nil,
162
- proxy_address: nil,
163
- proxy_port: nil,
164
- proxy_user: nil,
165
- proxy_pass: nil,
166
- open_timeout_seconds: 10,
167
- read_timeout_seconds: 30,
168
- flag_overrides: nil,
169
- data_governance: DataGovernance::GLOBAL)
170
- options = ConfigCatOptions.new(
171
- base_url: base_url,
172
- polling_mode: PollingMode.manual_poll(),
173
- config_cache: config_cache,
174
- proxy_address: proxy_address,
175
- proxy_port: proxy_port,
176
- proxy_user: proxy_user,
177
- proxy_pass: proxy_pass,
178
- open_timeout_seconds: open_timeout_seconds,
179
- read_timeout_seconds: read_timeout_seconds,
180
- flag_overrides: flag_overrides,
181
- data_governance: data_governance
182
- )
183
- client = ConfigCatClient.get(sdk_key, options)
184
- client.log.warn('create_client_with_manual_poll is deprecated. Create the ConfigCat Client as a Singleton object with `configcatclient.get()` instead')
185
- return client
186
- end
187
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: configcat
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.0
4
+ version: 7.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ConfigCat
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-27 00:00:00.000000000 Z
11
+ date: 2023-07-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby