001/*
002 * Copyright (C) 2006 The Guava 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 * http://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 com.google.common.util.concurrent;
018
019import com.google.common.annotations.Beta;
020
021import java.util.concurrent.Callable;
022import java.util.concurrent.TimeUnit;
023
024/**
025 * Produces proxies that impose a time limit on method
026 * calls to the proxied object.  For example, to return the value of
027 * {@code target.someMethod()}, but substitute {@code DEFAULT_VALUE} if this
028 * method call takes over 50 ms, you can use this code:
029 * <pre>
030 *   TimeLimiter limiter = . . .;
031 *   TargetType proxy = limiter.newProxy(
032 *       target, TargetType.class, 50, TimeUnit.MILLISECONDS);
033 *   try {
034 *     return proxy.someMethod();
035 *   } catch (UncheckedTimeoutException e) {
036 *     return DEFAULT_VALUE;
037 *   }
038 * </pre>
039 * <p>Please see {@code SimpleTimeLimiterTest} for more usage examples.
040 *
041 * @author Kevin Bourrillion
042 * @since 1.0
043 */
044@Beta
045public interface TimeLimiter {
046
047  /**
048   * Returns an instance of {@code interfaceType} that delegates all method
049   * calls to the {@code target} object, enforcing the specified time limit on
050   * each call.  This time-limited delegation is also performed for calls to
051   * {@link Object#equals}, {@link Object#hashCode}, and
052   * {@link Object#toString}.
053   * <p>
054   * If the target method call finishes before the limit is reached, the return
055   * value or exception is propagated to the caller exactly as-is. If, on the
056   * other hand, the time limit is reached, the proxy will attempt to abort the
057   * call to the target, and will throw an {@link UncheckedTimeoutException} to
058   * the caller.
059   * <p>
060   * It is important to note that the primary purpose of the proxy object is to
061   * return control to the caller when the timeout elapses; aborting the target
062   * method call is of secondary concern.  The particular nature and strength
063   * of the guarantees made by the proxy is implementation-dependent.  However,
064   * it is important that each of the methods on the target object behaves
065   * appropriately when its thread is interrupted.
066   *
067   * @param target the object to proxy
068   * @param interfaceType the interface you wish the returned proxy to
069   *     implement
070   * @param timeoutDuration with timeoutUnit, the maximum length of time that
071   *     callers are willing to wait on each method call to the proxy
072   * @param timeoutUnit with timeoutDuration, the maximum length of time that
073   *     callers are willing to wait on each method call to the proxy
074   * @return a time-limiting proxy
075   * @throws IllegalArgumentException if {@code interfaceType} is a regular
076   *     class, enum, or annotation type, rather than an interface
077   */
078  <T> T newProxy(T target, Class<T> interfaceType,
079      long timeoutDuration, TimeUnit timeoutUnit);
080
081  /**
082   * Invokes a specified Callable, timing out after the specified time limit.
083   * If the target method call finished before the limit is reached, the return
084   * value or exception is propagated to the caller exactly as-is.  If, on the
085   * other hand, the time limit is reached, we attempt to abort the call to the
086   * target, and throw an {@link UncheckedTimeoutException} to the caller.
087   * <p>
088   * <b>Warning:</b> The future of this method is in doubt.  It may be nuked, or
089   * changed significantly.
090   *
091   * @param callable the Callable to execute
092   * @param timeoutDuration with timeoutUnit, the maximum length of time to wait
093   * @param timeoutUnit with timeoutDuration, the maximum length of time to wait
094   * @param interruptible whether to respond to thread interruption by aborting
095   *     the operation and throwing InterruptedException; if false, the
096   *     operation is allowed to complete or time out, and the current thread's
097   *     interrupt status is re-asserted.
098   * @return the result returned by the Callable
099   * @throws InterruptedException if {@code interruptible} is true and our
100   *     thread is interrupted during execution
101   * @throws UncheckedTimeoutException if the time limit is reached
102   * @throws Exception
103   */
104  <T> T callWithTimeout(Callable<T> callable, long timeoutDuration,
105      TimeUnit timeoutUnit, boolean interruptible) throws Exception;
106}