diff --git a/rq/cli/cli.py b/rq/cli/cli.py index 8dd0b2b3..d0a5eff3 100755 --- a/rq/cli/cli.py +++ b/rq/cli/cli.py @@ -16,22 +16,27 @@ from rq import Connection, get_failed_queue, Queue from rq.contrib.legacy import cleanup_ghosts from rq.exceptions import InvalidJobOperationError from rq.utils import import_attribute -from rq.suspension import suspend as connection_suspend, resume as connection_resume, is_suspended +from rq.suspension import (suspend as connection_suspend, + resume as connection_resume, is_suspended) -from .helpers import (read_config_file, refresh, setup_loghandlers_from_args, - show_both, show_queues, show_workers) +from .helpers import (get_redis_from_config, read_config_file, refresh, + setup_loghandlers_from_args, show_both, show_queues, + show_workers) url_option = click.option('--url', '-u', envvar='RQ_REDIS_URL', help='URL describing Redis connection details.') -config_option = click.option('--config', '-c', help='Module containing RQ settings.') +config_option = click.option('--config', '-c', + help='Module containing RQ settings.') def connect(url, config=None): + if url: + return StrictRedis.from_url(url) + settings = read_config_file(config) if config else {} - url = url or settings.get('REDIS_URL') - return StrictRedis.from_url(url or 'redis://localhost:6379/0') + return get_redis_from_config(settings) @click.group() @@ -148,7 +153,6 @@ def worker(url, config, burst, name, worker_class, job_class, queue_class, path, settings = read_config_file(config) if config else {} # Worker specific default arguments - url = url or settings.get('REDIS_URL') queues = queues or settings.get('QUEUES', ['default']) sentry_dsn = sentry_dsn or settings.get('SENTRY_DSN') @@ -158,7 +162,7 @@ def worker(url, config, burst, name, worker_class, job_class, queue_class, path, setup_loghandlers_from_args(verbose, quiet) - conn = connect(url) + conn = connect(url, config) cleanup_ghosts(conn) worker_class = import_attribute(worker_class) queue_class = import_attribute(queue_class) diff --git a/rq/cli/helpers.py b/rq/cli/helpers.py index 0730d17b..d5c54a1a 100644 --- a/rq/cli/helpers.py +++ b/rq/cli/helpers.py @@ -7,6 +7,8 @@ import time from functools import partial import click +from redis import StrictRedis + from rq import Queue, Worker from rq.logutils import setup_loghandlers from rq.worker import WorkerStatus @@ -24,6 +26,19 @@ def read_config_file(module): if k.upper() == k]) +def get_redis_from_config(settings): + """Returns a StrictRedis instance from a dictionary of settings.""" + if settings.get('REDIS_URL') is not None: + return StrictRedis.from_url(settings['REDIS_URL']) + + return StrictRedis( + host=settings.get('REDIS_HOST', 'localhost'), + port=settings.get('REDIS_PORT', 6379), + db=settings.get('REDIS_DB', 0), + password=settings.get('REDIS_PASSWORD', None), + ) + + def pad(s, pad_to_length): """Pads the given string to the given length.""" return ('%-' + '%ds' % pad_to_length) % (s,) diff --git a/tests/test_helpers.py b/tests/test_helpers.py new file mode 100644 index 00000000..b43f13b7 --- /dev/null +++ b/tests/test_helpers.py @@ -0,0 +1,41 @@ +from rq.cli.helpers import get_redis_from_config + +from tests import RQTestCase + + +class TestHelpers(RQTestCase): + + def test_get_redis_from_config(self): + """Ensure Redis connection params are properly parsed""" + settings = { + 'REDIS_URL': 'redis://localhost:1/1' + } + + # Ensure REDIS_URL is read + redis = get_redis_from_config(settings) + connection_kwargs = redis.connection_pool.connection_kwargs + self.assertEqual(connection_kwargs['db'], 1) + self.assertEqual(connection_kwargs['port'], 1) + + settings = { + 'REDIS_URL': 'redis://localhost:1/1', + 'REDIS_HOST': 'foo', + 'REDIS_DB': 2, + 'REDIS_PORT': 2, + 'REDIS_PASSWORD': 'bar' + } + + # Ensure REDIS_URL is preferred + redis = get_redis_from_config(settings) + connection_kwargs = redis.connection_pool.connection_kwargs + self.assertEqual(connection_kwargs['db'], 1) + self.assertEqual(connection_kwargs['port'], 1) + + # Ensure fall back to regular connection parameters + settings['REDIS_URL'] = None + redis = get_redis_from_config(settings) + connection_kwargs = redis.connection_pool.connection_kwargs + self.assertEqual(connection_kwargs['host'], 'foo') + self.assertEqual(connection_kwargs['db'], 2) + self.assertEqual(connection_kwargs['port'], 2) + self.assertEqual(connection_kwargs['password'], 'bar')