Skip to content

Commit 0d7a510

Browse files
authored
Merge pull request #127 from splitio/development
Development
2 parents ea16457 + f85ea8c commit 0d7a510

21 files changed

+90
-97
lines changed

CHANGES.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
7.0.1 (Mar 8, 2019)
2+
- Updated Splits refreshing rate.
3+
- Replaced exception log level to error level.
4+
- Improved validation for apikey.
15
7.0.0 (Feb 21, 2019)
26
- BREAKING CHANGE: Stored Impressions in Queue.
37
- Fixed bug related to Machine Name and Machine IP.

doc/source/introduction.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ All the possible configuration options are:
7979
+------------------------+------+--------------------------------------------------------+---------+
8080
| readTimeout | int | The read timeout for HTTP connections in milliseconds. | 1500 |
8181
+------------------------+------+--------------------------------------------------------+---------+
82-
| featuresRefreshRate | int | The features (splits) update refresh period in | 30 |
82+
| featuresRefreshRate | int | The features (splits) update refresh period in | 5 |
8383
| | | seconds. | |
8484
+------------------------+------+--------------------------------------------------------+---------+
8585
| segmentsRefreshRate | int | The segments update refresh period in seconds. | 60 |

splitio/api.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import requests
66
import json
77

8-
from splitio.exceptions import ForbiddenException
98
from splitio.config import SDK_API_BASE_URL, EVENTS_API_BASE_URL, SDK_VERSION
109

1110
_SEGMENT_CHANGES_URL_TEMPLATE = '{base_url}/segmentChanges/{segment_name}/'
@@ -93,9 +92,6 @@ def _build_headers(self):
9392
return headers
9493

9594
def _logHttpError(self, response):
96-
if response.status_code == requests.codes.forbidden:
97-
raise ForbiddenException()
98-
9995
if response.status_code < requests.codes.ok or response.status_code >= requests.codes.bad:
10096
respJson = response.json()
10197
if 'message' in respJson:

