16161717
1818import errno
19- from datetime import datetime
20- from time import sleep
19+ from datetime import datetime , timedelta
2120
2221from cortx .utils .conf_store .error import ConfError
2322from cortx .utils .conf_store .conf_cache import ConfCache
@@ -279,40 +278,26 @@ def lock(self, index: str, **kwargs):
279278 raise ConfError (errno .EINVAL , "config index %s is not loaded" ,
280279 index )
281280
282- self .timeout = const .DEFAULT_LOCK_TIMEOUT
281+ self .duration = const .DEFAULT_LOCK_DURATION
283282 self .lock_owner = self .default_owner
284283 self .lock_key = const .LOCK_KEY
285- allowed_keys = { 'lock_key' , 'lock_owner' , 'timeout ' }
284+ allowed_keys = { 'lock_key' , 'lock_owner' , 'duration ' }
286285 for key , value in kwargs .items ():
287286 if key not in allowed_keys :
288287 raise ConfError (errno .EINVAL , "Invalid parameter %s" , key )
289288
290- if key == 'timeout ' and not isinstance (value , int ):
289+ if key == 'duration ' and not isinstance (value , int ):
291290 raise ConfError (errno .EINVAL , "Invalid value %s for parameter %s" , value , key )
292291
293292 setattr (self , key , value )
294293
295- who_owner = self ._get_lock_owner (index , self .lock_key )
296- if who_owner is not None :
297- return who_owner == self .lock_owner
298-
299- while self .timeout > 1 :
300- sleep (const .DEFAULT_RETRY_DELAY )
301- # TODO: Add condition_check scenario here
302- self .timeout -= 1
303-
304- if not self ._lock (index , self .lock_key , self .lock_owner ):
305- self .lock_owner = self .default_owner
306- return False
307- return True
308-
309- def _lock (self , index : str , lock_key : str , lock_owner : str ):
310- """Acquire lock on config."""
311- locked_at = str (datetime .timestamp (datetime .now ()))
312- self .set (index , const .LOCK_OWNER_KEY % lock_key , lock_owner )
313- self .set (index , const .LOCK_TIME_KEY % lock_key , locked_at )
314-
315- return self ._get_lock_owner (index , lock_key ) == lock_owner
294+ rc = False
295+ if not self .test_lock (index , lock_owner = self .lock_owner ):
296+ self .set (index , const .LOCK_OWNER_KEY % self .lock_key , self .lock_owner )
297+ lock_end_time = datetime .now () + timedelta (seconds = self .duration )
298+ self .set (index , const .LOCK_END_TIME_KEY % self .lock_key , str (lock_end_time ))
299+ rc = True
300+ return rc
316301
317302 def unlock (self , index : str , ** kwargs ):
318303 """Release config lock."""
@@ -336,24 +321,37 @@ def unlock(self, index: str, **kwargs):
336321
337322 setattr (self , key , value )
338323
339- _is_locked = self ._get_lock_owner (index , self .lock_key ) == self .lock_owner
340- return self .delete (index , const .LOCK_OWNER_KEY % self .lock_key ) if _is_locked \
341- or self .force else False
324+ rc = False
325+ if self ._get_lock_owner (index , self .lock_key ) == self .lock_owner or self .force :
326+ self .delete (index , const .LOCK_OWNER_KEY % self .lock_key )
327+ self .delete (index , const .LOCK_END_TIME_KEY % self .lock_key )
328+ rc = True
329+ return rc
342330
343331 def test_lock (self , index : str , ** kwargs ):
344332 """Check whether lock is acquired on the config."""
345333 if index not in self ._cache .keys ():
346334 raise ConfError (errno .EINVAL , "config index %s is not loaded" ,
347335 index )
348- allowed_keys = { 'lock_key' }
336+ allowed_keys = { 'lock_key' , 'lock_owner' }
349337 self .lock_key = const .LOCK_KEY
338+ self .lock_owner = self .default_owner
350339 for key , value in kwargs .items ():
351340 if key not in allowed_keys :
352341 raise ConfError (errno .EINVAL , "Invalid parameter %s" , key )
353342
354343 setattr (self , key , value )
355344
356- return False if self ._get_lock_owner (index , self .lock_key ) is None else True
345+ if self ._get_lock_owner (index , self .lock_key ) in [None , "" , self .lock_owner ]:
346+ return False
347+
348+ lock_end_time = self .get (index , const .LOCK_END_TIME_KEY % self .lock_key )
349+ if lock_end_time in [None , "" ]:
350+ return False
351+ lock_end_time = datetime .strptime (lock_end_time , "%Y-%m-%d %H:%M:%S.%f" )
352+ if lock_end_time < datetime .now ():
353+ return False
354+ return True
357355
358356 def _get_lock_owner (self , index : str , lock_key : str ):
359357 """Get owner of the config lock."""
@@ -473,7 +471,7 @@ def lock(index: str, **kwargs):
473471 :param index(required): Identifier of the config.
474472 :param lock_key(optional): Lock related key ex: conf>service>lock.
475473 :param lock_owner(optional, default=machine_id): Identity of the lock holder.
476- :param timeout (optional): Time delay before attempting to acquire lock .
474+ :param duration (optional): Obtains the lock for the give duration in terms of seconds .
477475
478476 :return: True if the lock was successfully acquired,
479477 false if it is already acquired by someone.
@@ -500,8 +498,9 @@ def test_lock(index: str, **kwargs):
500498 Test whether Config is locked.
501499 :param index(required): param index: Identifier of the config.
502500 :param lock_key(optional): Lock related key ex: conf>service>lock.
501+ :param lock_owner(optional, default=machine_id): Identity of owner who is sending test lock request.
503502
504- :return: True if lock is acquired by somone else False
503+ :return: True if lock is acquired by someone else False
505504 """
506505 return Conf ._conf .test_lock (index , ** kwargs )
507506
0 commit comments