EMMA Coverage Report (generated Thu Jan 24 13:37:04 CST 2013)
[all classes][org.springframework.batch.retry.backoff]

COVERAGE SUMMARY FOR SOURCE FILE [ExponentialBackOffPolicy.java]

nameclass, %method, %block, %line, %
ExponentialBackOffPolicy.java100% (2/2)77%  (10/13)89%  (132/148)86%  (30/35)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ExponentialBackOffPolicy100% (1/1)73%  (8/11)86%  (97/113)80%  (20/25)
getInitialInterval (): long 0%   (0/1)0%   (0/3)0%   (0/1)
getMaxInterval (): long 0%   (0/1)0%   (0/3)0%   (0/1)
getMultiplier (): double 0%   (0/1)0%   (0/3)0%   (0/1)
backOff (BackOffContext): void 100% (1/1)59%  (10/17)67%  (4/6)
ExponentialBackOffPolicy (): void 100% (1/1)100% (17/17)100% (6/6)
setInitialInterval (long): void 100% (1/1)100% (10/10)100% (2/2)
setMaxInterval (long): void 100% (1/1)100% (10/10)100% (2/2)
setMultiplier (double): void 100% (1/1)100% (10/10)100% (2/2)
setSleeper (Sleeper): void 100% (1/1)100% (4/4)100% (2/2)
start (RetryContext): BackOffContext 100% (1/1)100% (10/10)100% (1/1)
toString (): String 100% (1/1)100% (26/26)100% (1/1)
     
class ExponentialBackOffPolicy$ExponentialBackOffContext100% (1/1)100% (2/2)100% (35/35)100% (10/10)
ExponentialBackOffPolicy$ExponentialBackOffContext (long, double, long): void 100% (1/1)100% (12/12)100% (5/5)
getSleepAndIncrement (): long 100% (1/1)100% (23/23)100% (5/5)