splitio/brokers.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,6 @@ def _init_config(self, config=None):
264264
self._segment_fetcher_interval = segment_fetcher_interval
265265
self._split_fetcher_interval = split_fetcher_interval
266266
self._impressions_interval = impressions_interval
267-
268267
self._metrics_max_time_between_calls = min(
269268
MAX_INTERVAL,
270269
self._config['metricsRefreshRate']
@@ -661,7 +660,7 @@ def get_self_refreshing_broker(api_key, **kwargs):
661660
"eventsApiBaseUrl": "https://events.split.io/api",
662661
"connectionTimeout": 1500,
663662
"readTimeout": 1500,
664-
"featuresRefreshRate": 30,
663+
"featuresRefreshRate": 5,
665664
"segmentsRefreshRate": 60,
666665
"metricsRefreshRate": 60,
667666
"impressionsRefreshRate": 60,
@@ -676,7 +675,7 @@ def get_self_refreshing_broker(api_key, **kwargs):
676675
677676
* connectionTimeout: The TCP connection timeout (Default: 1500ms)
678677
* readTimeout: The HTTP read timeout (Default: 1500ms)
679-
* featuresRefreshRate: The refresh rate for features (Default: 30s)
678+
* featuresRefreshRate: The refresh rate for features (Default: 5s)
680679
* segmentsRefreshRate: The refresh rate for segments (Default: 60s)
681680
* metricsRefreshRate: The refresh rate for metrics (Default: 60s)
682681
* impressionsRefreshRate: The refresh rate for impressions (Default: 60s)
@@ -808,7 +807,7 @@ def get_uwsgi_broker(api_key, **kwargs):
808807
"apiKey": "some-api-key",
809808
"sdkApiBaseUrl": "https://sdk.split.io/api",
810809
"eventsApiBaseUrl": "https://events.split.io/api",
811-
"featuresRefreshRate": 30,
810+
"featuresRefreshRate": 5,
812811
"segmentsRefreshRate": 60,
813812
"metricsRefreshRate": 60,
814813
"impressionsRefreshRate": 60

splitio/clients.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def _send_impression_to_listener(self, impression, attributes):
6262
try:
6363
self._impression_listener.log_impression(impression, attributes)
6464
except ImpressionListenerException as e:
65-
self._logger.exception(e)
65+
self._logger.error(e)
6666

6767
def get_treatment(self, key, feature, attributes=None):
6868
"""
@@ -115,7 +115,7 @@ def get_treatment(self, key, feature, attributes=None):
115115

116116
return result['treatment']
117117
except Exception:
118-
self._logger.exception('Exception caught getting treatment for feature')
118+
self._logger.error('Error getting treatment for feature')
119119

120120
try:
121121
impression = self._build_impression(
@@ -129,9 +129,7 @@ def get_treatment(self, key, feature, attributes=None):
129129

130130
self._send_impression_to_listener(impression, attributes)
131131
except Exception: # pylint: disable=broad-except
132-
self._logger.exception(
133-
'Exception reporting impression into get_treatment exception block'
134-
)
132+
self._logger.error('Error reporting impression into get_treatment exception block')
135133
return CONTROL
136134

137135
def get_treatments(self, key, features, attributes=None):
@@ -189,8 +187,8 @@ def get_treatments(self, key, features, attributes=None):
189187
treatments[feature] = treatment['treatment']
190188

191189
except Exception:
192-
self._logger.exception('get_treatments: An exception occured when evaluating '
193-
'feature ' + feature + ' returning CONTROL.')
190+
self._logger.error('get_treatments: An exception occured when evaluating '
191+
'feature ' + feature + ' returning CONTROL.')
194192
treatments[feature] = CONTROL
195193
continue
196194

@@ -202,8 +200,8 @@ def get_treatments(self, key, features, attributes=None):
202200
for impression in bulk_impressions:
203201
self._send_impression_to_listener(impression, attributes)
204202
except Exception:
205-
self._logger.exception('get_treatments: An exception when trying to store '
206-
'impressions.')
203+
self._logger.error('get_treatments: An exception when trying to store '
204+
'impressions.')
207205

208206
return treatments
209207

@@ -244,7 +242,7 @@ def _record_stats(self, impressions, start, operation):
244242
self._broker.log_impressions(impressions)
245243
self._broker.log_operation_time(operation, end - start)
246244
except Exception:
247-
self._logger.exception('Exception caught recording impressions and metrics')
245+
self._logger.error('Error recording impressions and metrics')
248246

249247
def track(self, key, traffic_type, event_type, value=None):
250248
"""

splitio/config.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
'splitSdkMachineName': None,
2323
'splitSdkMachineIp': None,
2424
'readTimeout': 1500,
25-
'featuresRefreshRate': 30,
25+
'featuresRefreshRate': 5,
2626
'segmentsRefreshRate': 60,
2727
'metricsRefreshRate': 60,
2828
'impressionsRefreshRate': 60,
@@ -85,7 +85,7 @@ def parse_config_file(filename):
8585
"eventsApiBaseUrl": "https://events-loadtesting.split.io/api",
8686
"connectionTimeout": 1500,
8787
"readTimeout": 1500,
88-
"featuresRefreshRate": 30,
88+
"featuresRefreshRate": 5,
8989
"segmentsRefreshRate": 60,
9090
"metricsRefreshRate": 60,
9191
"impressionsRefreshRate": 60,
@@ -115,7 +115,7 @@ def parse_config_file(filename):
115115
if 'splitSdkMachineIp' in config:
116116
set_machine_ip(config['splitSdkMachineIp'])
117117
except Exception:
118-
logger.exception('There was a problem reading the config file: %s', filename)
118+
logger.error('There was a problem reading the config file: %s', filename)
119119
return DEFAULT_CONFIG.copy()
120120

121121
return config

splitio/exceptions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ class TimeoutException(Exception):
66
pass
77

88

9-
class ForbiddenException(Exception):
9+
class NetworkingException(Exception):
1010
pass

splitio/impressions.py

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -352,9 +352,7 @@ def _update_evictions(self, feature_name, feature_impressions):
352352
if len(test_impressions_data) > 0:
353353
self._api.test_impressions(test_impressions_data)
354354
except Exception:
355-
self._logger.exception(
356-
'Exception caught updating evicted impressions'
357-
)
355+
self._logger.error('Error updating evicted impressions')
358356
self._stopped = True
359357

360358
def _update_impressions(self):
@@ -370,7 +368,7 @@ def _update_impressions(self):
370368
if len(test_impressions_data) > 0:
371369
self._api.test_impressions(test_impressions_data)
372370
except Exception:
373-
self._logger.exception('Exception caught updating impressions')
371+
self._logger.error('Error updating impressions')
374372
self._stopped = True
375373

376374
def _notify_eviction(self, feature_name, feature_impressions):
@@ -392,9 +390,7 @@ def _notify_eviction(self, feature_name, feature_impressions):
392390
self._update_evictions, feature_name, feature_impressions
393391
)
394392
except Exception:
395-
self._logger.exception(
396-
'Exception caught starting evicted impressions update thread'
397-
)
393+
self._logger.error('Error starting evicted impressions update thread')
398394

