configcat 6.0.0 → 7.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: 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