configcat 3.1.0 → 4.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: b842d2ff2f62e6a6c3dbe2ddab53c561e4b1db93f3928ce805044127cd2d7819
4
- data.tar.gz: 6d64d084c4a732d26d54879d914f4e9ce1722b9e73fee2aa4161cc5503e152d7
3
+ metadata.gz: 118a3db79c8d7d9a0795897380a4dfaf14fecda8a636024abfd9d2433b3af924
4
+ data.tar.gz: 4c85c82b81fe08fcf9b6eed0a40bea06369939301aa09bc12e82b33a3b2176eb
5
5
  SHA512:
6
- metadata.gz: 83a7d19dc642e492bb5443a1fc42f0f35db8f5278f02582848e8677133f4450faa41a1a30b158ccdca58bc5396cad109b914fa4851e4db74dcf03df1f5129d00
7
- data.tar.gz: 2e79ed9965f3c9da2f8afd9fed4636b6d349b0bda09fdfb0d8398b6e4334a458713114d23083fc5f611878ea02801c5e8ea1e73fad54f6e580ef1c098e8f9d7c
6
+ metadata.gz: afe03eda0affc92755ae0eb91196a15bfe61f68a12244270bb5d19b3870bc023fe9ccf3231d8f11f414c4439b49fd2f9481e9a64295c3ab87697511ebcf57b25
7
+ data.tar.gz: 5ac8e3beef89cbc84ef89f2eb5b071fcf5cb348db1c302755ba4fc619c759f9919f80785b2b08a4a583725d35ea6b9ef038d869706956485eec3b4a9d4cadbaa
@@ -10,13 +10,17 @@ module ConfigCat
10
10
  attr_accessor :logger
11
11
  end
12
12
 
13
- def ConfigCat.create_client(sdk_key)
13
+ def ConfigCat.create_client(sdk_key, data_governance: DataGovernance::GLOBAL)
14
14
  #
15
15
  # Create an instance of ConfigCatClient and setup Auto Poll mode with default options
16
16
  #
17
17
  # :param sdk_key: ConfigCat SDK Key to access your configuration.
18
+ # :param data_governance:
19
+ # Default: Global. Set this parameter to be in sync with the Data Governance preference on the Dashboard:
20
+ # https://app.configcat.com/organization/data-governance
21
+ # (Only Organization Admins have access)
18
22
  #
19
- return create_client_with_auto_poll(sdk_key)
23
+ return create_client_with_auto_poll(sdk_key, data_governance: data_governance)
20
24
  end
21
25
 
22
26
  def ConfigCat.create_client_with_auto_poll(sdk_key,
@@ -25,10 +29,11 @@ module ConfigCat
25
29
  on_configuration_changed_callback: nil,
26
30
  config_cache_class: nil,
27
31
  base_url: nil,
28
- proxy_address:nil,
29
- proxy_port:nil,
30
- proxy_user:nil,
31
- proxy_pass:nil)
32
+ proxy_address: nil,
33
+ proxy_port: nil,
34
+ proxy_user: nil,
35
+ proxy_pass: nil,
36
+ data_governance: DataGovernance::GLOBAL)
32
37
  #
33
38
  # Create an instance of ConfigCatClient and setup Auto Poll mode with custom options
34
39
  #
@@ -43,6 +48,10 @@ module ConfigCat
43
48
  # :param proxy_port: Proxy port
44
49
  # :param proxy_user: username for proxy authentication
45
50
  # :param proxy_pass: password for proxy authentication
51
+ # :param data_governance:
52
+ # Default: Global. Set this parameter to be in sync with the Data Governance preference on the Dashboard:
53
+ # https://app.configcat.com/organization/data-governance
54
+ # (Only Organization Admins have access)
46
55
  #
47
56
  if sdk_key === nil
48
57
  raise ConfigCatClientException, "SDK Key is required."