399395
def _timer_refresh(self):
400396
"""
@@ -407,9 +403,7 @@ def _timer_refresh(self):
407403
try:
408404
self._thread_pool_executor.submit(self._update_impressions)
409405
except Exception:
410-
self._logger.exception(
411-
'Exception caught starting impressions update thread'
412-
)
406+
self._logger.error('Error starting impressions update thread')
413407

414408
try:
415409
if hasattr(self._interval, '__call__'):
@@ -421,7 +415,7 @@ def _timer_refresh(self):
421415
timer.daemon = True
422416
timer.start()
423417
except Exception:
424-
self._logger.exception('Exception caught refreshing timer')
418+
self._logger.error('Error refreshing timer')
425419
self._stopped = True
426420

427421

@@ -466,9 +460,7 @@ def log(self, impression):
466460
try:
467461
self._thread_pool_executor.submit(self._delegate.log, impression)
468462
except Exception:
469-
self._logger.exception(
470-
'Exception caught logging impression asynchronously'
471-
)
463+
self._logger.error('Error logging impression asynchronously')
472464

473465
def log_impressions(self, impressions):
474466
"""Log a bulk of impressions.
@@ -506,7 +498,7 @@ def log_impression(self, impression, attributes=None):
506498
try:
507499
self.impression_listener.log_impression(data)
508500
except Exception:
509-
raise ImpressionListenerException('Exception caught in log_impression user\'s'
501+
raise ImpressionListenerException('Error in log_impression user\'s'
510502
'method is throwing exceptions')
511503

512504

splitio/input_validator.py

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
import six
77
import re
88
import math
9+
import requests
910
from splitio.key import Key
1011
from splitio.treatments import CONTROL
1112
from splitio.api import SdkApi
12-
from splitio.exceptions import ForbiddenException
13+
from splitio.exceptions import NetworkingException
1314

1415

1516
_LOGGER = logging.getLogger(__name__)
@@ -397,11 +398,20 @@ def _valid_apikey_type(api_key, sdk_api_base_url):
397398
api_key,
398399
sdk_api_base_url=sdk_api_base_url,
399400
)
401+
_SEGMENT_CHANGES_URL_TEMPLATE = '{base_url}/segmentChanges/{segment_name}/'
402+
url = _SEGMENT_CHANGES_URL_TEMPLATE.format(base_url=sdk_api_base_url,
403+
segment_name='___TEST___')
404+
params = {
405+
'since': -1
406+
}
407+
headers = sdk_api._build_headers()
400408
try:
401-
sdk_api.segment_changes('___TEST___', -1)
402-
except ForbiddenException:
403-
return False
404-
return True
409+
response = requests.get(url, params=params, headers=headers, timeout=sdk_api._timeout)
410+
if response.status_code == requests.codes.forbidden:
411+
return False
412+
return True
413+
except requests.exceptions.RequestException:
414+
raise NetworkingException()
405415

406416

407417
def validate_factory_instantiation(apikey, config, sdk_api_base_url):
@@ -426,9 +436,12 @@ def validate_factory_instantiation(apikey, config, sdk_api_base_url):
426436
_LOGGER.error('no ready parameter has been set - incorrect control treatments '
427437
+ 'could be logged')
428438
return False
429-
if not _valid_apikey_type(apikey, sdk_api_base_url):
430-
_LOGGER.error('factory instantiation: you passed a browser type '
431-
+ 'api_key, please grab an api key from the Split '
432-
+ 'console that is of type sdk')
433-
return False
434-
return True
439+
try:
440+
if not _valid_apikey_type(apikey, sdk_api_base_url):
441+
_LOGGER.error('factory instantiation: you passed a browser type '
442+
+ 'api_key, please grab an api key from the Split '
443+
+ 'console that is of type sdk')
444+
return False
445+
return True
446+
except NetworkingException:
447+
_LOGGER.error("Error occured when tried to connect with Split servers")

