From 616bcf6bfd3b749fe70a91a8a726f9e1de82a2ce Mon Sep 17 00:00:00 2001 From: Neil Booth Date: Tue, 31 Jan 2017 08:13:25 +0900 Subject: [PATCH] Add daemon_url RPC call and document it. Closes #111 --- docs/RPC-INTERFACE.rst | 13 +++++++++++++ server/controller.py | 13 +++++++++++-- server/daemon.py | 16 ++++++++++------ 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/docs/RPC-INTERFACE.rst b/docs/RPC-INTERFACE.rst index 709c672..4816838 100644 --- a/docs/RPC-INTERFACE.rst +++ b/docs/RPC-INTERFACE.rst @@ -155,6 +155,19 @@ The following commands are available: Currently this is data gleaned from an IRC session. +* **daemon_url** + + This command takes an option argument that is interpreted + identically to the **DAEMON_URL** environment variable. If default + value of the argument is the **DAEMON_URL** environment variable. + + The command replaces the daemon's URL at run-time, and rotates to the + first in the list. + + For example, in case ElectrumX has rotated to a secondary daemon and + you want to revert to the first after fixing the issue, call this + command without an argument. + * **reorg** Force a block chain reorg. This command takes an optional diff --git a/server/controller.py b/server/controller.py index 0e5ce8f..a1f23a6 100644 --- a/server/controller.py +++ b/server/controller.py @@ -78,8 +78,8 @@ class Controller(util.LoggedClass): env.max_send = max(350000, env.max_send) self.setup_bands() # Set up the RPC request handlers - cmds = ('disconnect getinfo groups log peers reorg sessions stop' - .split()) + cmds = ('daemon_url disconnect getinfo groups log peers reorg ' + 'sessions stop'.split()) self.rpc_handlers = {cmd: getattr(self, 'rpc_' + cmd) for cmd in cmds} # Set up the ElectrumX request handlers rpcs = [ @@ -592,6 +592,15 @@ class Controller(util.LoggedClass): ''' return self.for_each_session(session_ids, self.toggle_logging) + def rpc_daemon_url(self, daemon_url=None): + '''Replace the daemon URL.''' + daemon_url = daemon_url or self.env.daemon_url + try: + 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) + def rpc_stop(self): '''Shut down the server cleanly.''' self.initiate_shutdown() diff --git a/server/daemon.py b/server/daemon.py index 8aacb9f..44a810c 100644 --- a/server/daemon.py +++ b/server/daemon.py @@ -30,12 +30,7 @@ class Daemon(util.LoggedClass): def __init__(self, urls): super().__init__() - 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 + self.set_urls(urls) self._height = None self._mempool_hashes = set() self.mempool_refresh_event = asyncio.Event() @@ -43,6 +38,15 @@ class Daemon(util.LoggedClass): # See DEFAULT_HTTP_WORKQUEUE in bitcoind, which is typically 16 self.workqueue_semaphore = asyncio.Semaphore(value=10) + def set_urls(self, urls): + '''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 + async def _send(self, payload, processor): '''Send a payload to be converted to JSON.