@@ -63,17 +72,19 @@ module ConfigCat
63
72
  proxy_address: proxy_address,
64
73
  proxy_port: proxy_port,
65
74
  proxy_user: proxy_user,
66
- proxy_pass: proxy_pass)
75
+ proxy_pass: proxy_pass,
76
+ data_governance: data_governance)
67
77
  end
68
78
 
69
79
  def ConfigCat.create_client_with_lazy_load(sdk_key,
70
80
  cache_time_to_live_seconds: 60,
71
81
  config_cache_class: nil,
72
82
  base_url: nil,
73
- proxy_address:nil,
74
- proxy_port:nil,
75
- proxy_user:nil,
76
- proxy_pass:nil)
83
+ proxy_address: nil,
84
+ proxy_port: nil,
85
+ proxy_user: nil,
86
+ proxy_pass: nil,
87
+ data_governance: DataGovernance::GLOBAL)
77
88
  #
78
89
  # Create an instance of ConfigCatClient and setup Lazy Load mode with custom options
79
90
  #
@@ -86,6 +97,10 @@ module ConfigCat
86
97
  # :param proxy_port: Proxy port
87
98
  # :param proxy_user: username for proxy authentication
88
99
  # :param proxy_pass: password for proxy authentication
100
+ # :param data_governance:
101
+ # Default: Global. Set this parameter to be in sync with the Data Governance preference on the Dashboard:
102
+ # https://app.configcat.com/organization/data-governance
103
+ # (Only Organization Admins have access)
89
104
  #
90
105
  if sdk_key === nil
91
106
  raise ConfigCatClientException, "SDK Key is required."
@@ -103,7 +118,8 @@ module ConfigCat
103
118
  proxy_address: proxy_address,
104
119
  proxy_port: proxy_port,
105
120
  proxy_user: proxy_user,
106
- proxy_pass: proxy_pass)
121
+ proxy_pass: proxy_pass,
122
+ data_governance: data_governance)
107
123
  end
108
124
 
109
125
  def ConfigCat.create_client_with_manual_poll(sdk_key,
@@ -112,7 +128,8 @@ module ConfigCat
112
128
  proxy_address:nil,
113
129
  proxy_port:nil,
114
130
  proxy_user:nil,
115
- proxy_pass:nil)
131
+ proxy_pass:nil,
132
+ data_governance: DataGovernance::GLOBAL)
116
133
  #
117
134
  # Create an instance of ConfigCatClient and setup Manual Poll mode with custom options
118
135
  #
@@ -124,6 +141,10 @@ module ConfigCat
124
141
  # :param proxy_port: Proxy port
125
142
  # :param proxy_user: username for proxy authentication
126
143
  # :param proxy_pass: password for proxy authentication
144
+ # :param data_governance:
145
+ # Default: Global. Set this parameter to be in sync with the Data Governance preference on the Dashboard:
146
+ # https://app.configcat.com/organization/data-governance
147
+ # (Only Organization Admins have access)
127
148
  #
128
149
  if sdk_key === nil
129
150
  raise ConfigCatClientException, "SDK Key is required."
@@ -138,7 +159,8 @@ module ConfigCat
138
159
  proxy_address: proxy_address,
139
160
  proxy_port: proxy_port,
140
161
  proxy_user: proxy_user,
141
- proxy_pass: proxy_pass)
162
+ proxy_pass: proxy_pass,
163
+ data_governance: data_governance)
142
164
  end
143
165
 
144
166
  end
@@ -1,9 +1,10 @@
1
1
  require 'configcat/interfaces'
2
+ require 'configcat/constants'
2
3
  require 'concurrent'
3
4
 
4
5
  module ConfigCat
5
6
  class AutoPollingCachePolicy < CachePolicy
6
- def initialize(config_fetcher, config_cache, poll_interval_seconds=60, max_init_wait_time_seconds=5, on_configuration_changed_callback=nil)
7
+ def initialize(config_fetcher, config_cache, cache_key, poll_interval_seconds=60, max_init_wait_time_seconds=5, on_configuration_changed_callback=nil)
7
8
  if poll_interval_seconds < 1
