package cn.iocoder.yudao.framework.redis.helper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * redis分布式锁并发控制模板类
 *
 * @author zhangguozhan
 */
@Slf4j
@Component
public class RedisLockTemplate {
    @Autowired
    private RedisDistributedLock redisDistributedLock;

    /**
     * redis分布式锁控制
     *
     * @param key               锁名
     * @param expireMS          锁的生命周期，单位：毫秒
     * @param redisLockCallback callback方法
     * @return
     */
    public Object execute(String key, long expireMS, RedisLockCallback redisLockCallback) {
        return execute(key, expireMS, redisLockCallback, false, 2);
    }

    /**
     * redis分布式锁控制
     *
     * @param key
     * @param expireMS
     * @param redisLockCallback
     * @param isAutoReleaseLock callback方法执行完成后自动释放锁
     * @return
     */
    public Object execute(String key, long expireMS, RedisLockCallback redisLockCallback,
                          boolean isAutoReleaseLock,
                          int retryTimes) {
        log.info("redis分布式锁控制 key={}", key);
        if (StringUtils.isBlank(key)) {
            log.info("try lock failure:key is null");
            return null;
        }
        boolean lock = redisDistributedLock.lock(key, expireMS, retryTimes, 1000);
        if (lock) {
            try {
                Object o = redisLockCallback.doInRedisLock();
                return o;
            } finally {
                if (isAutoReleaseLock) {
                    redisDistributedLock.releaseLock(key);
                }
            }
        } else {
            log.info("###key已存在，终止 key={}", key);
            return null;
        }

    }
}
