question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Managing the same lock with different handlers

See original GitHub issue

Describe the bug Sometimes I need to acquire and release the same lock with different objects. I am constricted by a legacy design to do it this way, because acquiring and releasing the lock will be in separate processes. However, if I open a second handle to the same lock key, I can’t release the lock from there.

To Reproduce

Python 3.6.5 (default, Mar 25 2020, 10:32:15) 
[GCC 4.2.1 Compatible Apple LLVM 10.0.1 (clang-1001.0.46.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pottery
>>> import redis
>>> lock = pottery.Redlock(key="test-lock", masters={redis.Redis()}, auto_release_time=40000)
>>> lock.acquire()
True
>>> lock.locked()
33200
>>> lock2 = pottery.Redlock(key="test-lock", masters={redis.Redis()}, auto_release_time=40000)
>>> lock.locked()
23395
>>> lock2.locked()
0
>>> lock2.release()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/arieroos/Workspace/dos/venv/lib/python3.6/site-packages/pottery/redlock.py", line 572, in release
    redis_errors=redis_errors,
pottery.exceptions.ReleaseUnlockedLock: key='redlock:test-lock', masters=[Redis<ConnectionPool<Connection<host=localhost,port=6379,db=0>>>], redis_errors=[]

Expected behavior

Python 3.6.5 (default, Mar 25 2020, 10:32:15) 
[GCC 4.2.1 Compatible Apple LLVM 10.0.1 (clang-1001.0.46.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pottery
>>> import redis
>>> lock = pottery.Redlock(key="test-lock", masters={redis.Redis()}, auto_release_time=40000)
>>> lock.acquire()
True
>>> lock.locked()
33200
>>> lock2 = pottery.Redlock(key="test-lock", masters={redis.Redis()}, auto_release_time=40000)
>>> lock.locked()
23395
>>> lock2.locked()
13395  # or some integer like that
>>> lock2.release()
# no exception thrown

Environment (please complete the following information):

  • OS: macOS (However, I use Linux in production)
  • Python version: 3.5.6

Additional context Currently I just ignore the Exception, as most locks will expire in time anyway. However, that is probably bad practice.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:6
  • Comments:7

github_iconTop GitHub Comments

1reaction
belthaZornvcommented, Oct 1, 2021

Same issue here - you’d expect a distributed lock - to be distributed; if you can’t check if a lock is locked from a different resource then there isn’t much use.

0reactions
Arrow-Licommented, Nov 29, 2022

I don’t know if we have the same issue. We use locks in different services (in some services they are also used in different threads), we set their key and master We use the locks using

with the_lock:
    <code we want to execute with lock>

The same key is used between services. It normally works fine (probably when they are not using it at the same time) and then some times we get ReleaseUnlockedLock

I’ve added some logs to see if what was running inside and it seems it finishes running. Then would it mean another lock acquired it and released it when this one was supposed to have it?

I’ll be checking more in depth to add more info, but if some one has a hint of what could be happening or what I could look for would be greatly appreciated.

Update: Tried a simple test with different services on different machines and worked correctly, will keep looking

Update 2: Oh I get it now You cannot use same lock variable, you need to initialize it again so it would have to be (as in the examples I guess)

with Redlock(the_lock_key):
    <code we want to execute with lock>

It’s weird, I got same error by below code.

            with Redlock(
                    key=f"{func.__module__}:{func.__name__}",
                    masters={get_redis_conn()},
                    context_manager_blocking=False
            ):
                pass # do something here

Error Info:

Traceback (most recent call last):
  File "/runtime/python3.9/lib/python3.9/site-packages/apscheduler/executors/base.py", line 125, in run_job
    retval = job.func(*job.args, **job.kwargs)
  File "/server/./utils/tools.py", line 118, in wrapper
    return func(*args, **kwargs)
  File "/runtime/python3.9/lib/python3.9/site-packages/pottery/redlock.py", line 673, in __exit__
    self.__release()
  File "/runtime/python3.9/lib/python3.9/site-packages/pottery/redlock.py", line 595, in release
    raise ReleaseUnlockedLock(
pottery.exceptions.ReleaseUnlockedLock: ('redlock:***.***:***', frozenset({Redis<ConnectionPool<Connection<host=***,port=6379,db=5>>>}))
Read more comments on GitHub >

github_iconTop Results From Across the Web

Alternatives To Using The Same Key For All Locks
Managing keys for multiple locks has never been so easy. If you're looking for a better alternative to: Carrying a bulky ring of...
Read more >
Lock User Management (LUM) FAQ's and Tips
Yes you can control multiple locks from a single app instance. Select all locks on the main page and then you can assign...
Read more >
Lock handler for arbitrary keys - java - Stack Overflow
The crudest way to do this is to associate every key with the same lock, which results in the coarsest synchronization possible. On...
Read more >
Transaction locking and row versioning guide - SQL Server
Each transaction requests locks of different types on the resources, ... the same row several times and reads different data each time.
Read more >
Lock Handling
From a usage point of view, the BDB SQL interface behaves in the same way as ... It also has a locking model...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found