8
9
  poll_interval_seconds = 1
9
10
  end
@@ -12,6 +13,7 @@ module ConfigCat
12
13
  end
13
14
  @_config_fetcher = config_fetcher
14
15
  @_config_cache = config_cache
16
+ @_cache_key = cache_key
15
17
  @_poll_interval_seconds = poll_interval_seconds
16
18
  @_max_init_wait_time_seconds = max_init_wait_time_seconds
17
19
  @_on_configuration_changed_callback = on_configuration_changed_callback
@@ -40,7 +42,7 @@ module ConfigCat
40
42
  end
41
43
  begin
42
44
  @_lock.acquire_read_lock()
43
- return @_config_cache.get()
45
+ return @_config_cache.get(@_cache_key)
44
46
  ensure
45
47
  @_lock.release_read_lock()
46
48
  end
@@ -52,7 +54,7 @@ module ConfigCat
52
54
 
53
55
  begin
54
56
  @_lock.acquire_read_lock()
55
- old_configuration = @_config_cache.get()
57
+ old_configuration = @_config_cache.get(@_cache_key)
56
58
  ensure
57
59
  @_lock.release_read_lock()
58
60
  end
@@ -62,7 +64,7 @@ module ConfigCat
62
64
  if configuration != old_configuration
63
65
  begin
64
66
  @_lock.acquire_write_lock()
65
- @_config_cache.set(configuration)
67
+ @_config_cache.set(@_cache_key, configuration)
66
68
  @_initialized = true
67
69
  ensure
68
70
  @_lock.release_write_lock()
@@ -3,15 +3,15 @@ require 'configcat/interfaces'
3
3
  module ConfigCat
4
4
  class InMemoryConfigCache < ConfigCache
5
5
  def initialize()
6
- @_value = nil
6
+ @_value = {}
7
7
  end
8
8
 
9
- def get()
10
- return @_value
9
+ def get(key)
10
+ return @_value.fetch(key, nil)
11
11
  end
12
12
 
13
- def set(value)
14
- @_value = value
13
+ def set(key, value)
14
+ @_value[key] = value
15
15
  end
16
16
  end
17
17
  end
@@ -5,6 +5,7 @@ require 'configcat/autopollingcachepolicy'
5
5
  require 'configcat/manualpollingcachepolicy'
6
6
  require 'configcat/lazyloadingcachepolicy'
7
7
  require 'configcat/rolloutevaluator'
8
+ require 'configcat/datagovernance'
8
9
 
9
10
  module ConfigCat
10
11
  KeyValue = Struct.new(:key, :value)
@@ -19,7 +20,8 @@ module ConfigCat
19
20
  proxy_address:nil,
20
21
  proxy_port:nil,
21
22
  proxy_user:nil,
22
- proxy_pass:nil)
23
+ proxy_pass:nil,
24
+ data_governance: DataGovernance::GLOBAL)
23
25
  if sdk_key === nil
24
26
  raise ConfigCatClientException, "SDK Key is required."
25
27
  end
@@ -32,15 +34,15 @@ module ConfigCat
32
34
  end
33
35
 
34
36
  if poll_interval_seconds > 0
35
- @_config_fetcher = CacheControlConfigFetcher.new(sdk_key, "p", base_url, proxy_address, proxy_port, proxy_user, proxy_pass)
36
- @_cache_policy = AutoPollingCachePolicy.new(@_config_fetcher, @_config_cache, poll_interval_seconds, max_init_wait_time_seconds, on_configuration_changed_callback)
37
+ @_config_fetcher = CacheControlConfigFetcher.new(sdk_key, "p", base_url, proxy_address, proxy_port, proxy_user, proxy_pass, data_governance)
38
+ @_cache_policy = AutoPollingCachePolicy.new(@_config_fetcher, @_config_cache, _get_cache_key(), poll_interval_seconds, max_init_wait_time_seconds, on_configuration_changed_callback)
37
39
  else
