package com.yichao.woo.ratelimiter.v2;
import com.google.common.base.Preconditions;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
public final class LuaRateLimiter {
private JedisPool jedisPool;
private String scriptSha1;
private RateLimitPolicy policy;
private LuaRateLimiter() {
jedisPool = new JedisPool("192.168.70.3", 6379);
}
public final boolean access(final String identity) {
Preconditions.checkNotNull(jedisPool, "Redis not initialized");
Preconditions.checkNotNull(policy, "Policy not initialized");
Preconditions.checkArgument(StringUtils.isNotBlank(scriptSha1), "Sha1 not initialized");
String key = policy.genBucketKey(identity);
try (Jedis jedis = jedisPool.getResource()) {
long result = (long) jedis.evalsha(scriptSha1, 1, key,
String.valueOf(policy.getIntervalPerPermit()),
String.valueOf(System.currentTimeMillis()),
String.valueOf(policy.getMaxBurstTokens()),
String.valueOf(policy.getCapacity()),
String.valueOf(policy.getIntervalInMills()));
return result == 1L;
}
}
static String read(String luaScriptPath) throws IOException {
Path path = Paths.get(luaScriptPath);
byte[] scriptBytes = Files.readAllBytes(path);
return new String(scriptBytes);
}
public static class Builder {
private String luaScript;
public Builder(String luaScriptPath) throws IOException {
luaScript = read(luaScriptPath);
}
public LuaRateLimiter newLuaRateLimiter(RateLimitPolicy policy) {
Preconditions.checkNotNull(policy);
LuaRateLimiter limiter = new LuaRateLimiter();
limiter.policy = policy;
try (Jedis jedis = limiter.jedisPool.getResource()) {
limiter.scriptSha1 = jedis.scriptLoad(luaScript);
}
return limiter;
}
}
}