Package edu.brown.hstore.callbacks

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

package edu.brown.hstore.callbacks;

import org.apache.log4j.Logger;
import org.voltdb.messaging.FastDeserializer;

import com.google.protobuf.RpcCallback;

import edu.brown.hstore.HStoreSite;
import edu.brown.hstore.Hstoreservice.Status;
import edu.brown.hstore.Hstoreservice.TransactionInitResponse;
import edu.brown.hstore.specexec.PrefetchQueryUtil;
import edu.brown.hstore.txns.RemoteTransaction;
import edu.brown.logging.LoggerUtil;
import edu.brown.logging.LoggerUtil.LoggerBoolean;
import edu.brown.utils.PartitionSet;

/**
*
* @author pavlo
*/
public class RemoteInitQueueCallback extends PartitionCountingCallback<RemoteTransaction> {
    private static final Logger LOG = Logger.getLogger(RemoteInitQueueCallback.class);
    private static final LoggerBoolean debug = new LoggerBoolean();
    private static final LoggerBoolean trace = new LoggerBoolean();
    static {
        LoggerUtil.attachObserver(LOG, debug, trace);
    }

    private final boolean prefetch;
    private ThreadLocal<FastDeserializer> prefetchDeserializers;
    private final PartitionSet localPartitions = new PartitionSet();
    private TransactionInitResponse.Builder builder = null;
    private RpcCallback<TransactionInitResponse> origCallback;
   
    // ----------------------------------------------------------------------------
    // INTIALIZATION
    // ----------------------------------------------------------------------------
   
    public RemoteInitQueueCallback(HStoreSite hstore_site) {
        super(hstore_site);
        this.prefetch = hstore_site.getHStoreConf().site.exec_prefetch_queries;
    }
   
    public void init(RemoteTransaction ts, PartitionSet partitions, RpcCallback<TransactionInitResponse> origCallback) {
        this.builder = TransactionInitResponse.newBuilder()
                            .setTransactionId(ts.getTransactionId().longValue())
                            .setStatus(Status.OK);
        this.origCallback = origCallback;
       
        // Remove non-local partitions
        this.localPartitions.clear();
        this.localPartitions.addAll(partitions);
        this.localPartitions.retainAll(this.hstore_site.getLocalPartitionIds());
        super.init(ts, this.localPartitions);
    }
   
    // ----------------------------------------------------------------------------
    // CALLBACK METHODS
    // ----------------------------------------------------------------------------

    @Override
    public void run(int partition) {
        if (trace.val)
            LOG.trace(String.format("%s - Prefetch=%s / HasPrefetchFragments=%s",
                      this.ts, this.prefetch, this.ts.hasPrefetchFragments()));
        if (this.prefetch && this.ts.hasPrefetchFragments()) {
            if (this.prefetchDeserializers == null) {
                if (debug.val)
                    LOG.debug(String.format("%s - Checking for prefetch queries at partition %d",
                              this.ts, partition));
                synchronized (this) {
                    this.prefetchDeserializers = new ThreadLocal<FastDeserializer>() {
                        @Override
                        protected FastDeserializer initialValue() {
                            return (new FastDeserializer(new byte[0]));
                        }
                    };
                } // SYNCH
            }
            FastDeserializer fd = this.prefetchDeserializers.get();
            boolean result = PrefetchQueryUtil.dispatchPrefetchQueries(hstore_site, this.ts, fd, partition);
            if (debug.val)
                LOG.debug(String.format("%s - Result from dispatching prefetch queries at partition %d -> %s",
                          this.ts, partition, result));
        }
        super.run(partition);
    }
   
    @Override
    protected void unblockCallback() {
        if (debug.val)
            LOG.debug(String.format("%s - Checking whether we can send back %s with status %s",
                      this.ts, TransactionInitResponse.class.getSimpleName(),
                      (this.builder != null ? this.builder.getStatus() : "???")));
        if (this.builder != null) {
            if (debug.val)
                LOG.debug(String.format("%s - Sending %s to %s with status %s",
                          this.ts,
                          TransactionInitResponse.class.getSimpleName(),
                          this.origCallback.getClass().getSimpleName(),
                          this.builder.getStatus()));
           
            // Ok so where's what going on here. We need to send back
            // an abort message, so we're going use the builder that we've been
            // working on and send out the bomb back to the base partition tells it that this
            // transaction is kaput at this HStoreSite.
            this.builder.clearPartitions();
            PartitionSet partitions = this.getPartitions();
            for (int partition : partitions.values()) {
                assert(this.hstore_site.isLocalPartition(partition));
                this.builder.addPartitions(partition);
            } // FOR

            assert(this.builder.getPartitionsList() != null) :
                String.format("The %s for %s has no results but it was suppose to have %d.",
                              builder.getClass().getSimpleName(), this.ts, this.getOrigCounter());
            assert(this.getOrigCounter() == this.builder.getPartitionsCount()) :
                String.format("The %s for %s has results from %d partitions but it was suppose to have %d.",
                              builder.getClass().getSimpleName(), this.ts, builder.getPartitionsCount(), this.getOrigCounter());
            assert(this.origCallback != null) :
                String.format("The original callback for %s is null!", this.ts);
           
            this.origCallback.run(this.builder.build());
            this.builder = null;
        }
        else if (debug.val) {
            LOG.warn(String.format("%s - No builder is available? Unable to send back %s",
                      this.ts, TransactionInitResponse.class.getSimpleName()));
        }
    }
   
    @Override
    protected void abortCallback(int partition, Status status) {
        // Uh... this might have already been sent out?
        if (this.builder != null) {
            if (debug.val)
                LOG.debug(String.format("%s - Aborting %s with status %s",
                          this.ts, this.getClass().getSimpleName(), status));
           
            // Ok so where's what going on here. We need to send back
            // an abort message, so we're going use the builder that we've been
            // working on and send out the bomb back to the base partition tells it that this
            // transaction is kaput at this HStoreSite.
            this.builder.setStatus(status);
            this.builder.clearPartitions();
            this.builder.addAllPartitions(this.getPartitions());
            this.builder.setRejectPartition(partition);
           
            assert(this.origCallback != null) :
                String.format("The original callback for %s is null!", this.ts);
           
            this.origCallback.run(this.builder.build());
            this.builder = null;
        }
        else if (debug.val) {
            LOG.warn(String.format("%s - No builder is available? Unable to send back %s",
                     this.ts, TransactionInitResponse.class.getSimpleName()));
        }
    }
}
TOP

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

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.