38
40
  if cache_time_to_live_seconds > 0
39
- @_config_fetcher = CacheControlConfigFetcher.new(sdk_key, "l", base_url, proxy_address, proxy_port, proxy_user, proxy_pass)
40
- @_cache_policy = LazyLoadingCachePolicy.new(@_config_fetcher, @_config_cache, cache_time_to_live_seconds)
41
+ @_config_fetcher = CacheControlConfigFetcher.new(sdk_key, "l", base_url, proxy_address, proxy_port, proxy_user, proxy_pass, data_governance)
42
+ @_cache_policy = LazyLoadingCachePolicy.new(@_config_fetcher, @_config_cache, _get_cache_key(), cache_time_to_live_seconds)
41
43
  else
42
- @_config_fetcher = CacheControlConfigFetcher.new(sdk_key, "m", base_url, proxy_address, proxy_port, proxy_user, proxy_pass)
43
- @_cache_policy = ManualPollingCachePolicy.new(@_config_fetcher, @_config_cache)
44
+ @_config_fetcher = CacheControlConfigFetcher.new(sdk_key, "m", base_url, proxy_address, proxy_port, proxy_user, proxy_pass, data_governance)
45
+ @_cache_policy = ManualPollingCachePolicy.new(@_config_fetcher, @_config_cache, _get_cache_key())
44
46
  end
45
47
  end
46
48
  end
@@ -59,7 +61,11 @@ module ConfigCat
59
61
  if config === nil
60
62
  return []
61
63
  end
62
- return config.keys
64
+ feature_flags = config.fetch(FEATURE_FLAGS, nil)
65
+ if feature_flags === nil
66
+ return []
67
+ end
68
+ return feature_flags.keys
63
69
  end
64
70
 
65
71
  def get_variation_id(key, default_variation_id, user=nil)
@@ -92,22 +98,29 @@ module ConfigCat
92
98
  ConfigCat.logger.warn("Evaluating get_variation_id('%s') failed. Cache is empty. Returning nil." % variation_id)
93
99
  return nil
94
100
  end
95
- for key, value in config
96
- if variation_id == value.fetch(RolloutEvaluator::VARIATION_ID, nil)
97
- return KeyValue.new(key, value[RolloutEvaluator::VALUE])
101
+
102
+ feature_flags = config.fetch(FEATURE_FLAGS, nil)
103
+ if feature_flags === nil
104
+ ConfigCat.logger.warn("Evaluating get_key_and_value('%s') failed. Cache is empty. Returning None." % variation_id)
105
+ return nil
106
+ end
107
+
108
+ for key, value in feature_flags
109
+ if variation_id == value.fetch(VARIATION_ID, nil)
110
+ return KeyValue.new(key, value[VALUE])
98
111
  end
99
112
 
100
- rollout_rules = value.fetch(RolloutEvaluator::ROLLOUT_RULES, [])
113
+ rollout_rules = value.fetch(ROLLOUT_RULES, [])
101
114
  for rollout_rule in rollout_rules
102
- if variation_id == rollout_rule.fetch(RolloutEvaluator::VARIATION_ID, nil)
103
- return KeyValue.new(key, rollout_rule[RolloutEvaluator::VALUE])
115
+ if variation_id == rollout_rule.fetch(VARIATION_ID, nil)
116
+ return KeyValue.new(key, rollout_rule[VALUE])
104
117
  end
105
118
  end
106
119
 
107
- rollout_percentage_items = value.fetch(RolloutEvaluator::ROLLOUT_PERCENTAGE_ITEMS, [])
120
+ rollout_percentage_items = value.fetch(ROLLOUT_PERCENTAGE_ITEMS, [])
108
121
  for rollout_percentage_item in rollout_percentage_items
