Skip to content

Commit 85d5a00

Browse files
rwlock: Add implementation explanation
1 parent 5be0756 commit 85d5a00

File tree

1 file changed

+29
-2
lines changed

1 file changed

+29
-2
lines changed

redis/rwlock.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,30 @@
2121
from redis import Redis
2222

2323

24+
# RwLock implementation
25+
# =====================
26+
#
27+
# The lock owns three keys:
28+
# - `<prefix>:write`: If this exists, holds the token of the user that
29+
# owns the exclusive write lock.
30+
# - `<prefix>:write_semaphore`: Semaphore tracking writers that are
31+
# waiting to acquire the lock. If any writers are waiting, readers
32+
# block.
33+
# - `<prefix>:read`: Another semaphore, tracks readers.
34+
#
35+
# Semaphores are implemented as ordered sets, where score is the
36+
# expiration time of the semaphore lease (Redis instance time). Expired
37+
# leases are pruned before attempting to acquire the lock.
38+
#
39+
# We can't use built-in key expiration because individual set members
40+
# cannot have an expiration. We can't create keys dynamically because
41+
# this may break multi-node compatibility.
42+
#
43+
# The write-acquire script is careful to ensure that the writer waiting
44+
# semaphore is only held if the caller is actually blocking; otherwise
45+
# the caller adds contention for no reason.
46+
47+
2448
class RwLock:
2549
"""A shared reader-writer lock.
2650
@@ -30,14 +54,17 @@ class RwLock:
3054
priority when waiting on the lock so that readers do not starve
3155
waiting writers. Writers are allowed to starve readers, however.
3256
33-
This type of lock is effective for scenarios where reads are
57+
This type of unfair lock is effective for scenarios where reads are
3458
frequent and writes are infrequent. Because this lock relies on busy
3559
waiting, it can be wasteful to use if your critical sections are
3660
long and frequent.
3761
3862
This lock is not fault-tolerant in a multi-node Redis setup. When a
3963
master fails and data is lost, writer exclusivity may be violated.
4064
In a single-node setup, the lock is sound.
65+
66+
This lock is not re-entrant; attempting to acquire it twice in the
67+
same thread may cause a deadlock until the blocking timeout ends.
4168
"""
4269

4370
lua_acquire_reader = None
@@ -78,7 +105,7 @@ class RwLock:
78105
# KEYS[3] - reader lock name
79106
# ARGV[1] - token
80107
# ARGV[2] - expiration
81-
# ARGV[3] - sempahore expiration
108+
# ARGV[3] - sempahore expiration (or 0 to release the sempahore)
82109
# ARGV[4] - max writers
83110
#
84111
# NOTE: return codes:

0 commit comments

Comments
 (0)