View Javadoc

1   /*
2      Copyright 2010 Atlassian
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  package io.atlassian.fugue.retry;
17  
18  import java.util.function.Function;
19  import java.util.function.Supplier;
20  
21  /**
22   * Provides factory methods for RetryFunction, RetryTask, and RetrySupplier.
23   * These classes can be used when a task is known to fail on occasion and no
24   * other workaround is known.
25   *
26   * This class is not instantiable.
27   *
28   */
29  public class RetryFactory {
30    private RetryFactory() {
31      throw new AssertionError("This class is non-instantiable.");
32    }
33  
34    /**
35     * Decorates a runnable so that it retries a number of times before being
36     * allowed to fail.
37     *
38     * @param task which will be wrapped for retrial. It should be idempotent on
39     * failure.
40     * @param tries the number of times to re-attempt the call
41     * @return a runnable which can be used to call another runnable multiple
42     * times when that runnable may fail sporadically
43     */
44    public static Runnable create(Runnable task, int tries) {
45      return create(task, tries, ExceptionHandlers.ignoreExceptionHandler());
46    }
47  
48    /**
49     * Decorates a runnable so that it retries a number of times before being
50     * allowed to fail.
51     *
52     * @param task which will be wrapped for retrial. It should be idempotent on
53     * failure.
54     * @param tries the number of times to re-attempt the call
55     * @param handler passed any exceptions that are encountered
56     * @return a runnable which can be used to call another runnable multiple
57     * times when that runnable may fail sporadically
58     */
59    public static Runnable create(Runnable task, int tries, ExceptionHandler handler) {
60      return new RetryTask(task, tries, handler);
61    }
62  
63    /**
64     * Decorates a runnable so that it retries a number of times before being
65     * allowed to fail, backing off exponentially in time.
66     *
67     * @param task which will be wrapped for retrial. It should be idempotent on
68     * failure.
69     * @param tries the number of times to re-attempt the call
70     * @param handler which acts on exceptions thrown by the wrapped supplier
71     * @param backoff time to wait in millis each time
72     * @return a runnable which can be used to call another runnable multiple
73     * times when that runnable may fail sporadically
74     */
75    public static Runnable create(Runnable task, int tries, ExceptionHandler handler, long backoff) {
76      return new RetryTask(task, tries, handler, new BeforeRetryExponentialBackoffTask(backoff));
77    }
78  
79    /**
80     * Decorates a supplier so that it retries a number of times before being
81     * allowed to fail.
82     *
83     * @param supplier which will be wrapped for retrial. It should be idempotent
84     * on failure.
85     * @param tries the number of times to re-attempt the call
86     * @param <A> The type of the object returned by supplier
87     * @return a supplier which can be used to call another supplier multiple
88     * times when that supplier may fail sporadically
89     */
90    public static <A> Supplier<A> create(Supplier<A> supplier, int tries) {
91      return create(supplier, tries, ExceptionHandlers.ignoreExceptionHandler());
92    }
93  
94    /**
95     * Decorates a supplier so that it retries a number of times before being
96     * allowed to fail.
97     *
98     * @param supplier which will be wrapped for retrial. It should be idempotent
99     * on failure.
100    * @param tries the number of times to re-attempt the call
101    * @param <A> The type of the object returned by supplier
102    * @param handler which acts on exceptions thrown by the wrapped supplier
103    * @return a supplier which can be used to call another supplier multiple
104    * times when that supplier may fail sporadically
105    */
106   public static <A> Supplier<A> create(Supplier<A> supplier, int tries, ExceptionHandler handler) {
107     return new RetrySupplier<>(supplier, tries, handler);
108   }
109 
110   /**
111    * Decorates a supplier so that it retries a number of times before being
112    * allowed to fail, backing-off in time exponentially.
113    *
114    * @param <A> The type of the object returned by supplier
115    * @param supplier which will be wrapped for retrial. It should be idempotent
116    * on failure.
117    * @param tries the number of times to re-attempt the call
118    * @param handler which acts on exceptions thrown by the wrapped supplier
119    * @param backoff time to wait in millis each time
120    * @return a supplier which can be used to call another supplier multiple
121    * times when that supplier may fail sporadically
122    */
123   public static <A> Supplier<A> create(Supplier<A> supplier, int tries, ExceptionHandler handler, long backoff) {
124     return new RetrySupplier<>(supplier, tries, handler, new BeforeRetryExponentialBackoffTask(backoff));
125   }
126 
127   /**
128    * Decorates a function so that it retries a number of times before being
129    * allowed to fail.
130    *
131    * @param <A> the type of the parameter the function accepts
132    * @param <B> the type of the result of the function's apply method
133    * @param function which will be wrapped for retrial. It should be idempotent
134    * on failure.
135    * @param tries the number of times to re-attempt the call
136    * @return a function which can be used to invoke another function multiple
137    * times when that function may fail sporadically
138    */
139   public static <A, B> Function<A, B> create(Function<A, B> function, int tries) {
140     return create(function, tries, ExceptionHandlers.ignoreExceptionHandler());
141   }
142 
143   /**
144    * Decorates a function so that it retries a number of times before being
145    * allowed to fail.
146    *
147    * @param <A> the type of the parameter the function accepts
148    * @param <B> the type of the result of the function's apply method
149    * @param function which will be wrapped for retrial. It should be idempotent
150    * on failure.
151    * @param tries the number of times to re-attempt the call
152    * @param handler which acts on exceptions thrown by the wrapped supplier
153    * @return a function which can be used to invoke another function multiple
154    * times when that function may fail sporadically
155    */
156   public static <A, B> Function<A, B> create(Function<A, B> function, int tries, ExceptionHandler handler) {
157     return create(function, tries, handler, 0);
158   }
159 
160   /**
161    * Decorates a function so that it retries a number of times before being
162    * allowed to fail.
163    *
164    * @param function which will be wrapped for retrial. It should be idempotent
165    * on failure.
166    * @param tries the number of times to re-attempt the call
167    * @param <A> the type of the parameter the function accepts
168    * @param <B> the type of the result of the function's apply method
169    * @param handler which acts on exceptions thrown by the wrapped supplier
170    * @param backoff time to wait in millis each time
171    * @return a function which can be used to invoke another function multiple
172    * times when that function may fail sporadically
173    */
174   public static <A, B> Function<A, B> create(Function<A, B> function, int tries, ExceptionHandler handler, long backoff) {
175     return new RetryFunction<>(function, tries, handler, new BeforeRetryExponentialBackoffTask(backoff));
176   }
177 }