/* * * Copyright 2016 Robert Winkler and Bohdan Storozhuk * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * */ package io.github.resilience4j.ratelimiter; import java.time.Duration; import static java.util.Objects.requireNonNull; public class RateLimiterConfig { private static final String TIMEOUT_DURATION_MUST_NOT_BE_NULL = "TimeoutDuration must not be null"; private static final String LIMIT_REFRESH_PERIOD_MUST_NOT_BE_NULL = "LimitRefreshPeriod must not be null"; private static final Duration ACCEPTABLE_REFRESH_PERIOD = Duration.ofNanos(1L); private Duration timeoutDuration = Duration.ofSeconds(5); private Duration limitRefreshPeriod = Duration.ofNanos(500); private int limitForPeriod = 50; private RateLimiterConfig() { } /** * Returns a builder to create a custom RateLimiterConfig. * * @return a {@link RateLimiterConfig.Builder} */ public static Builder custom() { return new Builder(); } /** * Creates a default RateLimiter configuration. * * @return a default RateLimiter configuration. */ public static RateLimiterConfig ofDefaults(){ return new Builder().build(); } public Duration getTimeoutDuration() { return timeoutDuration; } public Duration getLimitRefreshPeriod() { return limitRefreshPeriod; } public int getLimitForPeriod() { return limitForPeriod; } @Override public String toString() { return "RateLimiterConfig{" + "timeoutDuration=" + timeoutDuration + ", limitRefreshPeriod=" + limitRefreshPeriod + ", limitForPeriod=" + limitForPeriod + '}'; } public static class Builder { private RateLimiterConfig config = new RateLimiterConfig(); /** * Builds a RateLimiterConfig * * @return the RateLimiterConfig */ public RateLimiterConfig build() { return config; } /** * Configures the default wait for permission duration. * Default value is 5 seconds. * * @param timeoutDuration the default wait for permission duration * @return the RateLimiterConfig.Builder */ public Builder timeoutDuration(final Duration timeoutDuration) { config.timeoutDuration = checkTimeoutDuration(timeoutDuration); return this; } /** * Configures the period of limit refresh. * After each period rate limiter sets its permissions * count to {@link RateLimiterConfig#limitForPeriod} value. * Default value is 500 nanoseconds. * * @param limitRefreshPeriod the period of limit refresh * @return the RateLimiterConfig.Builder */ public Builder limitRefreshPeriod(final Duration limitRefreshPeriod) { config.limitRefreshPeriod = checkLimitRefreshPeriod(limitRefreshPeriod); return this; } /** * Configures the permissions limit for refresh period. * Count of permissions available during one rate limiter period * specified by {@link RateLimiterConfig#limitRefreshPeriod} value. * Default value is 50. * * @param limitForPeriod the permissions limit for refresh period * @return the RateLimiterConfig.Builder */ public Builder limitForPeriod(final int limitForPeriod) { config.limitForPeriod = checkLimitForPeriod(limitForPeriod); return this; } } private static Duration checkTimeoutDuration(final Duration timeoutDuration) { return requireNonNull(timeoutDuration, TIMEOUT_DURATION_MUST_NOT_BE_NULL); } private static Duration checkLimitRefreshPeriod(Duration limitRefreshPeriod) { requireNonNull(limitRefreshPeriod, LIMIT_REFRESH_PERIOD_MUST_NOT_BE_NULL); boolean refreshPeriodIsTooShort = limitRefreshPeriod.compareTo(ACCEPTABLE_REFRESH_PERIOD) < 0; if (refreshPeriodIsTooShort) { throw new IllegalArgumentException("LimitRefreshPeriod is too short"); } return limitRefreshPeriod; } private static int checkLimitForPeriod(final int limitForPeriod) { if (limitForPeriod < 1) { throw new IllegalArgumentException("LimitForPeriod should be greater than 0"); } return limitForPeriod; } }