From 0d6e74cfc7041a55b08e0b5f7a73769af10ce632 Mon Sep 17 00:00:00 2001 From: vrde Date: Wed, 27 Apr 2016 17:00:21 +0200 Subject: [PATCH] Use .wait to check when the database is ready --- bigchaindb/commands/bigchain.py | 9 ++++++-- bigchaindb/commands/utils.py | 37 ++++++++++++++++++++++++++++----- bigchaindb/exceptions.py | 3 ++- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/bigchaindb/commands/bigchain.py b/bigchaindb/commands/bigchain.py index 8065834a..d23f99fc 100644 --- a/bigchaindb/commands/bigchain.py +++ b/bigchaindb/commands/bigchain.py @@ -19,7 +19,9 @@ import bigchaindb.config_utils from bigchaindb.util import ProcessGroup from bigchaindb.client import temp_client from bigchaindb import db -from bigchaindb.exceptions import DatabaseAlreadyExists, KeypairNotFoundException +from bigchaindb.exceptions import (StartupError, + DatabaseAlreadyExists, + KeypairNotFoundException) from bigchaindb.commands import utils from bigchaindb.processes import Processes from bigchaindb import crypto @@ -149,7 +151,10 @@ def run_start(args): bigchaindb.config_utils.autoconfigure(filename=args.config, force=True) if args.start_rethinkdb: - proc = utils.start_rethinkdb() + try: + proc = utils.start_rethinkdb() + except StartupError as e: + sys.exit('Error starting RethinkDB, reason is: {}'.format(e)) logger.info('RethinkDB started with PID %s' % proc.pid) try: diff --git a/bigchaindb/commands/utils.py b/bigchaindb/commands/utils.py index 99b6b4cb..b3cc356c 100644 --- a/bigchaindb/commands/utils.py +++ b/bigchaindb/commands/utils.py @@ -2,31 +2,58 @@ for ``argparse.ArgumentParser``. """ -import time import argparse import multiprocessing as mp import subprocess +import rethinkdb as r + +import bigchaindb +from bigchaindb.exceptions import StartupError +from bigchaindb import db from bigchaindb.version import __version__ def start_rethinkdb(): + """Start RethinkDB as a child process and wait for it to be + available. + + Raises: + ``bigchaindb.exceptions.StartupError`` if RethinkDB cannot + be started. + """ + proc = subprocess.Popen(['rethinkdb', '--bind', 'all'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) + dbname = bigchaindb.config['database']['name'] line = '' for line in proc.stdout: if line.startswith('Server ready'): # FIXME: seems like tables are not ready when the server is ready, - # that's why we need to sleep a bit before returning. - # Not the optimal solution. Happy to see the right one :) - time.sleep(1) + # that's why we need to query RethinkDB to know the state + # of the database. This code assumes the tables are ready + # when the database is ready. This seems a valid assumption. + + try: + conn = db.get_conn() + # Before checking if the db is ready, we need to query + # the server to check if it contains that db + if r.db_list().contains(dbname).run(conn): + r.db(dbname).wait().run(conn) + except (r.ReqlOpFailedError, r.ReqlDriverError) as exc: + raise StartupError('Error waiting for the database `{}` ' + 'to be ready'.format(dbname)) from exc + return proc - exit('Error starting RethinkDB, reason is: {}'.format(line)) + # We are here when we exhaust the stdout of the process. + # The last `line` contains info about the error. + raise StartupError(line) + proc.kill() diff --git a/bigchaindb/exceptions.py b/bigchaindb/exceptions.py index 0baa4ad2..8abfaaf7 100644 --- a/bigchaindb/exceptions.py +++ b/bigchaindb/exceptions.py @@ -28,4 +28,5 @@ class DatabaseDoesNotExist(Exception): class KeypairNotFoundException(Exception): """Raised if operation cannot proceed because the keypair was not given""" - +class StartupError(Exception): + """Raised when there is an error starting up the system"""