Use .wait to check when the database is ready

This commit is contained in:
vrde 2016-04-27 17:00:21 +02:00
parent 70b86ce49b
commit 0d6e74cfc7
No known key found for this signature in database
GPG Key ID: 6581C7C39B3D397D
3 changed files with 41 additions and 8 deletions

View File

@ -19,7 +19,9 @@ import bigchaindb.config_utils
from bigchaindb.util import ProcessGroup from bigchaindb.util import ProcessGroup
from bigchaindb.client import temp_client from bigchaindb.client import temp_client
from bigchaindb import db from bigchaindb import db
from bigchaindb.exceptions import DatabaseAlreadyExists, KeypairNotFoundException from bigchaindb.exceptions import (StartupError,
DatabaseAlreadyExists,
KeypairNotFoundException)
from bigchaindb.commands import utils from bigchaindb.commands import utils
from bigchaindb.processes import Processes from bigchaindb.processes import Processes
from bigchaindb import crypto from bigchaindb import crypto
@ -149,7 +151,10 @@ def run_start(args):
bigchaindb.config_utils.autoconfigure(filename=args.config, force=True) bigchaindb.config_utils.autoconfigure(filename=args.config, force=True)
if args.start_rethinkdb: 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) logger.info('RethinkDB started with PID %s' % proc.pid)
try: try:

View File

@ -2,31 +2,58 @@
for ``argparse.ArgumentParser``. for ``argparse.ArgumentParser``.
""" """
import time
import argparse import argparse
import multiprocessing as mp import multiprocessing as mp
import subprocess import subprocess
import rethinkdb as r
import bigchaindb
from bigchaindb.exceptions import StartupError
from bigchaindb import db
from bigchaindb.version import __version__ from bigchaindb.version import __version__
def start_rethinkdb(): 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'], proc = subprocess.Popen(['rethinkdb', '--bind', 'all'],
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
universal_newlines=True) universal_newlines=True)
dbname = bigchaindb.config['database']['name']
line = '' line = ''
for line in proc.stdout: for line in proc.stdout:
if line.startswith('Server ready'): if line.startswith('Server ready'):
# FIXME: seems like tables are not ready when the server is ready, # FIXME: seems like tables are not ready when the server is ready,
# that's why we need to sleep a bit before returning. # that's why we need to query RethinkDB to know the state
# Not the optimal solution. Happy to see the right one :) # of the database. This code assumes the tables are ready
time.sleep(1) # 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 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() proc.kill()

View File

@ -28,4 +28,5 @@ class DatabaseDoesNotExist(Exception):
class KeypairNotFoundException(Exception): class KeypairNotFoundException(Exception):
"""Raised if operation cannot proceed because the keypair was not given""" """Raised if operation cannot proceed because the keypair was not given"""
class StartupError(Exception):
"""Raised when there is an error starting up the system"""