Add retrier decorator
This commit is contained in:
parent
45764df6b0
commit
aa3c1a953a
@ -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(
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user