Remove `use_connection` (#1859)

* feat: remove use_connection

* fix: clear old test
main
lowercase00 2 years ago committed by GitHub
parent 7f9f0f72ba
commit d5bde117c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -3,61 +3,20 @@ title: "RQ: Connections"
layout: docs layout: docs
--- ---
Although RQ features the `use_connection()` command for convenience, it ### The connection parameter
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.
Each RQ object (queues, workers, jobs) has a `connection` keyword
## Single Redis connection (easy) argument that can be passed to the constructor - this is the recommended way of handling connections.
<div class="warning">
<img style="float: right; margin-right: -60px; margin-top: -38px" src="/img/warning.png" />
<strong>Note:</strong>
<p>
The use of <code>use_connection</code> is deprecated.
Please don't use <code>use_connection</code> in your scripts.
Instead, use explicit connection management.
</p>
</div>
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:
```python ```python
from redis import Redis from redis import Redis
from rq import use_connection from rq import Queue
redis = Redis('my.host.org', 6789, password='secret') redis = Redis('localhost', 6789)
use_connection(redis) q = Queue(connection=redis)
``` ```
Be aware of the fact that `use_connection` pollutes the global namespace. It This pattern allows for different connections to be passed to different objects:
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:
```python ```python
from rq import Queue 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. Every job that is enqueued on a queue will know what connection it belongs to.
The same goes for the workers. The same goes for the workers.
This approach is very precise, but rather verbose, and therefore, tedious.
### Connection contexts (precise and concise) ### Connection contexts (precise and concise)
<div class="warning">
<img style="float: right; margin-right: -60px; margin-top: -38px" src="/img/warning.png" />
<strong>Note:</strong>
<p>
The use of <code>Connection</code> context manager is deprecated.
Please don't use <code>Connection</code> in your scripts.
Instead, use explicit connection management.
</p>
</div>
There is a better approach if you want to use multiple connections, though. 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 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 on the RQ connection stack, which is a mechanism to temporarily replace the

@ -1,6 +1,6 @@
# flake8: noqa # 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 .job import cancel_job, get_current_job, requeue_job, Retry
from .queue import Queue from .queue import Queue
from .version import VERSION from .version import VERSION

@ -3,7 +3,7 @@ from typing import Optional
import warnings import warnings
from redis import Redis from redis import Redis
from .local import LocalStack, release_local from .local import LocalStack
class NoRedisConnectionException(Exception): class NoRedisConnectionException(Exception):
@ -65,22 +65,6 @@ def pop_connection() -> 'Redis':
return _connection_stack.pop() 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': def get_current_connection() -> 'Redis':
""" """
Returns the current Redis connection (i.e. the topmost on the 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() _connection_stack = LocalStack()
__all__ = ['Connection', 'get_current_connection', 'push_connection', 'pop_connection', 'use_connection'] __all__ = ['Connection', 'get_current_connection', 'push_connection', 'pop_connection']

@ -1,9 +1,7 @@
from redis import Redis from redis import Redis
from rq import Connection, Queue, use_connection, get_current_connection, pop_connection from rq import Connection, Queue
from rq.connections import NoRedisConnectionException from tests import RQTestCase, find_empty_redis_database
from tests import find_empty_redis_database, RQTestCase
from tests.fixtures import do_nothing from tests.fixtures import do_nothing
@ -37,30 +35,3 @@ class TestConnectionInheritance(RQTestCase):
job2 = q2.enqueue(do_nothing) job2 = q2.enqueue(do_nothing)
self.assertEqual(q1.connection, job1.connection) self.assertEqual(q1.connection, job1.connection)
self.assertEqual(q2.connection, job2.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()

Loading…
Cancel
Save