Remove `use_connection` (#1859)

* feat: remove use_connection

* fix: clear old test
This commit is contained in:
lowercase00 2023-03-07 00:54:47 -03:00 committed by GitHub
parent 7f9f0f72ba
commit d5bde117c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 22 additions and 100 deletions

View File

@ -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)
<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:
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)
<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.
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

View File

@ -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

View File

@ -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']

View File

@ -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()