001/*
002 * Copyright (C) 2006 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
005 * in compliance with the License. You may obtain a copy of the License at
006 *
007 * http://www.apache.org/licenses/LICENSE-2.0
008 *
009 * Unless required by applicable law or agreed to in writing, software distributed under the License
010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
011 * or implied. See the License for the specific language governing permissions and limitations under
012 * the License.
013 */
014
015package com.google.common.util.concurrent;
016
017import static com.google.common.base.Preconditions.checkNotNull;
018import static com.google.common.util.concurrent.Platform.restoreInterruptIfIsInterruptedException;
019
020import com.google.common.annotations.GwtIncompatible;
021import com.google.common.annotations.J2ktIncompatible;
022import com.google.errorprone.annotations.CanIgnoreReturnValue;
023import java.util.concurrent.Callable;
024import java.util.concurrent.ExecutionException;
025import java.util.concurrent.TimeUnit;
026import org.jspecify.annotations.Nullable;
027
028/**
029 * A TimeLimiter implementation which actually does not attempt to limit time at all. This may be
030 * desirable to use in some unit tests. More importantly, attempting to debug a call which is
031 * time-limited would be extremely annoying, so this gives you a time-limiter you can easily swap in
032 * for your real time-limiter while you're debugging.
033 *
034 * @author Kevin Bourrillion
035 * @author Jens Nyman
036 * @since 1.0
037 */
038@J2ktIncompatible
039@GwtIncompatible
040public final class FakeTimeLimiter implements TimeLimiter {
041  /** Creates a new {@link FakeTimeLimiter}. */
042  public FakeTimeLimiter() {}
043
044  @CanIgnoreReturnValue // TODO(kak): consider removing this
045  @Override
046  public <T> T newProxy(
047      T target, Class<T> interfaceType, long timeoutDuration, TimeUnit timeoutUnit) {
048    checkNotNull(target);
049    checkNotNull(interfaceType);
050    checkNotNull(timeoutUnit);
051    return target; // ha ha
052  }
053
054  @CanIgnoreReturnValue // TODO(kak): consider removing this
055  @Override
056  @ParametricNullness
057  public <T extends @Nullable Object> T callWithTimeout(
058      Callable<T> callable, long timeoutDuration, TimeUnit timeoutUnit) throws ExecutionException {
059    checkNotNull(callable);
060    checkNotNull(timeoutUnit);
061    try {
062      return callable.call();
063    } catch (RuntimeException e) {
064      throw new UncheckedExecutionException(e);
065    } catch (Exception e) {
066      restoreInterruptIfIsInterruptedException(e);
067      throw new ExecutionException(e);
068    } catch (Error e) {
069      throw new ExecutionError(e);
070    }
071  }
072
073  @CanIgnoreReturnValue // TODO(kak): consider removing this
074  @Override
075  @ParametricNullness
076  public <T extends @Nullable Object> T callUninterruptiblyWithTimeout(
077      Callable<T> callable, long timeoutDuration, TimeUnit timeoutUnit) throws ExecutionException {
078    return callWithTimeout(callable, timeoutDuration, timeoutUnit);
079  }
080
081  @Override
082  @SuppressWarnings("CatchingUnchecked") // sneaky checked exception
083  public void runWithTimeout(Runnable runnable, long timeoutDuration, TimeUnit timeoutUnit) {
084    checkNotNull(runnable);
085    checkNotNull(timeoutUnit);
086    try {
087      runnable.run();
088    } catch (Exception e) { // sneaky checked exception
089      throw new UncheckedExecutionException(e);
090    } catch (Error e) {
091      throw new ExecutionError(e);
092    }
093  }
094
095  @Override
096  public void runUninterruptiblyWithTimeout(
097      Runnable runnable, long timeoutDuration, TimeUnit timeoutUnit) {
098    runWithTimeout(runnable, timeoutDuration, timeoutUnit);
099  }
100}