/* * Copyright 2014 WANdisco * * WANdisco licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package c5db.util; import com.google.common.util.concurrent.ListenableFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /** * An executor service which accepts tasks (suppliers of some result) each with an associated * string key, and guarantees that all tasks associated with a given key will be run serially, * in the order they are submitted. No guarantee is made about the relative completion order * of tasks associated with different keys. * <p> * The notion of a well-defined "order in which tasks are submitted" requires that tasks with * the same key be submitted in a deterministic order, e.g., unaffected by thread scheduling. * <p> * The purpose is so a single thread pool can handle IO requests for, potentially, several * different logs: the requests for each individual log need to be serialized with other * requests for that same log, and the "key" in that situation is some string that uniquely * identifies that log. However, in such a situation, IO requests for one log can be freely * interspersed with requests for another. */ public interface KeySerializingExecutor { /** * Submit a task for execution. * * @param key Key associated with the task; the task will not be executed until all previously-submitted * tasks with the same key have finished execution. * @param task A supplier of some result, which may throw an exception. * @param <T> The type of the result produced by the task. * @return A future which will produce the result of the task, or else an exception. */ <T> ListenableFuture<T> submit(String key, CheckedSupplier<T, Exception> task); /** * Shut down the executor. After calling this method, any call to submit will result in an exception. This * method will block until all previously submitted tasks complete, or until the specified time limit * expires, in which case a TimeoutException will be thrown. * * @param timeout Time to wait for previously submitted tasks to complete * @param unit Time unit associated with timeout. */ void shutdownAndAwaitTermination(long timeout, TimeUnit unit) throws InterruptedException, TimeoutException; }