@Service
public class ReportConcurrentService {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private RedisConfig redisConfig;
@Value("${report.user-concurrent:1}")
private int userConcurrent;
@Value("${report.common-concurrent:10}")
private int commonConcurrent;
private String getUserKey(long userId, String beanName) {
return redisConfig.getUkPrfex(String.join(":", CoreConstants.REPORT_CONCURRENT_USER_COUNTER, String.valueOf(userId), beanName));
}
private String getCommonKey() {
return redisConfig.getUkPrfex(String.join(":", CoreConstants.REPORT_CONCURRENT_COMMON_COUNTER));
}
public void acquire(long userId, String beanName) {
String commonKey = getCommonKey();
Long increment = redisTemplate.opsForValue().increment(commonKey);
redisTemplate.expire(commonKey, 1, TimeUnit.HOURS);
if (increment != null && increment > commonConcurrent) {
redisTemplate.opsForValue().decrement(commonKey);
ReportConcurrentErrorEnum.EXCEEDING_CONCURRENT_LIMIT.fail();
}
String userKey = getUserKey(userId, beanName);
increment = redisTemplate.opsForValue().increment(userKey);
redisTemplate.expire(userKey, 1, TimeUnit.HOURS);
if (increment != null && increment > userConcurrent) {
redisTemplate.opsForValue().decrement(commonKey);
redisTemplate.opsForValue().decrement(userKey);
ReportConcurrentErrorEnum.HAS_TASK_IN_EXPORTING.fail();
}
}
public void release(long userId, String beanName) {
String key = getCommonKey();
redisTemplate.opsForValue().decrement(key);
key = getUserKey(userId, beanName);
redisTemplate.opsForValue().decrement(key);
}
}