Package: distrilockper
distrilockper - Distributed Lock HelperFeatureSupport Redis Cluster and Redis Single setupRedis operation with Lua scripting (Atomic operations)Lock watch dog (auto increase the alive time of key if the process time is large than key ttl)Thread safeSupport Reentrant lockSupport expired unlock function, automatically unlock after x seconds, no need to manually unlock by call unlock methodSupport try lock, wait n second if the lock is existed.Basic UsageInstallpipinstalldistrilockperdeclare config instancefromdistrilockperimportConfigconfig=Config()select single Redis server mode or cluster Redis servers modeconfig.use_single_server()config.use_cluster_servers()set the configconfig.use_single_server().set_config(host='0.0.0.0',port=6379)config.use_cluster_servers().set_config(host='0.0.0.0',port=7000)config.use_cluster_servers().add_node_address(host='0.0.0.0',port=7000)\.add_node_address(host='0.0.0.0',port=7001)\.add_node_address(host='0.0.0.0',port=7002)\.add_node_address(host='0.0.0.0',port=7003)\.add_node_address(host='0.0.0.0',port=7004)\.add_node_address(host='0.0.0.0',port=7005)The set_config and add_node_address method takes several arguments from python redis librarydeclare the lock instancehelper=LockHelper()helper.create(config)get a kind of locklock=helper.get_reentrant_lock(key='apples')try lock the keyresult=lock.try_lock(wait_time=10,lease_time=7,time_unit='second')The try_lock method takes several arguments:wait_time: try lock operation time outlease_time: the release time of the locktime_unit: unit of lease_time and wait_timeseconds/shour/hminute/mmilliseconds/msunlock after business logic donelock.unlock()Reentrantthe reentrant lock only supports in the same threadGet the lock in different threadfromdistrilockperimportConfigfromdistrilockperimportLockHelperfrommultiprocessing.dummyimportPoolasThreadPoolconfig=Config()config.use_single_server().set_config(host='0.0.0.0',port=6379)helper=LockHelper()helper.create(config)defget_lock(_):print("run",_)Locker1=helper.get_reentrant_lock(key='apples')re1=Locker1.try_lock(60,10,'second')assertre1==Trueprint("get lock",re1)assertLocker1.is_exists()==Trueprint('exists',Locker1.is_exists())pool=ThreadPool(100)results=pool.map(get_lock,range(10))get the lock in same threadfromdistrilockperimportConfigfromdistrilockperimportLockHelperfrommultiprocessing.dummyimportPoolasThreadPoolconfig=Config()config.use_single_server().set_config(host='0.0.0.0',port=6379)helper=LockHelper()helper.create(config)foriinrange(10):Locker1=helper.get_reentrant_lock(key='apples')re1=Locker1.try_lock(60,10,'second')assertre1==Trueprint("get lock",re1)assertLocker1.is_exists()==Trueprint('exists',Locker1.is_exists())Watchdog (for lock)use case: the time is not predictable for time-consuming task or business logic. you can not set the fixed release time for lock you got. An Alternative plan that you can set a high number for release but it will be wait a long long time when you program be aborted unexpectedlyWatchdog mechanism will refresh regularly the lock until you call unlock method or the program be aborted unexpectedlyfromdistrilockperimportConfigfromdistrilockperimportLockHelperfromrandomimportrandintfromtimeimportsleepconfig=Config()config.use_single_server().set_config(host='0.0.0.0',port=6379)helper=LockHelper()helper.create(config)foriinrange(10):Locker1=helper.get_reentrant_lock(key='apples')re1=Locker1.try_lock(wait_time=60,time_unit='second')assertre1==Trueprint("get lock",re1)assertLocker1.is_exists()==Trueprint('exists',Locker1.is_exists())print('do something ')sleep(randint(10,100))assertLocker1.unlock()==True