Browse Source

Improve retry logic

patch-2
Neil Booth 7 years ago
parent
commit
ab0e9eb123
  1. 20
      electrumx/server/daemon.py

20
electrumx/server/daemon.py

@ -42,14 +42,17 @@ class Daemon(object):
class DaemonWarmingUpError(Exception): class DaemonWarmingUpError(Exception):
'''Raised when the daemon returns an error in its results.''' '''Raised when the daemon returns an error in its results.'''
def __init__(self, coin, url, max_workqueue=10): def __init__(self, coin, url, max_workqueue=10, init_retry=0.25,
max_retry=4.0):
self.coin = coin self.coin = coin
self.logger = class_logger(__name__, self.__class__.__name__) self.logger = class_logger(__name__, self.__class__.__name__)
self.set_url(url) self.set_url(url)
self._height = None
# Limit concurrent RPC calls to this number. # Limit concurrent RPC calls to this number.
# See DEFAULT_HTTP_WORKQUEUE in bitcoind, which is typically 16 # See DEFAULT_HTTP_WORKQUEUE in bitcoind, which is typically 16
self.workqueue_semaphore = asyncio.Semaphore(value=max_workqueue) self.workqueue_semaphore = asyncio.Semaphore(value=max_workqueue)
self.init_retry = init_retry
self.max_retry = max_retry
self._height = None
self.available_rpcs = {} self.available_rpcs = {}
def set_url(self, url): def set_url(self, url):
@ -109,19 +112,18 @@ class Daemon(object):
are raise through DaemonError. are raise through DaemonError.
''' '''
def log_error(error): def log_error(error):
nonlocal last_error_log, secs nonlocal last_error_log, retry
now = time.time() now = time.time()
if now - last_error_log > 60: if now - last_error_log > 60:
last_error_time = now last_error_time = now
self.logger.error(f'{error} Retrying occasionally...') self.logger.error(f'{error} Retrying occasionally...')
if secs == max_secs and self.failover(): if retry == self.max_retry and self.failover():
secs = 0.25 retry = 0
on_good_message = None on_good_message = None
last_error_log = 0 last_error_log = 0
data = json.dumps(payload) data = json.dumps(payload)
secs = 0.25 retry = self.init_retry
max_secs = 4
while True: while True:
try: try:
result = await self._send_data(data) result = await self._send_data(data)
@ -146,8 +148,8 @@ class Daemon(object):
log_error('work queue full.') log_error('work queue full.')
on_good_message = 'running normally' on_good_message = 'running normally'
await asyncio.sleep(secs) await asyncio.sleep(retry)
secs = min(max_secs, secs * 2) retry = max(min(self.max_retry, retry * 2), self.init_retry)
async def _send_single(self, method, params=None): async def _send_single(self, method, params=None):
'''Send a single request to the daemon.''' '''Send a single request to the daemon.'''

Loading…
Cancel
Save