From 184fc615bda9e2072a84a0fe8da599ff505dfd39 Mon Sep 17 00:00:00 2001 From: Neil Booth Date: Wed, 1 Feb 2017 19:25:45 +0900 Subject: [PATCH] Improve clarity about current daemon URL --- server/controller.py | 3 ++- server/daemon.py | 32 +++++++++++++++++++++++--------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/server/controller.py b/server/controller.py index a1f23a6..f814e6f 100644 --- a/server/controller.py +++ b/server/controller.py @@ -450,6 +450,7 @@ class Controller(util.LoggedClass): def getinfo(self): '''A one-line summary of server state.''' return { + 'daemon': self.daemon.logged_url(), 'daemon_height': self.daemon.cached_height(), 'db_height': self.bp.db_height, 'closing': len([s for s in self.sessions if s.is_closing()]), @@ -599,7 +600,7 @@ class Controller(util.LoggedClass): self.daemon.set_urls(self.env.coin.daemon_urls(daemon_url)) except Exception as e: raise RPCError('an error occured: {}'.format(e)) - return 'set daemon URL to {}'.format(daemon_url) + return 'now using daemon at {}'.format(self.daemon.logged_url()) def rpc_stop(self): '''Shut down the server cleanly.''' diff --git a/server/daemon.py b/server/daemon.py index 44a810c..e5d1fda 100644 --- a/server/daemon.py +++ b/server/daemon.py @@ -42,10 +42,27 @@ class Daemon(util.LoggedClass): '''Set the URLS to the given list, and switch to the first one.''' if not urls: raise DaemonError('no daemon URLs provided') - for url in urls: - self.logger.info('daemon at {}'.format(self.logged_url(url))) self.urls = urls self.url_index = 0 + for n, url in enumerate(urls): + self.logger.info('daemon #{:d} at {}{}' + .format(n + 1, self.logged_url(url), + '' if n else ' (current)')) + + def url(self): + '''Returns the current daemon URL.''' + return self.urls[self.url_index] + + def failover(self): + '''Call to fail-over to the next daemon URL. + + Returns False if there is only one, otherwise True. + ''' + if len(self.urls) > 1: + self.url_index = (self.url_index + 1) % len(self.urls) + self.logger.info('failing over to {}'.format(self.logged_url())) + return True + return False async def _send(self, payload, processor): '''Send a payload to be converted to JSON. @@ -72,8 +89,7 @@ class Daemon(util.LoggedClass): while True: try: async with self.workqueue_semaphore: - url = self.urls[self.url_index] - async with aiohttp.post(url, data=data) as resp: + async with aiohttp.post(self.url(), data=data) as resp: # If bitcoind can't find a tx, for some reason # it returns 500 but fills out the JSON. # Should still return 200 IMO. @@ -99,17 +115,15 @@ class Daemon(util.LoggedClass): except Exception: self.log_error(traceback.format_exc()) - if secs >= max_secs and len(self.urls) > 1: - self.url_index = (self.url_index + 1) % len(self.urls) - logged_url = self.logged_url(self.urls[self.url_index]) - self.logger.info('failing over to {}'.format(logged_url)) + if secs >= max_secs and self.failover(): secs = 1 else: await asyncio.sleep(secs) secs = min(max_secs, secs * 2) - def logged_url(self, url): + 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):