109
- if variation_id == rollout_percentage_item.fetch(RolloutEvaluator::VARIATION_ID, nil)
110
- return KeyValue.new(key, rollout_percentage_item[RolloutEvaluator::VALUE])
122
+ if variation_id == rollout_percentage_item.fetch(VARIATION_ID, nil)
123
+ return KeyValue.new(key, rollout_percentage_item[VALUE])
111
124
  end
112
125
  end
113
126
  end
@@ -122,5 +135,11 @@ module ConfigCat
122
135
  @_config_fetcher.close()
123
136
  end
124
137
 
138
+ private
139
+
140
+ def _get_cache_key()
141
+ return Digest::SHA1.hexdigest("ruby_" + CONFIG_FILE_NAME + "_" + @_sdk_key)
142
+ end
143
+
125
144
  end
126
145
  end
@@ -1,13 +1,22 @@
1
1
  require 'configcat/interfaces'
2
2
  require 'configcat/version'
3
+ require 'configcat/datagovernance'
4
+ require 'configcat/constants'
3
5
  require 'net/http'
4
6
  require 'uri'
5
7
  require 'json'
6
8
 
7
9
  module ConfigCat
8
- BASE_URL = "https://cdn.configcat.com"
10
+ BASE_URL_GLOBAL = "https://cdn-global.configcat.com"
11
+ BASE_URL_EU_ONLY = "https://cdn-eu.configcat.com"
9
12
  BASE_PATH = "configuration-files/"
10
- BASE_EXTENSION = "/config_v4.json"
13
+ BASE_EXTENSION = "/" + CONFIG_FILE_NAME + ".json"
14
+
15
+ class RedirectMode
16
+ NO_REDIRECT = 0
17
+ SHOULD_REDIRECT = 1
18
+ FORCE_REDIRECT = 2
19
+ end
11
20
 
12
21
  class FetchResponse
13
22
  def initialize(response)
@@ -32,34 +41,89 @@ module ConfigCat
32
41
  end
33
42
 
34
43
  class CacheControlConfigFetcher < ConfigFetcher
35
- def initialize(sdk_key, mode, base_url=nil, proxy_address=nil, proxy_port=nil, proxy_user=nil, proxy_pass=nil)
44
+ def initialize(sdk_key, mode, base_url=nil, proxy_address=nil, proxy_port=nil, proxy_user=nil, proxy_pass=nil,
45
+ data_governance=DataGovernance::GLOBAL)
36
46
  @_sdk_key = sdk_key
47
+ @_proxy_address = proxy_address
48
+ @_proxy_port = proxy_port
49
+ @_proxy_user = proxy_user
50
+ @_proxy_pass = proxy_pass
37
51
  @_etag = ""
38
52
  @_headers = {"User-Agent" => ((("ConfigCat-Ruby/") + mode) + ("-")) + VERSION, "X-ConfigCat-UserAgent" => ((("ConfigCat-Ruby/") + mode) + ("-")) + VERSION, "Content-Type" => "application/json"}
39
53
  if !base_url.equal?(nil)
54
+ @_base_url_overridden = true
40
55
  @_base_url = base_url.chomp("/")
41
56
  else
42
- @_base_url = BASE_URL
57
+ @_base_url_overridden = false
58
+ if data_governance == DataGovernance::EU_ONLY
59
+ @_base_url = BASE_URL_EU_ONLY
60
+ else
61
+ @_base_url = BASE_URL_GLOBAL
62
+ end
43
63
  end
44
- uri = URI.parse(@_base_url)
45
- @_http = Net::HTTP.new(uri.host, uri.port, proxy_address, proxy_port, proxy_user, proxy_pass)
46
- @_http.use_ssl = true if uri.scheme == 'https'
47
- @_http.open_timeout = 10 # in seconds
48
- @_http.read_timeout = 30 # in seconds
49
64
  end
