@@ -4,15 +4,18 @@ defmodule ConfigCat.Client do
4
4
use GenServer
5
5
6
6
alias ConfigCat.CachePolicy
7
+ alias ConfigCat.Config
8
+ alias ConfigCat.Config.Setting
7
9
alias ConfigCat.EvaluationDetails
10
+ alias ConfigCat.EvaluationLogger
8
11
alias ConfigCat.FetchTime
9
12
alias ConfigCat.Hooks
10
13
alias ConfigCat.OverrideDataSource
11
14
alias ConfigCat.Rollout
12
15
alias ConfigCat.User
13
16
17
+ require ConfigCat.Config.SettingType , as: SettingType
14
18
require ConfigCat.ConfigCatLogger , as: ConfigCatLogger
15
- require ConfigCat.Constants , as: Constants
16
19
17
20
defmodule State do
18
21
@ moduledoc false
@@ -96,9 +99,12 @@ defmodule ConfigCat.Client do
96
99
97
100
@ impl GenServer
98
101
def handle_call ( { :get_key_and_value , variation_id } , _from , % State { } = state ) do
99
- case cached_settings ( state ) do
100
- { :ok , settings , _fetch_time_ms } ->
101
- result = Enum . find_value ( settings , nil , & entry_matching ( & 1 , variation_id ) )
102
+ case cached_config ( state ) do
103
+ { :ok , config , _fetch_time_ms } ->
104
+ result =
105
+ config
106
+ |> Config . settings ( )
107
+ |> Enum . find_value ( nil , & entry_matching ( & 1 , variation_id ) )
102
108
103
109
if is_nil ( result ) do
104
110
ConfigCatLogger . error (
@@ -183,9 +189,9 @@ defmodule ConfigCat.Client do
183
189
end
184
190
185
191
defp do_get_all_keys ( % State { } = state ) do
186
- case cached_settings ( state ) do
187
- { :ok , settings , _fetch_time_ms } ->
188
- Map . keys ( settings )
192
+ case cached_config ( state ) do
193
+ { :ok , config , _fetch_time_ms } ->
194
+ config |> Config . settings ( ) |> Map . keys ( )
189
195
190
196
_ ->
191
197
ConfigCatLogger . error ( "Config JSON is not present. Returning empty result." ,
@@ -197,29 +203,26 @@ defmodule ConfigCat.Client do
197
203
end
198
204
199
205
defp entry_matching ( { key , setting } , variation_id ) do
200
- value_matching ( key , setting , variation_id ) ||
201
- value_matching ( key , Map . get ( setting , Constants . rollout_rules ( ) ) , variation_id ) ||
202
- value_matching ( key , Map . get ( setting , Constants . percentage_rules ( ) ) , variation_id )
203
- end
204
-
205
- defp value_matching ( key , value , variation_id ) when is_list ( value ) do
206
- Enum . find_value ( value , nil , & value_matching ( key , & 1 , variation_id ) )
207
- end
208
-
209
- defp value_matching ( key , value , variation_id ) do
210
- if Map . get ( value , Constants . variation_id ( ) , nil ) == variation_id do
211
- { key , Map . get ( value , Constants . value ( ) ) }
206
+ case Setting . variation_value ( setting , variation_id ) do
207
+ nil -> nil
208
+ value -> { key , value }
212
209
end
213
210
end
214
211
215
212
defp evaluate ( key , user , default_value , default_variation_id , % State { } = state ) do
216
213
user = if user != nil , do: user , else: state . default_user
217
214
218
- details =
219
- case cached_settings ( state ) do
220
- { :ok , settings , fetch_time_ms } ->
215
+ % EvaluationDetails { } =
216
+ details =
217
+ with { :ok , config , fetch_time_ms } <- cached_config ( state ) ,
218
+ { :ok , _settings } <- Config . fetch_settings ( config ) ,
219
+ { :ok , logger } <- EvaluationLogger . start ( ) do
220
+ try do
221
221
% EvaluationDetails { } =
222
- details = Rollout . evaluate ( key , user , default_value , default_variation_id , settings )
222
+ details =
223
+ Rollout . evaluate ( key , user , default_value , default_variation_id , config , logger )
224
+
225
+ check_type_mismatch ( details . value , default_value )
223
226
224
227
fetch_time =
225
228
case FetchTime . to_datetime ( fetch_time_ms ) do
@@ -228,7 +231,14 @@ defmodule ConfigCat.Client do
228
231
end
229
232
230
233
% { details | fetch_time: fetch_time }
234
+ after
235
+ logger
236
+ |> EvaluationLogger . result ( )
237
+ |> ConfigCatLogger . debug ( event_id: 5000 )
231
238
239
+ EvaluationLogger . stop ( logger )
240
+ end
241
+ else
232
242
_ ->
233
243
message =
234
244
"Config JSON is not present when evaluating setting '#{ key } '. Returning the `default_value` parameter that you specified in your application: '#{ default_value } '."
@@ -249,23 +259,48 @@ defmodule ConfigCat.Client do
249
259
details
250
260
end
251
261
252
- defp cached_settings ( % State { } = state ) do
262
+ defp cached_config ( % State { } = state ) do
253
263
% { cache_policy: policy , flag_overrides: flag_overrides , instance_id: instance_id } = state
254
- local_settings = OverrideDataSource . overrides ( flag_overrides )
264
+ local_config = OverrideDataSource . overrides ( flag_overrides )
255
265
256
266
case OverrideDataSource . behaviour ( flag_overrides ) do
257
267
:local_only ->
258
- { :ok , local_settings , 0 }
268
+ { :ok , local_config , 0 }
259
269
260
270
:local_over_remote ->
261
- with { :ok , remote_settings , fetch_time_ms } <- policy . get ( instance_id ) do
262
- { :ok , Map . merge ( remote_settings , local_settings ) , fetch_time_ms }
271
+ with { :ok , remote_config , fetch_time_ms } <- policy . get ( instance_id ) do
272
+ { :ok , Config . merge ( remote_config , local_config ) , fetch_time_ms }
263
273
end
264
274
265
275
:remote_over_local ->
266
- with { :ok , remote_settings , fetch_time_ms } <- policy . get ( instance_id ) do
267
- { :ok , Map . merge ( local_settings , remote_settings ) , fetch_time_ms }
276
+ with { :ok , remote_config , fetch_time_ms } <- policy . get ( instance_id ) do
277
+ merged = Config . merge ( local_config , remote_config )
278
+ { :ok , merged , fetch_time_ms }
268
279
end
269
280
end
270
281
end
282
+
283
+ defp check_type_mismatch ( _value , nil ) , do: :ok
284
+
285
+ defp check_type_mismatch ( value , default_value ) do
286
+ value_type = SettingType . from_value ( value )
287
+ default_type = SettingType . from_value ( default_value )
288
+ number_types = [ SettingType . double ( ) , SettingType . int ( ) ]
289
+
290
+ cond do
291
+ value_type == default_type ->
292
+ :ok
293
+
294
+ value_type in number_types and default_type in number_types ->
295
+ :ok
296
+
297
+ true ->
298
+ ConfigCatLogger . warning (
299
+ "The type of a setting does not match the type of the specified default value (#{ default_value } ). " <>
300
+ "Setting's type was #{ value_type } but the default value's type was #{ default_type } . " <>
301
+ "Please make sure that using a default value not matching the setting's type was intended." ,
302
+ event_id: 4002
303
+ )
304
+ end
305
+ end
271
306
end
0 commit comments