001/*
002 * Copyright 2002-2016 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.util.backoff;
018
019/**
020 * A simple {@link BackOff} implementation that provides a fixed interval
021 * between two attempts and a maximum number of retries.
022 *
023 * @author Stephane Nicoll
024 * @since 4.1
025 */
026public class FixedBackOff implements BackOff {
027
028        /**
029         * The default recovery interval: 5000 ms = 5 seconds.
030         */
031        public static final long DEFAULT_INTERVAL = 5000;
032
033        /**
034         * Constant value indicating an unlimited number of attempts.
035         */
036        public static final long UNLIMITED_ATTEMPTS = Long.MAX_VALUE;
037
038        private long interval = DEFAULT_INTERVAL;
039
040        private long maxAttempts = UNLIMITED_ATTEMPTS;
041
042
043        /**
044         * Create an instance with an interval of {@value #DEFAULT_INTERVAL}
045         * ms and an unlimited number of attempts.
046         */
047        public FixedBackOff() {
048        }
049
050        /**
051         * Create an instance.
052         * @param interval the interval between two attempts
053         * @param maxAttempts the maximum number of attempts
054         */
055        public FixedBackOff(long interval, long maxAttempts) {
056                this.interval = interval;
057                this.maxAttempts = maxAttempts;
058        }
059
060
061        /**
062         * Set the interval between two attempts in milliseconds.
063         */
064        public void setInterval(long interval) {
065                this.interval = interval;
066        }
067
068        /**
069         * Return the interval between two attempts in milliseconds.
070         */
071        public long getInterval() {
072                return interval;
073        }
074
075        /**
076         * Set the maximum number of attempts in milliseconds.
077         */
078        public void setMaxAttempts(long maxAttempts) {
079                this.maxAttempts = maxAttempts;
080        }
081
082        /**
083         * Return the maximum number of attempts in milliseconds.
084         */
085        public long getMaxAttempts() {
086                return maxAttempts;
087        }
088
089        @Override
090        public BackOffExecution start() {
091                return new FixedBackOffExecution();
092        }
093
094
095        private class FixedBackOffExecution implements BackOffExecution {
096
097                private long currentAttempts = 0;
098
099                @Override
100                public long nextBackOff() {
101                        this.currentAttempts++;
102                        if (this.currentAttempts <= getMaxAttempts()) {
103                                return getInterval();
104                        }
105                        else {
106                                return STOP;
107                        }
108                }
109
110                @Override
111                public String toString() {
112                        final StringBuilder sb = new StringBuilder("FixedBackOff{");
113                        sb.append("interval=").append(FixedBackOff.this.interval);
114                        String attemptValue = (FixedBackOff.this.maxAttempts == Long.MAX_VALUE ?
115                                        "unlimited" : String.valueOf(FixedBackOff.this.maxAttempts));
116                        sb.append(", currentAttempts=").append(this.currentAttempts);
117                        sb.append(", maxAttempts=").append(attemptValue);
118                        sb.append('}');
119                        return sb.toString();
120                }
121        }
122
123}