[ redis基于Django分布式锁 ]


Redis-基于redis的cache实现

from django.core import cache, checks
import uuid, time

class CacheLock:
    def __init__(self, expries=60, wait_timeout=0) -> None:
        '''
        expries: 锁的过期时间
        wait_timeout: 客户端设置的超时时间
        '''
        self.cache = cache
        self.expires = expries
        self.wait_timeout = wait_timeout

    def get_lock(self, lock_key):
        # 获取锁
        wait_timeout = self.wait_timeout
        identifier = uuid.uuid4()
        while wait_timeout <= 0:
            if self.cache.add(key=lock_key, value=identifier, timeout=self.expires):
                print('加锁成功')
                return identifier
            wait_timeout -= 1
            time.sleep(1)
        print('msg: 当前有其他用户正在编辑')

    def release_lock(self, lock_key, identifier):
        # 释放锁
        lock_value = self.cache.get(lock_key)     
        if lock_value == identifier:
            print('释放锁成功')
            self.cache.delete(lock_key)


# 装饰器
def lock(cache_lock):
    def my_decorator(func):
        def wrapper(*args, **kwargs):
            lock_key = 'redis_lock:'
            identifier = cache_lock.get_lock(lock_key)

            执行顺序
                1. 加锁
                2. try - return - 执行业务
                3. finally - 释放锁

            try:
                return func(*args, **kwargs)
            finally:
                cache_lock.release_lock(lock_key, identifier)
        return wrapper
    return my_decorator
# 使用
@lock(CacheLock())
def redis_cache_lock_test(name):
    print(f'name={name}')

装饰器解析
把CacheLock实例化后传入lock装饰器

一、 lock装饰器进入
    1. 参数说明:: 
        - cache_lock = CacheLock(), 
        - func = redis_cache_lock_test(name), 
        - (*args, **kwargs) = 主函数传的参数name
    2. 执行流程
        - 进入装饰器函数wrapper内部执行
        - try - return 执行func也就是主函数
        - finally 解锁