50
65
 
51
66
  # Returns the FetchResponse object contains configuration json Dictionary
52
- def get_configuration_json()
67
+ def get_configuration_json(retries=0)
53
68
  ConfigCat.logger.debug "Fetching configuration from ConfigCat"
54
69
  uri = URI.parse((((@_base_url + ("/")) + BASE_PATH) + @_sdk_key) + BASE_EXTENSION)
55
70
  headers = @_headers
56
71
  headers["If-None-Match"] = @_etag unless @_etag.empty?
72
+ _create_http()
57
73
  request = Net::HTTP::Get.new(uri.request_uri, headers)
58
74
  response = @_http.request(request)
59
75
  etag = response["ETag"]
60
76
  @_etag = etag unless etag.nil? || etag.empty?
61
77
  ConfigCat.logger.debug "ConfigCat configuration json fetch response code:#{response.code} Cached:#{response['ETag']}"
62
- return FetchResponse.new(response)
78
+ fetch_response = FetchResponse.new(response)
79
+
80
+ # If there wasn't a config change, we return the response.
81
+ if !fetch_response.is_fetched()
82
+ return fetch_response
83
+ end
84
+
85
+ preferences = fetch_response.json().fetch(PREFERENCES, nil)
86
+ if preferences === nil
87
+ return fetch_response
88
+ end
89
+
90
+ base_url = preferences.fetch(BASE_URL, nil)
91
+
92
+ # If the base_url is the same as the last called one, just return the response.
93
+ if base_url.equal?(nil) || @_base_url == base_url
94
+ return fetch_response
95
+ end
96
+
97
+ redirect = preferences.fetch(REDIRECT, nil)
98
+ # If the base_url is overridden, and the redirect parameter is not 2 (force),
99
+ # the SDK should not redirect the calls and it just have to return the response.
100
+ if @_base_url_overridden && redirect != RedirectMode::FORCE_REDIRECT
101
+ return fetch_response
102
+ end
103
+
104
+ # The next call should use the base_url provided in the config json
105
+ @_base_url = base_url
106
+
107
+ # If the redirect property == 0 (redirect not needed), return the response
108
+ if redirect == RedirectMode::NO_REDIRECT
109
+ # Return the response
110
+ return fetch_response
111
+ end
112
+
113
+ # Try to download again with the new url
114
+
115
+ if redirect == RedirectMode::SHOULD_REDIRECT
116
+ ConfigCat.logger.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.")
117
+ end
118
+
119
+ # To prevent loops we check if we retried at least 3 times with the new base_url
120
+ if retries >= 2
121
+ ConfigCat.logger.error("Redirect loop during config.json fetch. Please contact support@configcat.com.")
122
+ return fetch_response
123
+ end
124
+
125
+ # Retry the config download with the new base_url
126
+ return get_configuration_json(retries + 1)
63
127
  end
64
128
 
65
129
  def close()
@@ -67,5 +131,19 @@ module ConfigCat
67
131
  @_http = nil
68
132
  end
69
133
  end
134
+
135
+ private
136
+
137
+ def _create_http()
138
+ uri = URI.parse(@_base_url)
139
+ use_ssl = true if uri.scheme == 'https'
140
+ if @_http.equal?(nil) || @_http.address != uri.host || @_http.port != uri.port || @_http.use_ssl? != use_ssl
141
+ close()
142
+ @_http = Net::HTTP.new(uri.host, uri.port, @_proxy_address, @_proxy_port, @_proxy_user, @_proxy_pass)
143
+ @_http.use_ssl = use_ssl
144
+ @_http.open_timeout = 10 # in seconds
145
+ @_http.read_timeout = 30 # in seconds
146
+ end
147
+ end
70
148
  end
71
149
  end
