Clean up daemon URL handling and interface

This commit is contained in:
Neil Booth 2018-08-13 10:47:22 +09:00
parent 08347fe275
commit 61711fcfd7
3 changed files with 15 additions and 19 deletions

View File

@ -111,10 +111,6 @@ class Coin(object):
url = 'http://' + url url = 'http://' + url
return url + '/' return url + '/'
@classmethod
def daemon_urls(cls, urls):
return [cls.sanitize_url(url) for url in urls.split(',')]
@classmethod @classmethod
def genesis_block(cls, block): def genesis_block(cls, block):
'''Check the Genesis block is the right one for this coin. '''Check the Genesis block is the right one for this coin.

View File

@ -38,31 +38,36 @@ 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, urls, max_workqueue=10): def __init__(self, coin, url, max_workqueue=10):
self.coin = coin self.coin = coin
self.logger = class_logger(__name__, self.__class__.__name__) self.logger = class_logger(__name__, self.__class__.__name__)
self.set_urls(coin.daemon_urls(urls)) self.set_url(url)
self._height = None 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.available_rpcs = {} self.available_rpcs = {}
def set_urls(self, urls): def set_url(self, url):
'''Set the URLS to the given list, and switch to the first one.''' '''Set the URLS to the given list, and switch to the first one.'''
if not urls: urls = url.split(',')
raise DaemonError('no daemon URLs provided') urls = [self.coin.sanitize_url(url) for url in urls]
self.urls = urls
self.url_index = 0
for n, url in enumerate(urls): for n, url in enumerate(urls):
status = '' if n else ' (current)' status = '' if n else ' (current)'
logged_url = self.logged_url(url) logged_url = self.logged_url(url)
self.logger.info(f'daemon #{n + 1} at {logged_url}{status}') self.logger.info(f'daemon #{n + 1} at {logged_url}{status}')
self.url_index = 0
self.urls = urls
def url(self): def current_url(self):
'''Returns the current daemon URL.''' '''Returns the current daemon URL.'''
return self.urls[self.url_index] return self.urls[self.url_index]
def logged_url(self, url=None):
'''The host and port part, for logging.'''
url = url or self.current_url()
return url[url.rindex('@') + 1:]
def failover(self): def failover(self):
'''Call to fail-over to the next daemon URL. '''Call to fail-over to the next daemon URL.
@ -81,7 +86,7 @@ class Daemon(object):
async def _send_data(self, data): async def _send_data(self, data):
async with self.workqueue_semaphore: async with self.workqueue_semaphore:
async with self.client_session() as session: async with self.client_session() as session:
async with session.post(self.url(), data=data) as resp: async with session.post(self.current_url(), data=data) as resp:
# If bitcoind can't find a tx, for some reason # If bitcoind can't find a tx, for some reason
# it returns 500 but fills out the JSON. # it returns 500 but fills out the JSON.
# Should still return 200 IMO. # Should still return 200 IMO.
@ -139,11 +144,6 @@ class Daemon(object):
await asyncio.sleep(secs) await asyncio.sleep(secs)
secs = min(max_secs, secs * 2, 1) secs = min(max_secs, secs * 2, 1)
def logged_url(self, url=None):
'''The host and port part, for logging.'''
url = url or self.url()
return url[url.rindex('@') + 1:]
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.'''
def processor(result): def processor(result):

View File

@ -383,7 +383,7 @@ class SessionManager(object):
'''Replace the daemon URL.''' '''Replace the daemon URL.'''
daemon_url = daemon_url or self.env.daemon_url daemon_url = daemon_url or self.env.daemon_url
try: try:
self.daemon.set_urls(self.env.coin.daemon_urls(daemon_url)) self.daemon.set_url(daemon_url)
except Exception as e: except Exception as e:
raise RPCError(BAD_REQUEST, f'an error occured: {e!r}') raise RPCError(BAD_REQUEST, f'an error occured: {e!r}')
return f'now using daemon at {self.daemon.logged_url()}' return f'now using daemon at {self.daemon.logged_url()}'