1/*
2 * Copyright 2006-2007 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 
17package org.springframework.batch.retry.backoff;
18 
19import org.springframework.batch.retry.RetryContext;
20import org.springframework.util.ClassUtils;
21 
22/**
23 * Implementation of {@link BackOffPolicy} that increases the back off period
24 * for each retry attempt in a given set using the {@link Math#exp(double)
25 * exponential} function.
26 * <p/>
27 * This implementation is thread-safe and suitable for concurrent access.
28 * Modifications to the configuration do not affect any retry sets that are
29 * already in progress.
30 * <p/>
31 * The {@link #setInitialInterval(long)} property controls the initial value
32 * passed to {@link Math#exp(double)} and the {@link #setMultiplier(double)}
33 * property controls by how much this value is increased for each subsequent
34 * attempt.
35 * 
36 * @author Rob Harrop
37 * @author Dave Syer
38 */
39public class ExponentialBackOffPolicy implements BackOffPolicy {
40 
41        /**
42         * The default 'initialInterval' value - 100 millisecs. Coupled with the
43         * default 'multiplier' value this gives a useful initial spread of pauses
44         * for 1-5 retries.
45         */
46        public static final long DEFAULT_INITIAL_INTERVAL = 100L;
47 
48        /**
49         * The default maximum backoff time (30 seconds).
50         */
51        public static final long DEFAULT_MAX_INTERVAL = 30000L;
52 
53        /**
54         * The default 'multiplier' value - value 2 (100% increase per backoff).
55         */
56        public static final double DEFAULT_MULTIPLIER = 2;
57 
58        /**
59         * The initial sleep interval.
60         */
61        private volatile long initialInterval = DEFAULT_INITIAL_INTERVAL;
62 
63        /**
64         * The maximum value of the backoff period in milliseconds.
65         */
66        private volatile long maxInterval = DEFAULT_MAX_INTERVAL;
67 
68        /**
69         * The value to increment the exp seed with for each retry attempt.
70         */
71        private volatile double multiplier = DEFAULT_MULTIPLIER;
72 
73        private Sleeper sleeper = new ObjectWaitSleeper();
74 
75        /**
76         * Public setter for the {@link Sleeper} strategy.
77         * @param sleeper the sleeper to set defaults to {@link ObjectWaitSleeper}.
78         */
79        public void setSleeper(Sleeper sleeper) {
80                this.sleeper = sleeper;
81        }
82 
83        /**
84         * Set the initial sleep interval value. Default is <code>100</code>
85         * millisecond. Cannot be set to a value less than one.
86         */
87        public void setInitialInterval(long initialInterval) {
88                this.initialInterval = (initialInterval > 1 ? initialInterval : 1);
89        }
90 
91        /**
92         * Set the multiplier value. Default is '<code>2.0</code>'. Hint: do not use
93         * values much in excess of 1.0 (or the backoff will get very long very
94         * fast).
95         */
96        public void setMultiplier(double multiplier) {
97                this.multiplier = (multiplier > 1.0 ? multiplier : 1.0);
98        }
99 
100        /**
101         * Setter for maximum back off period. Default is 30000 (30 seconds). the
102         * value will be reset to 1 if this method is called with a value less than
103         * 1. Set this to avoid infinite waits if backing off a large number of
104         * times (or if the multiplier is set too high).
105         * 
106         * @param maxInterval in milliseconds.
107         */
108        public void setMaxInterval(long maxInterval) {
109                this.maxInterval = maxInterval > 0 ? maxInterval : 1;
110        }
111 
112        /**
113         * The initial period to sleep on the first backoff.
114         * @return the initial interval
115         */
116        public long getInitialInterval() {
117                return initialInterval;
118        }
119 
120        /**
121         * The maximum interval to sleep for. Defaults to 30 seconds.
122         * 
123         * @return the maximum interval.
124         */
125        public long getMaxInterval() {
126                return maxInterval;
127        }
128 
129        /**
130         * The multiplier to use to generate the next backoff interval from the
131         * last.
132         * 
133         * @return the multiplier in use
134         */
135        public double getMultiplier() {
136                return multiplier;
137        }
138 
139        /**
140         * Returns a new instance of {@link BackOffContext} configured with the
141         * 'expSeed' and 'increment' values.
142         */
143        public BackOffContext start(RetryContext context) {
144                return new ExponentialBackOffContext(this.initialInterval, this.multiplier, this.maxInterval);
145        }
146 
147        /**
148         * Pause for a length of time equal to '
149         * <code>exp(backOffContext.expSeed)</code>'.
150         */
151        public void backOff(BackOffContext backOffContext) throws BackOffInterruptedException {
152                ExponentialBackOffContext context = (ExponentialBackOffContext) backOffContext;
153                try {
154                        sleeper.sleep(context.getSleepAndIncrement());
155                }
156                catch (InterruptedException e) {
157                        throw new BackOffInterruptedException("Thread interrupted while sleeping", e);
158                }
159        }
160 
161        private static class ExponentialBackOffContext implements BackOffContext {
162 
163                private final double multiplier;
164 
165                private long interval;
166 
167                private long maxInterval;
168 
169                public ExponentialBackOffContext(long expSeed, double multiplier, long maxInterval) {
170                        this.interval = expSeed;
171                        this.multiplier = multiplier;
172                        this.maxInterval = maxInterval;
173                }
174 
175                public synchronized long getSleepAndIncrement() {
176                        long sleep = this.interval;
177                        if (sleep > maxInterval) {
178                                sleep = (long) maxInterval;
179                        }
180                        else {
181                                this.interval *= this.multiplier;
182                        }
183                        return sleep;
184                }
185        }
186 
187        public String toString() {
188                return ClassUtils.getShortName(getClass()) + "[initialInterval=" + initialInterval + ", multiplier="
189                                + multiplier + ", maxInterval=" + maxInterval + "]";
190        }
191 
192}

[all classes][org.springframework.batch.retry.backoff]
EMMA 2.0.5312 (C) Vladimir Roubtsov