Package edu.brown.hstore.callbacks

Source Code of edu.brown.hstore.callbacks.AbstractTransactionCallback

package edu.brown.hstore.callbacks;

import org.apache.log4j.Logger;

import com.google.protobuf.RpcCallback;

import edu.brown.hstore.HStoreSite;
import edu.brown.hstore.Hstoreservice.Status;
import edu.brown.hstore.txns.AbstractTransaction;
import edu.brown.hstore.txns.LocalTransaction;
import edu.brown.logging.LoggerUtil;
import edu.brown.logging.LoggerUtil.LoggerBoolean;

/**
* Special BlockingCallback wrapper for transactions. This class has utility methods for
* identifying when it is safe to delete a transaction handle from our local HStoreSite.
* @author pavlo
* @param <X> The type of AbstractTransaction handle that this callback uses
* @param <T> The message type of the original RpcCallback
* @param <U> The message type that we will accumulate before invoking the original RpcCallback
*/
@Deprecated
public abstract class AbstractTransactionCallback<X extends AbstractTransaction, T, U> extends BlockingRpcCallback<T, U> {
    private static final Logger LOG = Logger.getLogger(AbstractTransactionCallback.class);
    private static final LoggerBoolean debug = new LoggerBoolean();
    private static final LoggerBoolean trace = new LoggerBoolean();
    static {
        LoggerUtil.attachObserver(LOG, debug, trace);
    }
   
    /**
     * The current transaction handle that this callback is assigned to
     */
    protected X ts;
   
    /**
     * This flag is set to true after the unblockCallback() invocation is finished
     * This prevents somebody from checking whether we have invoked the unblock callback
     * but are still in the middle of processing it.
     */
    private boolean unblockFinished = false;
   
    /**
     * This flag is set to true after the abortCallback() invocation is finished
     * This prevents somebody from checking whether we have invoked the abort callback
     * but are still in the middle of processing it.
     */
    private boolean abortFinished = false;
   
    /**
     * Constructor
     * @param hstore_site
     */
    protected AbstractTransactionCallback(HStoreSite hstore_site) {
        super(hstore_site, false);
    }
   
    protected void init(X ts, int counter_val, RpcCallback<T> orig_callback) {
        assert(ts != null) :
            String.format("Null transaction handle in %s", this.getClass().getSimpleName());
        assert(ts.isInitialized()) :
            String.format("Uninitialized transaction handle in %s", this.getClass().getSimpleName());
       
        this.ts = ts;
        if (debug.val) LOG.debug(this.ts + " - Initializing new " + this.getClass().getSimpleName());
        super.init(this.ts.getTransactionId(), counter_val, orig_callback);
    }

    @Override
    protected void finishImpl() {
        this.ts = null;
        this.unblockFinished = false;
        this.abortFinished = false;
    }

    @Override
    public final boolean isInitialized() {
        return (this.ts != null);
    }
   
    @Override
    protected final void unblockCallback() {
        assert(this.isUnblocked());
        assert(this.ts != null) :
            String.format("Null transaction handle for txn #%s in %s [lastTxn=%s / counter=%d/%d]",
                          this.getTransactionId(), this.getClass().getSimpleName(),
                          this.getOrigTransactionId(), this.getCounter(), this.getOrigCounter());
        assert(this.ts.isInitialized()) :
            String.format("Uninitialized transaction handle for txn #%s in %s [lastTxn=%s / origCounter=%d/%d]",
                          this.getTransactionId(), this.getClass().getSimpleName(),
                          this.getOrigTransactionId(), this.getCounter(), this.getOrigCounter());
       
        if (this.isAborted() == false) {
            this.unblockTransactionCallback();
        }
        this.unblockFinished = true;
    }
   
    @Override
    protected final void abortCallback(Status status) {
        assert(this.isAborted());
       
        // We can't abort if we've already invoked the regular callback
        boolean finish = false;
        if (this.isUnblocked() == false) {
            finish = this.abortTransactionCallback(status);
        }
       
        // If we abort, then we have to send out an ABORT to
        // all of the partitions that we originally sent INIT requests too
        // Note that we do this *even* if we haven't heard back from the remote
        // HStoreSite that they've acknowledged our transaction
        // We don't care when we get the response for this
        if (finish && this.ts.isPredictSinglePartition() == false) {
            if (this.ts instanceof LocalTransaction) {
                this.finishTransaction(status);
            } else {
                // FIXME
            }
        }
        this.abortFinished = true;
        this.hstore_site.queueDeleteTransaction(this.txn_id, status);
    }
   
    @SuppressWarnings("unchecked")
    @Override
    public void cancel() {
        super.cancel();
        if (this.getOrigCallback() != null) {
            ((BlockingRpcCallback<T, U>)this.getOrigCallback()).cancel();
        }
    }
   

    /**
     * Transaction unblocking callback implementation
     * @return
     */
    protected abstract void unblockTransactionCallback();
   
    /**
     * Transaction abort callback implementation
     * If this returns true, then we will invoke finishTransaction()
     * @return
     */
    protected abstract boolean abortTransactionCallback(Status status);
   
    // ----------------------------------------------------------------------------
    // CALLBACK CHECKS
    // ----------------------------------------------------------------------------
   
    /**
     * Returns true if either the unblock or abort callbacks have been invoked
     * and have finished their processing
     */
    public final boolean allCallbacksFinished() {
        if (this.isCanceled() == false && this.isInitialized()) {
            if (this.getCounter() != 0) return (false);
            return ((this.isUnblocked() && this.unblockFinished) || (this.isAborted() && this.abortFinished));
        }
        return (true);
    }
   
    // ----------------------------------------------------------------------------
    // INTERNAL UTILITY METHODS
    // ----------------------------------------------------------------------------
   
    /**
     * Tell the HStoreCoordinator to invoke the TransactionFinish process
     * @param status
     */
    protected final void finishTransaction(Status status) {
        assert(this.ts != null) :
            "Null transaction handle for txn #" + this.getTransactionId();
        if (debug.val) LOG.debug(String.format("%s - Invoking TransactionFinish protocol from %s [status=%s]",
                                   this.ts, this.getClass().getSimpleName(), status));
       
        // Let everybody know that the party is over!
        if (this.ts instanceof LocalTransaction) {
            LocalTransaction local_ts = (LocalTransaction)this.ts;
            LocalFinishCallback callback = ((LocalTransaction)this.ts).getFinishCallback();
            callback.init(local_ts, status);
            this.hstore_site.getCoordinator().transactionFinish(local_ts, status, callback);
        }
    }
   
    @Override
    public String toString() {
        return String.format("%s / %s / Deletable=%s",
                             super.toString(), this.ts, this.allCallbacksFinished());
    }
}
TOP

Related Classes of edu.brown.hstore.callbacks.AbstractTransactionCallback

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.