View Javadoc
1   /*
2    * Copyright (C) 2006 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5    * in compliance with the License. You may obtain a copy of the License at
6    *
7    * http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software distributed under the License
10   * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11   * or implied. See the License for the specific language governing permissions and limitations under
12   * the License.
13   */
14  
15  package com.google.common.util.concurrent;
16  
17  import com.google.common.annotations.Beta;
18  import com.google.common.annotations.GwtIncompatible;
19  import java.util.concurrent.Callable;
20  import java.util.concurrent.ExecutionException;
21  import java.util.concurrent.TimeUnit;
22  import java.util.concurrent.TimeoutException;
23  
24  /**
25   * Imposes a time limit on method calls.
26   *
27   * @author Kevin Bourrillion
28   * @author Jens Nyman
29   * @since 1.0
30   */
31  @Beta
32  @GwtIncompatible
33  public interface TimeLimiter {
34  
35    /**
36     * Returns an instance of {@code interfaceType} that delegates all method calls to the
37     * {@code target} object, enforcing the specified time limit on each call. This time-limited
38     * delegation is also performed for calls to {@link Object#equals}, {@link Object#hashCode}, and
39     * {@link Object#toString}.
40     *
41     * <p>If the target method call finishes before the limit is reached, the return value or
42     * exception is propagated to the caller exactly as-is. If, on the other hand, the time limit is
43     * reached, the proxy will attempt to abort the call to the target, and will throw an
44     * {@link UncheckedTimeoutException} to the caller.
45     *
46     * <p>It is important to note that the primary purpose of the proxy object is to return control to
47     * the caller when the timeout elapses; aborting the target method call is of secondary concern.
48     * The particular nature and strength of the guarantees made by the proxy is
49     * implementation-dependent. However, it is important that each of the methods on the target
50     * object behaves appropriately when its thread is interrupted.
51     *
52     * <p>For example, to return the value of {@code target.someMethod()}, but substitute {@code
53     * DEFAULT_VALUE} if this method call takes over 50 ms, you can use this code:
54     *
55     * <pre>
56     *   TimeLimiter limiter = . . .;
57     *   TargetType proxy = limiter.newProxy(
58     *       target, TargetType.class, 50, TimeUnit.MILLISECONDS);
59     *   try {
60     *     return proxy.someMethod();
61     *   } catch (UncheckedTimeoutException e) {
62     *     return DEFAULT_VALUE;
63     *   }
64     * </pre>
65     *
66     * @param target the object to proxy
67     * @param interfaceType the interface you wish the returned proxy to implement
68     * @param timeoutDuration with timeoutUnit, the maximum length of time that callers are willing to
69     *     wait on each method call to the proxy
70     * @param timeoutUnit with timeoutDuration, the maximum length of time that callers are willing to
71     *     wait on each method call to the proxy
72     * @return a time-limiting proxy
73     * @throws IllegalArgumentException if {@code interfaceType} is a regular class, enum, or
74     *     annotation type, rather than an interface
75     */
76    <T> T newProxy(T target, Class<T> interfaceType, long timeoutDuration, TimeUnit timeoutUnit);
77  
78    /**
79     * Invokes a specified Callable, timing out after the specified time limit. If the target method
80     * call finishes before the limit is reached, the return value or a wrapped exception is
81     * propagated. If, on the other hand, the time limit is reached, we attempt to abort the call to
82     * the target, and throw a {@link TimeoutException} to the caller.
83     *
84     * @param callable the Callable to execute
85     * @param timeoutDuration with timeoutUnit, the maximum length of time to wait
86     * @param timeoutUnit with timeoutDuration, the maximum length of time to wait
87     * @return the result returned by the Callable
88     * @throws TimeoutException if the time limit is reached
89     * @throws InterruptedException if the current thread was interrupted during execution
90     * @throws ExecutionException if {@code callable} throws a checked exception
91     * @throws UncheckedExecutionException if {@code callable} throws a {@code RuntimeException}
92     * @throws ExecutionError if {@code callable} throws an {@code Error}
93     * @since 22.0
94     */
95    <T> T callWithTimeout(Callable<T> callable, long timeoutDuration, TimeUnit timeoutUnit)
96        throws TimeoutException, InterruptedException, ExecutionException;
97  
98    /**
99     * Invokes a specified Callable, timing out after the specified time limit. If the target method
100    * call finishes before the limit is reached, the return value or a wrapped exception is
101    * propagated. If, on the other hand, the time limit is reached, we attempt to abort the call to
102    * the target, and throw a {@link TimeoutException} to the caller.
103    *
104    * <p>The difference with {@link #callWithTimeout(Callable, long, TimeUnit)} is that this method
105    * will ignore interrupts on the current thread.
106    *
107    * @param callable the Callable to execute
108    * @param timeoutDuration with timeoutUnit, the maximum length of time to wait
109    * @param timeoutUnit with timeoutDuration, the maximum length of time to wait
110    * @return the result returned by the Callable
111    * @throws TimeoutException if the time limit is reached
112    * @throws ExecutionException if {@code callable} throws a checked exception
113    * @throws UncheckedExecutionException if {@code callable} throws a {@code RuntimeException}
114    * @throws ExecutionError if {@code callable} throws an {@code Error}
115    * @since 22.0
116    */
117   <T> T callUninterruptiblyWithTimeout(
118       Callable<T> callable, long timeoutDuration, TimeUnit timeoutUnit)
119       throws TimeoutException, ExecutionException;
120 
121   /**
122    * Invokes a specified Runnable, timing out after the specified time limit. If the target method
123    * run finishes before the limit is reached, this method returns or a wrapped exception is
124    * propagated. If, on the other hand, the time limit is reached, we attempt to abort the run, and
125    * throw a {@link TimeoutException} to the caller.
126    *
127    * @param runnable the Runnable to execute
128    * @param timeoutDuration with timeoutUnit, the maximum length of time to wait
129    * @param timeoutUnit with timeoutDuration, the maximum length of time to wait
130    * @throws TimeoutException if the time limit is reached
131    * @throws InterruptedException if the current thread was interrupted during execution
132    * @throws UncheckedExecutionException if {@code runnable} throws a {@code RuntimeException}
133    * @throws ExecutionError if {@code runnable} throws an {@code Error}
134    * @since 22.0
135    */
136   void runWithTimeout(Runnable runnable, long timeoutDuration, TimeUnit timeoutUnit)
137       throws TimeoutException, InterruptedException;
138 
139   /**
140    * Invokes a specified Runnable, timing out after the specified time limit. If the target method
141    * run finishes before the limit is reached, this method returns or a wrapped exception is
142    * propagated. If, on the other hand, the time limit is reached, we attempt to abort the run, and
143    * throw a {@link TimeoutException} to the caller.
144    *
145    * <p>The difference with {@link #runWithTimeout(Runnable, long, TimeUnit)} is that this method
146    * will ignore interrupts on the current thread.
147    *
148    * @param runnable the Runnable to execute
149    * @param timeoutDuration with timeoutUnit, the maximum length of time to wait
150    * @param timeoutUnit with timeoutDuration, the maximum length of time to wait
151    * @throws TimeoutException if the time limit is reached
152    * @throws UncheckedExecutionException if {@code runnable} throws a {@code RuntimeException}
153    * @throws ExecutionError if {@code runnable} throws an {@code Error}
154    * @since 22.0
155    */
156   void runUninterruptiblyWithTimeout(Runnable runnable, long timeoutDuration, TimeUnit timeoutUnit)
157       throws TimeoutException;
158 }