I'm trying to create a lock on a redis value in a django project, but am having trouble. Non blocking code works just fine, ie:
r = redis.StrictRedis(host='localhost', port=6379)
data_dict = {'key': 'value'}
r.hmset('hash', data_dict)
However when trying to use a lock to prevent other threads from writing to this, with code:
r = redis.StrictRedis(host='localhost', port=6379)
data_dict = {'key': 'value'}
lock = r.lock('hash')
with lock.acquire() as l:
r.hmset('hash', data_dict)
throws:redis.exceptions.ResponseError: WRONGTYPE Operation against a key holding the wrong kind of value
I apologize if this is a very stupid question but I don't understand how I'm getting that error, the data being set is literally the same
from redis import Redis conn = Redis() import redis_lock lock = redis_lock. Lock(conn, "name-of-the-lock") if lock. acquire(blocking=False): print("Got the lock.") lock. release() else: print("Someone else has the lock.")
The simplest way to use Redis to lock a resource is to create a key in an instance. The key is usually created with a limited time to live, using the Redis expires feature, so that eventually it will get released (property 2 in our list). When the client needs to release the resource, it deletes the key.
To connect and use Redis with Python, we need a Python-Redis client. For this process, we will opt for redis-py as it is easy to use and configure. The previous command should download and install the Redis-py client.
There are two problems:
To elaborate on point 2, here are the steps involved with using a lock:
Lock
object.Without using a context manager (the with ...
statement), the code might look like this:
lock = r.lock('my_lock')
lock.acquire(blocking=True)
r.set('foo', 'bar')
lock.release()
With a context manager, that code gets simplified to this:
with r.lock('my_lock'):
r.set('foo', 'bar')
What is happening here is the following:
r.lock()
creates and returns a Lock
object.Lock.__enter__()
is called automatically, which in turn calls Lock.acquire()
. Lock.__exit__()
is called automatically, which in turn calls Lock.release()
.You can see this in the redis-py source code.
lock()
)Lock
class) You are trying to set a dictionary in the same key as the lock. You want to have a key for the lock and another for the dictionary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With