splitio/metrics.py

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -363,50 +363,48 @@ def _update_count_fn(self):
363363
try:
364364
self._api.metrics_counters(build_metrics_counter_data(count_metrics))
365365
except:
366-
self._logger.exception('Exception caught sending count metrics to the back-end. '
367-
'Ignoring metrics.')
366+
self._logger.error('Error sending count metrics to the back-end. Ignoring metrics.')
368367
self._ignore_metrics = True
369368

370369
def update_count(self):
371370
"""Signals that an update on count metrics should be sent to the Split.io back-end"""
372371
try:
373372
self._thread_pool_executor.submit(self._update_count_fn)
374373
except:
375-
self._logger.exception('Exception caught submitting count metrics update task.')
374+
self._logger.error('Error submitting count metrics update task.')
376375

377376
def _update_time_fn(self):
378377
time_metrics = self._fetch_time_metrics_and_clear()
379378

380379
try:
381380
self._api.metrics_times(build_metrics_times_data(time_metrics))
382381
except:
383-
self._logger.exception('Exception caught sending time metrics to the back-end. '
384-
'Ignoring metrics.')
382+
self._logger.error('Error sending time metrics to the back-end. Ignoring metrics.')
385383
self._ignore_metrics = True
386384

387385
def update_time(self):
388386
"""Signals that an update on time metrics should be sent to the Split.io back-end"""
389387
try:
390388
self._thread_pool_executor.submit(self._update_time_fn)
391389
except:
392-
self._logger.exception('Exception caught submitting time metrics update task.')
390+
self._logger.error('Error submitting time metrics update task.')
393391

394392
def _update_gauge_fn(self):
395393
gauge_metrics = self._fetch_gauge_metrics_and_clear()
396394

397395
try:
398396
self._api.metrics_gauge(build_metrics_gauge_data(gauge_metrics))
399397
except:
400-
self._logger.exception('Exception caught sending gauge metrics to the back-end. '
401-
'Ignoring metrics.')
398+
self._logger.error('Error sending gauge metrics to the back-end. '
399+
'Ignoring metrics.')
402400
self._ignore_metrics = True
403401

404402
def update_gauge(self):
405403
"""Signals that an update on time metrics should be sent to the Split.io back-end"""
406404
try:
407405
self._thread_pool_executor.submit(self._update_gauge_fn)
408406
except:
409-
self._logger.exception('Exception caught submitting gauge metrics update task.')
407+
self._logger.error('Error submitting gauge metrics update task.')
410408

411409

412410
class LoggerMetrics(InMemoryMetrics):
@@ -469,7 +467,7 @@ def count(self, counter, delta):
469467
try:
470468
self._thread_pool_executor.submit(self._delegate.count, counter, delta)
471469
except:
472-
self._logger.exception('Exception caught submitting count metric')
470+
self._logger.error('Error submitting count metric')
473471

474472
def time(self, operation, time_in_ms):
475473
"""Records an execution time in milliseconds for the specified named operation. This method
@@ -485,7 +483,7 @@ def time(self, operation, time_in_ms):
485483
try:
486484
self._thread_pool_executor.submit(self._delegate.time, operation, time_in_ms)
487485
except:
488-
self._logger.exception('Exception caught submitting time metric')
486+
self._logger.error('Error submitting time metric')
489487

490488
def gauge(self, gauge, value):
491489
"""Records the latest fixed value for the specified named gauge. This method is
@@ -501,7 +499,7 @@ def gauge(self, gauge, value):
501499
try:
502500
self._thread_pool_executor.submit(self._delegate.gauge, gauge, value)
503501
except:
504-
self._logger.exception('Exception caught submitting gauge metric')
502+
self._logger.error('Error submitting gauge metric')
505503

506504

507505
class CacheBasedMetrics(Metrics):

0 commit comments

Comments
 (0)