1
1
import threading
2
2
import time as mod_time
3
3
import uuid
4
- from types import SimpleNamespace
4
+ from types import SimpleNamespace , TracebackType
5
+ from typing import Optional , Type
5
6
6
7
from redis .exceptions import LockError , LockNotOwnedError
8
+ from redis .typing import Number
7
9
8
10
9
11
class Lock :
@@ -74,12 +76,13 @@ class Lock:
74
76
def __init__ (
75
77
self ,
76
78
redis ,
77
- name ,
78
- timeout = None ,
79
- sleep = 0.1 ,
80
- blocking = True ,
81
- blocking_timeout = None ,
82
- thread_local = True ,
79
+ name : str ,
80
+ * ,
81
+ timeout : Optional [Number ] = None ,
82
+ sleep : Number = 0.1 ,
83
+ blocking : bool = True ,
84
+ blocking_timeout : Optional [Number ] = None ,
85
+ thread_local : bool = True ,
83
86
):
84
87
"""
85
88
Create a new Lock instance named ``name`` using the Redis client
@@ -142,7 +145,7 @@ def __init__(
142
145
self .local .token = None
143
146
self .register_scripts ()
144
147
145
- def register_scripts (self ):
148
+ def register_scripts (self ) -> None :
146
149
cls = self .__class__
147
150
client = self .redis
148
151
if cls .lua_release is None :
@@ -152,15 +155,27 @@ def register_scripts(self):
152
155
if cls .lua_reacquire is None :
153
156
cls .lua_reacquire = client .register_script (cls .LUA_REACQUIRE_SCRIPT )
154
157
155
- def __enter__ (self ):
158
+ def __enter__ (self ) -> "Lock" :
156
159
if self .acquire ():
157
160
return self
158
161
raise LockError ("Unable to acquire lock within the time specified" )
159
162
160
- def __exit__ (self , exc_type , exc_value , traceback ):
163
+ def __exit__ (
164
+ self ,
165
+ exc_type : Optional [Type [BaseException ]],
166
+ exc_value : Optional [BaseException ],
167
+ traceback : Optional [TracebackType ],
168
+ ) -> None :
161
169
self .release ()
162
170
163
- def acquire (self , blocking = None , blocking_timeout = None , token = None ):
171
+ def acquire (
172
+ self ,
173
+ * ,
174
+ sleep : Optional [Number ] = None ,
175
+ blocking : Optional [bool ] = None ,
176
+ blocking_timeout : Optional [Number ] = None ,
177
+ token : Optional [str ] = None ,
178
+ ):
164
179
"""
165
180
Use Redis to hold a shared, distributed lock named ``name``.
166
181
Returns True once the lock is acquired.
@@ -176,7 +191,8 @@ def acquire(self, blocking=None, blocking_timeout=None, token=None):
176
191
object with the default encoding. If a token isn't specified, a UUID
177
192
will be generated.
178
193
"""
179
- sleep = self .sleep
194
+ if sleep is None :
195
+ sleep = self .sleep
180
196
if token is None :
181
197
token = uuid .uuid1 ().hex .encode ()
182
198
else :
@@ -200,7 +216,7 @@ def acquire(self, blocking=None, blocking_timeout=None, token=None):
200
216
return False
201
217
mod_time .sleep (sleep )
202
218
203
- def do_acquire (self , token ) :
219
+ def do_acquire (self , token : str ) -> bool :
204
220
if self .timeout :
205
221
# convert to milliseconds
206
222
timeout = int (self .timeout * 1000 )
@@ -210,13 +226,13 @@ def do_acquire(self, token):
210
226
return True
211
227
return False
212
228
213
- def locked (self ):
229
+ def locked (self ) -> bool :
214
230
"""
215
231
Returns True if this key is locked by any process, otherwise False.
216
232
"""
217
233
return self .redis .get (self .name ) is not None
218
234
219
- def owned (self ):
235
+ def owned (self ) -> bool :
220
236
"""
221
237
Returns True if this key is locked by this lock, otherwise False.
222
238
"""
@@ -228,21 +244,23 @@ def owned(self):
228
244
stored_token = encoder .encode (stored_token )
229
245
return self .local .token is not None and stored_token == self .local .token
230
246
231
- def release (self ):
232
- "Releases the already acquired lock"
247
+ def release (self ) -> None :
248
+ """
249
+ Releases the already acquired lock
250
+ """
233
251
expected_token = self .local .token
234
252
if expected_token is None :
235
253
raise LockError ("Cannot release an unlocked lock" )
236
254
self .local .token = None
237
255
self .do_release (expected_token )
238
256
239
- def do_release (self , expected_token ) :
257
+ def do_release (self , expected_token : str ) -> None :
240
258
if not bool (
241
259
self .lua_release (keys = [self .name ], args = [expected_token ], client = self .redis )
242
260
):
243
261
raise LockNotOwnedError ("Cannot release a lock" " that's no longer owned" )
244
262
245
- def extend (self , additional_time , replace_ttl = False ):
263
+ def extend (self , additional_time : int , replace_ttl : bool = False ) -> bool :
246
264
"""
247
265
Adds more time to an already acquired lock.
248
266
@@ -259,19 +277,19 @@ def extend(self, additional_time, replace_ttl=False):
259
277
raise LockError ("Cannot extend a lock with no timeout" )
260
278
return self .do_extend (additional_time , replace_ttl )
261
279
262
- def do_extend (self , additional_time , replace_ttl ) :
280
+ def do_extend (self , additional_time : int , replace_ttl : bool ) -> bool :
263
281
additional_time = int (additional_time * 1000 )
264
282
if not bool (
265
283
self .lua_extend (
266
284
keys = [self .name ],
267
- args = [self .local .token , additional_time , replace_ttl and "1" or "0" ],
285
+ args = [self .local .token , additional_time , "1" if replace_ttl else "0" ],
268
286
client = self .redis ,
269
287
)
270
288
):
271
- raise LockNotOwnedError ("Cannot extend a lock that's" " no longer owned" )
289
+ raise LockNotOwnedError ("Cannot extend a lock that's no longer owned" )
272
290
return True
273
291
274
- def reacquire (self ):
292
+ def reacquire (self ) -> bool :
275
293
"""
276
294
Resets a TTL of an already acquired lock back to a timeout value.
277
295
"""
@@ -281,12 +299,12 @@ def reacquire(self):
281
299
raise LockError ("Cannot reacquire a lock with no timeout" )
282
300
return self .do_reacquire ()
283
301
284
- def do_reacquire (self ):
302
+ def do_reacquire (self ) -> bool :
285
303
timeout = int (self .timeout * 1000 )
286
304
if not bool (
287
305
self .lua_reacquire (
288
306
keys = [self .name ], args = [self .local .token , timeout ], client = self .redis
289
307
)
290
308
):
291
- raise LockNotOwnedError ("Cannot reacquire a lock that's" " no longer owned" )
309
+ raise LockNotOwnedError ("Cannot reacquire a lock that's no longer owned" )
292
310
return True
0 commit comments