public InMemorySlidingWindowRequestRateLimiter(Set<RequestLimitRule> rules) { this(rules, new SystemTimeSupplier()); }
@Override public CompletionStage<Long> getAsync() { return CompletableFuture.completedFuture(get()); }
@Test void shouldGetSystemCurrentTime() { Long time = new SystemTimeSupplier().get(); assertThat(time).isCloseTo(System.currentTimeMillis() / 1000L, Offset.offset(2L)); }
@Test void shouldGetReactiveSystemCurrentTime() { Long time = new SystemTimeSupplier().getReactive().block(); assertThat(time).isCloseTo(System.currentTimeMillis() / 1000L, Offset.offset(2L)); } }
@Test void shouldGetAsyncSystemCurrentTime() throws Exception { Long time = new SystemTimeSupplier().getAsync().toCompletableFuture().get(); assertThat(time).isCloseTo(System.currentTimeMillis() / 1000L, Offset.offset(2L)); }
private boolean eqOrGeLimit(String key, int weight, boolean strictlyGreater) { final long now = timeSupplier.get(); final Set<RequestLimitRule> rules = rulesSupplier.getRules(key);
private Mono<Boolean> eqOrGeLimitReactive(String key, int weight, boolean strictlyGreater) { requireNonNull(key); String rulesJson = requestLimitRulesSupplier.getRules(key); return Mono.zip(timeSupplier.getReactive(), scriptLoader.storedScript()) .flatMapMany(tuple -> { Long time = tuple.getT1(); StoredScript script = tuple.getT2(); return redisScriptingReactiveCommands .evalsha(script.getSha(), VALUE, new String[]{key}, rulesJson, time.toString(), Integer.toString(weight), toStringOneZero(strictlyGreater)) .doOnError(STARTS_WITH_NO_SCRIPT_ERROR, e -> script.dispose()); }) .retry(1, STARTS_WITH_NO_SCRIPT_ERROR) .single() .map("1"::equals) .doOnSuccess(over -> { if (over) { LOG.debug("Requests matched by key '{}' incremented by weight {} are greater than {}the limit", key, weight, strictlyGreater ? "" : "or equal to "); } }); }
public RedisSlidingWindowRequestRateLimiter(RedisScriptingReactiveCommands<String, String> redisScriptingReactiveCommands, RedisKeyReactiveCommands<String, String> redisKeyCommands, Set<RequestLimitRule> rules) { this(redisScriptingReactiveCommands, redisKeyCommands, rules, new SystemTimeSupplier()); }
@Override public Mono<Long> getReactive() { return Mono.just(get()); }
private boolean eqOrGeLimit(String key, int weight, boolean strictlyGreater) { final long now = timeSupplier.get(); final Set<RequestLimitRule> rules = rulesSupplier.getRules(key);
public HazelcastSlidingWindowRequestRateLimiter(HazelcastInstance hz, Set<RequestLimitRule> rules) { this(hz, rules, new SystemTimeSupplier()); }
public InMemorySlidingWindowRequestRateLimiter(RequestLimitRule rule) { this(Collections.singleton(rule), new SystemTimeSupplier()); }
@Test void shouldReloadMissingScript() { ImmutableSet<RequestLimitRule> rules = ImmutableSet.of(RequestLimitRule.of(Duration.ofSeconds(60), 1)); ReactiveRequestRateLimiter rateLimiter = getRateLimiter(rules, new SystemTimeSupplier()); rateLimiter.overLimitWhenIncrementedReactive(UUID.randomUUID().toString()).block(Duration.ofSeconds(5)); getRedisScriptingReactiveCommands().scriptFlush().block(); rateLimiter.overLimitWhenIncrementedReactive(UUID.randomUUID().toString()).block(Duration.ofSeconds(5)); } }