@@ -0,0 +1,17 @@
1
+ module ConfigCat
2
+ CONFIG_FILE_NAME = "config_v5"
3
+
4
+ PREFERENCES = "p"
5
+ BASE_URL = "u"
6
+ REDIRECT = "r"
7
+
8
+ FEATURE_FLAGS = "f"
9
+ VALUE = "v"
10
+ COMPARATOR = "t"
11
+ COMPARISON_ATTRIBUTE = "a"
12
+ COMPARISON_VALUE = "c"
13
+ ROLLOUT_PERCENTAGE_ITEMS = "p"
14
+ PERCENTAGE = "p"
15
+ ROLLOUT_RULES = "r"
16
+ VARIATION_ID = "i"
17
+ end
@@ -0,0 +1,10 @@
1
+ module ConfigCat
2
+ class DataGovernance
3
+ # Control the location of the config.json files containing your feature flags
4
+ # and settings within the ConfigCat CDN.
5
+ # Global: Select this if your feature flags are published to all global CDN nodes.
6
+ # EuOnly: Select this if your feature flags are published to CDN nodes only in the EU.
7
+ GLOBAL = 0
8
+ EU_ONLY = 1
9
+ end
10
+ end
@@ -23,13 +23,13 @@ module ConfigCat
23
23
  # Config cache interface
24
24
  #
25
25
 
26
- def get()
26
+ def get(key)
27
27
  #
28
28
  # :returns the config json object from the cache
29
29
  #
30
30
  end
31
31
 
32
- def set(value)
32
+ def set(key, value)
33
33
  #
34
34
  # Sets the config json cache.
35
35
  #
@@ -1,15 +1,18 @@
1
1
  require 'configcat/interfaces'
2
+ require 'configcat/constants'
2
3
  require 'concurrent'
3
4
 
5
+
4
6
  module ConfigCat
5
7
  class LazyLoadingCachePolicy < CachePolicy
6
8
 
7
- def initialize(config_fetcher, config_cache, cache_time_to_live_seconds=60)
9
+ def initialize(config_fetcher, config_cache, cache_key, cache_time_to_live_seconds=60)
8
10
  if cache_time_to_live_seconds < 1
9
11
  cache_time_to_live_seconds = 1
10
12
  end
11
13
  @_config_fetcher = config_fetcher
12
14
  @_config_cache = config_cache
15
+ @_cache_key = cache_key
13
16
  @_cache_time_to_live = cache_time_to_live_seconds
14
17
  @_lock = Concurrent::ReadWriteLock.new()
15
18
  @_last_updated = nil
@@ -20,7 +23,7 @@ module ConfigCat
20
23
  @_lock.acquire_read_lock()
21
24
  utc_now = Time.now.utc
22
25
  if !@_last_updated.equal?(nil) && (@_last_updated + @_cache_time_to_live > utc_now)
23
- config = @_config_cache.get()
26
+ config = @_config_cache.get(@_cache_key)
24
27
  if !config.equal?(nil)
25
28
  return config
26
29
  end
@@ -31,7 +34,7 @@ module ConfigCat
31
34
  force_refresh()
32
35
  begin
33
36
  @_lock.acquire_read_lock()
34
- config = @_config_cache.get()
37
+ config = @_config_cache.get(@_cache_key)
35
38
  return config
36
39
  ensure
37
40
  @_lock.release_read_lock()
@@ -45,7 +48,7 @@ module ConfigCat
45
48
  configuration = configuration_response.json()
46
49
  begin
47
50
  @_lock.acquire_write_lock()
48
- @_config_cache.set(configuration)
51
+ @_config_cache.set(@_cache_key, configuration)
49
52
  @_last_updated = Time.now.utc
50
53
  ensure
51
54
  @_lock.release_write_lock()
@@ -1,18 +1,20 @@
1
1
  require 'configcat/interfaces'
2
+ require 'configcat/constants'
2
3
  require 'concurrent'
3
4
 
4
5
  module ConfigCat
5
6
  class ManualPollingCachePolicy < CachePolicy
