Add retrier decorator

This commit is contained in:
enenn 2018-03-24 08:46:20 +01:00
parent 45764df6b0
commit aa3c1a953a
2 changed files with 22 additions and 3 deletions

View File

@ -16,6 +16,7 @@ logger = logging.getLogger(__name__)
# Current selected exchange # Current selected exchange
_API: ccxt.Exchange = None _API: ccxt.Exchange = None
_CONF: dict = {} _CONF: dict = {}
API_RETRY_COUNT = 4
# Holds all open sell orders for dry_run # Holds all open sell orders for dry_run
_DRY_RUN_OPEN_ORDERS: Dict[str, Any] = {} _DRY_RUN_OPEN_ORDERS: Dict[str, Any] = {}
@ -23,6 +24,23 @@ _DRY_RUN_OPEN_ORDERS: Dict[str, Any] = {}
_TICKER_CACHE: dict = {} _TICKER_CACHE: dict = {}
def retrier(f):
def wrapper(*args, **kwargs):
count = kwargs.pop('count', API_RETRY_COUNT)
try:
return f(*args, **kwargs)
except (NetworkException, DependencyException) as ex:
logger.warning('%s returned exception: "%s"', f, ex)
if count > 0:
count -= 1
kwargs.update({'count': count})
logger.warning('retrying %s still for %s times', f, count)
return wrapper(*args, **kwargs)
else:
raise OperationalException('Giving up retrying: %s', f)
return wrapper
def init(config: dict) -> None: def init(config: dict) -> None:
""" """
Initializes this module with the given config, Initializes this module with the given config,
@ -192,6 +210,7 @@ def get_balances() -> dict:
raise OperationalException(e) raise OperationalException(e)
@retrier
def get_ticker(pair: str, refresh: Optional[bool] = True) -> dict: def get_ticker(pair: str, refresh: Optional[bool] = True) -> dict:
global _TICKER_CACHE global _TICKER_CACHE
try: try:
@ -208,7 +227,7 @@ def get_ticker(pair: str, refresh: Optional[bool] = True) -> dict:
raise OperationalException(e) raise OperationalException(e)
@cached(TTLCache(maxsize=100, ttl=30)) @retrier
def get_ticker_history(pair: str, tick_interval: str) -> List[Dict]: def get_ticker_history(pair: str, tick_interval: str) -> List[Dict]:
if 'fetchOHLCV' not in _API.has or not _API.has['fetchOHLCV']: if 'fetchOHLCV' not in _API.has or not _API.has['fetchOHLCV']:
raise OperationalException( raise OperationalException(

View File

@ -307,7 +307,7 @@ def test_get_ticker(default_conf, mocker):
assert ticker['bid'] == 0.5 assert ticker['bid'] == 0.5
assert ticker['ask'] == 1 assert ticker['ask'] == 1
with pytest.raises(NetworkException): with pytest.raises(OperationalException): # test retrier
api_mock.fetch_ticker = MagicMock(side_effect=ccxt.NetworkError) api_mock.fetch_ticker = MagicMock(side_effect=ccxt.NetworkError)
mocker.patch('freqtrade.exchange._API', api_mock) mocker.patch('freqtrade.exchange._API', api_mock)
get_ticker(pair='ETH/BTC', refresh=True) get_ticker(pair='ETH/BTC', refresh=True)
@ -365,7 +365,7 @@ def test_get_ticker_history(default_conf, mocker):
assert ticks[0]['C'] == 4 assert ticks[0]['C'] == 4
assert ticks[0]['V'] == 5 assert ticks[0]['V'] == 5
with pytest.raises(NetworkException): with pytest.raises(OperationalException): # test retrier
api_mock.fetch_ohlcv = MagicMock(side_effect=ccxt.NetworkError) api_mock.fetch_ohlcv = MagicMock(side_effect=ccxt.NetworkError)
mocker.patch('freqtrade.exchange._API', api_mock) mocker.patch('freqtrade.exchange._API', api_mock)
# new symbol to get around cache # new symbol to get around cache