blob: 726121a2c20eab2574ff70c2fea087d6534abef3 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.servicecomb.governance.policy;
import java.time.Duration;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
public class RetryPolicy extends AbstractPolicy {
public static final int DEFAULT_MAX_ATTEMPTS = 3;
public static final Duration DEFAULT_WAIT_DURATION = Duration.ofMillis(1);
public static final String DEFAULT_RETRY_ON_RESPONSE_STATUS_502 = "502";
public static final String DEFAULT_RETRY_ON_RESPONSE_STATUS_503 = "503";
public static final List<String> DEFAULT_STATUS_LIST = Arrays.asList(DEFAULT_RETRY_ON_RESPONSE_STATUS_502,
DEFAULT_RETRY_ON_RESPONSE_STATUS_503);
private static final Duration INITIAL_INTERVAL = Duration.ofMillis(1000);
private static final float MULTIPLIER = 2;
private static final double RANDOMIZATION_FACTOR = 0.5;
private static final String DEFAULT_RETRY_STRATEGY = "FixedInterval";
//max retry attempts
private int maxAttempts = DEFAULT_MAX_ATTEMPTS;
//wait duration for each retry
private String waitDuration = DEFAULT_WAIT_DURATION.toString();
//status code that need retry
private List<String> retryOnResponseStatus = DEFAULT_STATUS_LIST;
//retry strategy
private String retryStrategy = DEFAULT_RETRY_STRATEGY;
// initial interval for backoff retry
private String initialInterval = INITIAL_INTERVAL.toString();
// multiplier for backoff retry
private float multiplier = MULTIPLIER;
// randomization factor for backoff retry
private double randomizationFactor = RANDOMIZATION_FACTOR;
// if throw an MaxRetriesExceededException if retry condition is based on result
private boolean failAfterMaxAttempts = false;
// if retry on the same instance. This property is not directly used in
// RetryHandler, but used for loadbalancers
private int retryOnSame = 0;
public List<String> getRetryOnResponseStatus() {
if (CollectionUtils.isEmpty(retryOnResponseStatus)) {
return DEFAULT_STATUS_LIST;
}
return retryOnResponseStatus;
}
public void setRetryOnResponseStatus(List<String> retryOnResponseStatus) {
if (retryOnResponseStatus == null) {
return;
}
this.retryOnResponseStatus = retryOnResponseStatus.stream().filter(e -> !StringUtils.isEmpty(e))
.collect(Collectors.toList());
}
public int getMaxAttempts() {
return maxAttempts;
}
public void setMaxAttempts(int maxAttempts) {
this.maxAttempts = maxAttempts;
}
public String getWaitDuration() {
return Duration.parse(waitDuration).toMillis() < 1 ? DEFAULT_WAIT_DURATION.toString() : waitDuration;
}
public void setWaitDuration(String waitDuration) {
this.waitDuration = stringOfDuration(waitDuration, DEFAULT_WAIT_DURATION);
}
public String getRetryStrategy() {
if (StringUtils.isEmpty(retryStrategy)) {
retryStrategy = DEFAULT_RETRY_STRATEGY;
}
return retryStrategy;
}
public void setRetryStrategy(String retryStrategy) {
this.retryStrategy = retryStrategy;
}
public String getInitialInterval() {
return initialInterval;
}
public void setInitialInterval(String initialInterval) {
this.initialInterval = stringOfDuration(initialInterval, INITIAL_INTERVAL);
}
public float getMultiplier() {
return multiplier;
}
public void setMultiplier(float multiplier) {
this.multiplier = multiplier;
}
public double getRandomizationFactor() {
return randomizationFactor;
}
public void setRandomizationFactor(double randomizationFactor) {
this.randomizationFactor = randomizationFactor;
}
public boolean isFailAfterMaxAttempts() {
return failAfterMaxAttempts;
}
public void setFailAfterMaxAttempts(boolean failAfterMaxAttempts) {
this.failAfterMaxAttempts = failAfterMaxAttempts;
}
public int getRetryOnSame() {
return retryOnSame;
}
public void setRetryOnSame(int retryOnSame) {
this.retryOnSame = retryOnSame;
}
@Override
public boolean isValid() {
if (maxAttempts < 1) {
return false;
}
if (Duration.parse(waitDuration).toMillis() < 0) {
return false;
}
if (Duration.parse(initialInterval).toMillis() < 10) {
return false;
}
return super.isValid();
}
@Override
public String toString() {
return "RetryPolicy{" +
"maxAttempts=" + maxAttempts +
", waitDuration=" + waitDuration +
", retryOnResponseStatus='" + retryOnResponseStatus + '\'' +
'}';
}
}