001/*
002 * Copyright (C) 2010 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.util.concurrent.Internal.toNanosSaturated;
018
019import com.google.common.annotations.GwtIncompatible;
020import com.google.common.annotations.J2ktIncompatible;
021import com.google.errorprone.annotations.DoNotMock;
022import java.time.Duration;
023import java.util.Collection;
024import java.util.List;
025import java.util.concurrent.Callable;
026import java.util.concurrent.ExecutionException;
027import java.util.concurrent.ExecutorService;
028import java.util.concurrent.Future;
029import java.util.concurrent.RejectedExecutionException;
030import java.util.concurrent.TimeUnit;
031import java.util.concurrent.TimeoutException;
032import org.jspecify.annotations.Nullable;
033
034/**
035 * An {@link ExecutorService} that returns {@link ListenableFuture} instances. To create an instance
036 * from an existing {@link ExecutorService}, call {@link
037 * MoreExecutors#listeningDecorator(ExecutorService)}.
038 *
039 * @author Chris Povirk
040 * @since 10.0
041 */
042@DoNotMock(
043    "Use TestingExecutors.sameThreadScheduledExecutor, or wrap a real Executor from "
044        + "java.util.concurrent.Executors with MoreExecutors.listeningDecorator")
045@GwtIncompatible
046public interface ListeningExecutorService extends ExecutorService {
047  /**
048   * @return a {@code ListenableFuture} representing pending completion of the task
049   * @throws RejectedExecutionException {@inheritDoc}
050   */
051  @Override
052  <T extends @Nullable Object> ListenableFuture<T> submit(Callable<T> task);
053
054  /**
055   * @return a {@code ListenableFuture} representing pending completion of the task
056   * @throws RejectedExecutionException {@inheritDoc}
057   */
058  @Override
059  ListenableFuture<?> submit(Runnable task);
060
061  /**
062   * @return a {@code ListenableFuture} representing pending completion of the task
063   * @throws RejectedExecutionException {@inheritDoc}
064   */
065  @Override
066  <T extends @Nullable Object> ListenableFuture<T> submit(
067      Runnable task, @ParametricNullness T result);
068
069  /**
070   * {@inheritDoc}
071   *
072   * <p>All elements in the returned list must be {@link ListenableFuture} instances. The easiest
073   * way to obtain a {@code List<ListenableFuture<T>>} from this method is an unchecked (but safe)
074   * cast:
075   *
076   * <pre>
077   *   {@code @SuppressWarnings("unchecked") // guaranteed by invokeAll contract}
078   *   {@code List<ListenableFuture<T>> futures = (List) executor.invokeAll(tasks);}
079   * </pre>
080   *
081   * @return A list of {@code ListenableFuture} instances representing the tasks, in the same
082   *     sequential order as produced by the iterator for the given task list, each of which has
083   *     completed.
084   * @throws RejectedExecutionException {@inheritDoc}
085   * @throws NullPointerException if any task is null
086   */
087  @Override
088  <T extends @Nullable Object> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
089      throws InterruptedException;
090
091  /**
092   * {@inheritDoc}
093   *
094   * <p>All elements in the returned list must be {@link ListenableFuture} instances. The easiest
095   * way to obtain a {@code List<ListenableFuture<T>>} from this method is an unchecked (but safe)
096   * cast:
097   *
098   * <pre>
099   *   {@code @SuppressWarnings("unchecked") // guaranteed by invokeAll contract}
100   *   {@code List<ListenableFuture<T>> futures = (List) executor.invokeAll(tasks, timeout, unit);}
101   * </pre>
102   *
103   * @return a list of {@code ListenableFuture} instances representing the tasks, in the same
104   *     sequential order as produced by the iterator for the given task list. If the operation did
105   *     not time out, each task will have completed. If it did time out, some of these tasks will
106   *     not have completed.
107   * @throws RejectedExecutionException {@inheritDoc}
108   * @throws NullPointerException if any task is null
109   */
110  @Override
111  <T extends @Nullable Object> List<Future<T>> invokeAll(
112      Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
113      throws InterruptedException;
114
115  /**
116   * Duration-based overload of {@link #invokeAll(Collection, long, TimeUnit)}.
117   *
118   * @since 32.1.0
119   */
120  @J2ktIncompatible
121  default <T extends @Nullable Object> List<Future<T>> invokeAll(
122      Collection<? extends Callable<T>> tasks, Duration timeout) throws InterruptedException {
123    return invokeAll(tasks, toNanosSaturated(timeout), TimeUnit.NANOSECONDS);
124  }
125
126  /**
127   * Duration-based overload of {@link #invokeAny(Collection, long, TimeUnit)}.
128   *
129   * @since 32.1.0
130   */
131  @J2ktIncompatible
132  default <T extends @Nullable Object> T invokeAny(
133      Collection<? extends Callable<T>> tasks, Duration timeout)
134      throws InterruptedException, ExecutionException, TimeoutException {
135    return invokeAny(tasks, toNanosSaturated(timeout), TimeUnit.NANOSECONDS);
136  }
137
138  /**
139   * Duration-based overload of {@link #awaitTermination(long, TimeUnit)}.
140   *
141   * @since 32.1.0
142   */
143  @J2ktIncompatible
144  default boolean awaitTermination(Duration timeout) throws InterruptedException {
145    return awaitTermination(toNanosSaturated(timeout), TimeUnit.NANOSECONDS);
146  }
147}