All Downloads are FREE. Search and download functionalities are using the official Maven repository.

co.cask.tephra.TransactionExecutor Maven / Gradle / Ivy

/*
 * Copyright © 2012-2014 Cask Data, Inc.
 *
 * Licensed 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 co.cask.tephra;

import com.google.common.util.concurrent.ListenableFuture;

import java.util.concurrent.Callable;

/**
 * Utility that wraps the execution of a function into the context of a transaction.
 */
// todo: implementations should throw different from TransactionFailureException in case of user code error?
// todo: accept only Callable? Executors util has a way to convert everything to Callable...
public interface TransactionExecutor {

  /**
   * A function is a class with a single method that takes an argument and returns a result.
   * @param  the type of the argument
   * @param  the type of the result
   */
  public interface Function {
    O apply(I input) throws Exception;
  }

  /**
   * A procedure is a class with a single void method that takes an argument.
   * @param  the type of the argument
   */
  public interface Procedure {
    void apply(I input) throws Exception;
  }

  /**
   * A subroutine is a class with a single void method without arguments.
   */
  public interface Subroutine {
    void apply() throws Exception;
  }

  // Due to a bug in checkstyle, it would emit false positives here of the form
  // "Unable to get class information for @throws tag '' (...)".
  // This comment disables that check up to the corresponding ON comments below

  // CHECKSTYLE OFF: @throws

  /**
   * Execute a function under transactional semantics. A transaction is started  and all datasets
   * are initialized with the transaction. Then the passed function is executed, the transaction
   * is committed, and the function return value is returned as the return value of this method.
   * If any exception is caught, the transaction is aborted and the original exception is rethrown,
   * wrapped into a TransactionFailureException. If the transaction fails due to a write conflict,
   * a TransactionConflictException is thrown.
   * @param function the function to execute
   * @param input the input parameter for the function
   * @param  the input type of the function
   * @param  the result type of the function
   * @return the function's return value
   * @throws TransactionConflictException if there is a write conflict with another transaction.
   * @throws TransactionFailureException if any exception is caught, be it from the function or from the datasets.
   */
   O execute(Function function, I input) throws TransactionFailureException, InterruptedException;

  // CHECKSTYLE ON

  /**
   * Like {@link #execute(Function, Object)} but without a return value.
   */
   void execute(Procedure procedure, I input) throws TransactionFailureException, InterruptedException;

  /**
   * Like {@link #execute(Function, Object)} but the callable has no argument.
   */
   O execute(Callable callable) throws TransactionFailureException, InterruptedException;

  /**
   * Like {@link #execute(Function, Object)} but without argument or return value.
   */
  void execute(Subroutine subroutine) throws TransactionFailureException, InterruptedException;

  /**
   * Same as {@link #execute(Function, Object)} but
   * suppresses exception with {@link com.google.common.base.Throwables#propagate(Throwable)}
   */
   O executeUnchecked(Function function, I input);

  /**
   * Same as {@link #execute(Procedure, Object)} but
   * suppresses exception with {@link com.google.common.base.Throwables#propagate(Throwable)}
   */
   void executeUnchecked(Procedure procedure, I input);

  /**
   * Same as {@link #execute(Callable)} but
   * suppresses exception with {@link com.google.common.base.Throwables#propagate(Throwable)}
   */
   O executeUnchecked(Callable callable);

  /**
   * Same as {@link #execute(Subroutine)} but
   * suppresses exception with {@link com.google.common.base.Throwables#propagate(Throwable)}
   */
  void executeUnchecked(Subroutine subroutine);

  /**
   * Same as {@link #execute(Function, Object)} but executes asynchronously
   */
   ListenableFuture submit(Function function, I input);

  /**
   * Same as {@link #execute(Procedure, Object)} but executes asynchronously
   */
   ListenableFuture submit(Procedure procedure, I input);

  /**
   * Same as {@link #execute(Callable)} but executes asynchronously
   */
   ListenableFuture submit(Callable callable);

  /**
   * Same as {@link #execute(Subroutine)} but executes asynchronously
   */
  ListenableFuture submit(Subroutine subroutine);

}