6
- def initialize(config_fetcher, config_cache)
7
+ def initialize(config_fetcher, config_cache, cache_key)
7
8
  @_config_fetcher = config_fetcher
8
9
  @_config_cache = config_cache
10
+ @_cache_key = cache_key
9
11
  @_lock = Concurrent::ReadWriteLock.new()
10
12
  end
11
13
 
12
14
  def get()
13
15
  begin
14
16
  @_lock.acquire_read_lock()
15
- config = @_config_cache.get()
17
+ config = @_config_cache.get(@_cache_key)
16
18
  return config
17
19
  ensure
18
20
  @_lock.release_read_lock()
@@ -26,7 +28,7 @@ module ConfigCat
26
28
  configuration = configuration_response.json()
27
29
  begin
28
30
  @_lock.acquire_write_lock()
29
- @_config_cache.set(configuration)
31
+ @_config_cache.set(@_cache_key, configuration)
30
32
  ensure
31
33
  @_lock.release_write_lock()
32
34
  end
@@ -1,4 +1,5 @@
1
1
  require 'configcat/user'
2
+ require 'configcat/constants'
2
3
  require 'digest'
3
4
  require 'semantic'
4
5
 
@@ -6,21 +7,18 @@ module ConfigCat
6
7
  class RolloutEvaluator
7
8
  COMPARATOR_TEXTS = ["IS ONE OF", "IS NOT ONE OF", "CONTAINS", "DOES NOT CONTAIN", "IS ONE OF (SemVer)", "IS NOT ONE OF (SemVer)", "< (SemVer)", "<= (SemVer)", "> (SemVer)", ">= (SemVer)", "= (Number)", "<> (Number)", "< (Number)", "<= (Number)", "> (Number)", ">= (Number)"]
8
9
 
9
- VALUE = "v"
10
- COMPARATOR = "t"
11
- COMPARISON_ATTRIBUTE = "a"
12
- COMPARISON_VALUE = "c"
13
- ROLLOUT_PERCENTAGE_ITEMS = "p"
14
- PERCENTAGE = "p"
15
- ROLLOUT_RULES = "r"
16
- VARIATION_ID = "i"
17
-
18
10
  def self.evaluate(key, user, default_value, default_variation_id, config)
19
11
  ConfigCat.logger.info("Evaluating get_value('%s')." % key)
20
12
 
21
- setting_descriptor = config.fetch(key, nil)
13
+ feature_flags = config.fetch(FEATURE_FLAGS, nil)
14
+ if feature_flags === nil
15
+ ConfigCat.logger.error("Evaluating get_value('%s') failed. Value not found for key '%s' Returning default_value: [%s]." % [key, key, default_value.to_s])
16
+ return default_value, default_variation_id
17
+ end
18
+
19
+ setting_descriptor = feature_flags.fetch(key, nil)
22
20
  if setting_descriptor === nil
23
- ConfigCat.logger.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, config.keys.join(", ")])
21
+ ConfigCat.logger.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, feature_flags.keys.join(", ")])
24
22
  return default_value, default_variation_id
25
23
  end
26
24
 
@@ -1,3 +1,3 @@
1
1
  module ConfigCat
2
- VERSION = "3.1.0"
2
+ VERSION = "4.0.0"
3
3
  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: 3.1.0
4
+ version: 4.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: 2020-09-14 00:00:00.000000000 Z
11
+ date: 2020-10-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -110,6 +110,8 @@ files:
110
110
  - lib/configcat/configcache.rb
111
111
  - lib/configcat/configcatclient.rb
112
112
  - lib/configcat/configfetcher.rb
113
+ - lib/configcat/constants.rb
114
+ - lib/configcat/datagovernance.rb
113
115
  - lib/configcat/interfaces.rb
114
116
  - lib/configcat/lazyloadingcachepolicy.rb
115
117
  - lib/configcat/manualpollingcachepolicy.rb