From d5bde117c2f5477b5d0ba9846f2a7c4480ca1854 Mon Sep 17 00:00:00 2001 From: lowercase00 <21188280+lowercase00@users.noreply.github.com> Date: Tue, 7 Mar 2023 00:54:47 -0300 Subject: [PATCH] Remove `use_connection` (#1859) * feat: remove use_connection * fix: clear old test --- docs/docs/connections.md | 67 ++++++++++------------------------------ rq/__init__.py | 2 +- rq/connections.py | 20 ++---------- tests/test_connection.py | 33 ++------------------ 4 files changed, 22 insertions(+), 100 deletions(-) diff --git a/docs/docs/connections.md b/docs/docs/connections.md index f58da10f..4382cefc 100644 --- a/docs/docs/connections.md +++ b/docs/docs/connections.md @@ -3,61 +3,20 @@ title: "RQ: Connections" layout: docs --- -Although RQ features the `use_connection()` command for convenience, it -is deprecated, since it pollutes the global namespace. Instead, prefer explicit -connection management using the `with Connection(...):` context manager, or -pass in Redis connection references to queues directly. +### The connection parameter - -## Single Redis connection (easy) - -
- - Note: -

- The use of use_connection is deprecated. - Please don't use use_connection in your scripts. - Instead, use explicit connection management. -

-
- -In development mode, to connect to a default, local Redis server: - -```python -from rq import use_connection -use_connection() -``` - -In production, to connect to a specific Redis server: +Each RQ object (queues, workers, jobs) has a `connection` keyword +argument that can be passed to the constructor - this is the recommended way of handling connections. ```python from redis import Redis -from rq import use_connection +from rq import Queue -redis = Redis('my.host.org', 6789, password='secret') -use_connection(redis) +redis = Redis('localhost', 6789) +q = Queue(connection=redis) ``` -Be aware of the fact that `use_connection` pollutes the global namespace. It -also implies that you can only ever use a single connection. - - -## Multiple Redis connections - -However, the single connection pattern facilitates only those cases where you -connect to a single Redis instance, and where you affect global context (by -replacing the existing connection with the `use_connection()` call). You can -only use this pattern when you are in full control of your web stack. - -In any other situation, or when you want to use multiple connections, you -should use `Connection` contexts or pass connections around explicitly. - - -### Explicit connections (precise, but tedious) - -Each RQ object instance (queues, workers, jobs) has a `connection` keyword -argument that can be passed to the constructor. Using this, you don't need to -use `use_connection()`. Instead, you can create your queues like this: +This pattern allows for different connections to be passed to different objects: ```python from rq import Queue @@ -73,11 +32,19 @@ q2 = Queue('bar', connection=conn2) Every job that is enqueued on a queue will know what connection it belongs to. The same goes for the workers. -This approach is very precise, but rather verbose, and therefore, tedious. - ### Connection contexts (precise and concise) +
+ + Note: +

+ The use of Connection context manager is deprecated. + Please don't use Connection in your scripts. + Instead, use explicit connection management. +

+
+ There is a better approach if you want to use multiple connections, though. Each RQ object instance, upon creation, will use the topmost Redis connection on the RQ connection stack, which is a mechanism to temporarily replace the diff --git a/rq/__init__.py b/rq/__init__.py index d5db6813..ec635d75 100644 --- a/rq/__init__.py +++ b/rq/__init__.py @@ -1,6 +1,6 @@ # flake8: noqa -from .connections import Connection, get_current_connection, pop_connection, push_connection, use_connection +from .connections import Connection, get_current_connection, pop_connection, push_connection from .job import cancel_job, get_current_job, requeue_job, Retry from .queue import Queue from .version import VERSION diff --git a/rq/connections.py b/rq/connections.py index 413ee5a0..2c6d227c 100644 --- a/rq/connections.py +++ b/rq/connections.py @@ -3,7 +3,7 @@ from typing import Optional import warnings from redis import Redis -from .local import LocalStack, release_local +from .local import LocalStack class NoRedisConnectionException(Exception): @@ -65,22 +65,6 @@ def pop_connection() -> 'Redis': return _connection_stack.pop() -def use_connection(redis: Optional['Redis'] = None): - """ - Clears the stack and uses the given connection. Protects against mixed - use of use_connection() and stacked connection contexts. - - Args: - redis (Optional[Redis], optional): A Redis Connection. Defaults to None. - """ - assert len(_connection_stack) <= 1, 'You should not mix Connection contexts with use_connection()' - release_local(_connection_stack) - - if redis is None: - redis = Redis() - push_connection(redis) - - def get_current_connection() -> 'Redis': """ Returns the current Redis connection (i.e. the topmost on the @@ -118,4 +102,4 @@ def resolve_connection(connection: Optional['Redis'] = None) -> 'Redis': _connection_stack = LocalStack() -__all__ = ['Connection', 'get_current_connection', 'push_connection', 'pop_connection', 'use_connection'] +__all__ = ['Connection', 'get_current_connection', 'push_connection', 'pop_connection'] diff --git a/tests/test_connection.py b/tests/test_connection.py index fdfafbd0..393c20d7 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -1,9 +1,7 @@ from redis import Redis -from rq import Connection, Queue, use_connection, get_current_connection, pop_connection -from rq.connections import NoRedisConnectionException - -from tests import find_empty_redis_database, RQTestCase +from rq import Connection, Queue +from tests import RQTestCase, find_empty_redis_database from tests.fixtures import do_nothing @@ -37,30 +35,3 @@ class TestConnectionInheritance(RQTestCase): job2 = q2.enqueue(do_nothing) self.assertEqual(q1.connection, job1.connection) self.assertEqual(q2.connection, job2.connection) - - -class TestConnectionHelpers(RQTestCase): - def test_use_connection(self): - """Test function use_connection works as expected.""" - conn = new_connection() - use_connection(conn) - - self.assertEqual(conn, get_current_connection()) - - use_connection() - - self.assertNotEqual(conn, get_current_connection()) - - use_connection(self.testconn) # Restore RQTestCase connection - - with self.assertRaises(AssertionError): - with Connection(new_connection()): - use_connection() - with Connection(new_connection()): - use_connection() - - def test_resolve_connection_raises_on_no_connection(self): - """Test function resolve_connection raises if there is no connection.""" - pop_connection() - with self.assertRaises(NoRedisConnectionException): - Queue()