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.Hstoreservice.WorkResult;
import edu.brown.hstore.Hstoreservice.TransactionWorkResponse;
import edu.brown.hstore.txns.AbstractTransaction;
import edu.brown.logging.LoggerUtil;
import edu.brown.logging.LoggerUtil.LoggerBoolean;
import edu.brown.utils.PartitionSet;
/**
*
* @author pavlo
*/
public class RemoteWorkCallback extends PartitionCountingCallback<AbstractTransaction> implements RpcCallback<WorkResult> {
private static final Logger LOG = Logger.getLogger(RemoteWorkCallback.class);
private static final LoggerBoolean debug = new LoggerBoolean();
static {
LoggerUtil.attachObserver(LOG, debug);
}
private TransactionWorkResponse.Builder builder = null;
private RpcCallback<TransactionWorkResponse> orig_callback = null;
// ----------------------------------------------------------------------------
// INTIALIZATION
// ----------------------------------------------------------------------------
/**
* Default Constructor
*/
public RemoteWorkCallback(HStoreSite hstore_site) {
super(hstore_site);
}
public void init(AbstractTransaction ts, PartitionSet partitions, RpcCallback<TransactionWorkResponse> orig_callback) {
super.init(ts, partitions);
this.orig_callback = orig_callback;
this.builder = TransactionWorkResponse.newBuilder()
.setTransactionId(ts.getTransactionId().longValue())
.setStatus(Status.OK);
}
// ----------------------------------------------------------------------------
// CALLBACK METHODS
// ----------------------------------------------------------------------------
@Override
public void unblockCallback() {
if (debug.val)
LOG.debug(String.format("%s - Invoking %s to send back %d partition results",
this.ts, this.orig_callback.getClass().getSimpleName(), this.builder.getResultsCount()));
assert(this.getOrigCounter() == this.builder.getResultsCount()) :
String.format("The %s for %s has results from %d partitions but it was suppose to have %d.",
this.builder.getClass().getSimpleName(), this.ts, this.builder.getResultsCount(), this.getOrigCounter());
this.orig_callback.run(this.builder.build());
}
@Override
protected void abortCallback(int partition, Status status) {
assert(false) : String.format("Unexpected %s for %s", status, this.ts);
}
// ----------------------------------------------------------------------------
// RPC CALLBACK
// ----------------------------------------------------------------------------
@Override
public synchronized void run(WorkResult parameter) {
this.builder.addResults(parameter);
if (debug.val)
LOG.debug(String.format("%s - Added new %s from partition %d",
this.ts, parameter.getClass().getSimpleName(), parameter.getPartitionId()));
if (parameter.hasError()) {
LOG.info(String.format("%s - Marking %s with an error from partition %d",
this.ts, this.builder.getClass().getSimpleName(), parameter.getPartitionId()));
System.out.println(this.hstore_site.getTransaction(this.builder.getTransactionId())+" "+this.builder.getTransactionId());
if (debug.val)
LOG.debug(String.format("%s - Marking %s with an error from partition %d",
this.ts, this.builder.getClass().getSimpleName(), parameter.getPartitionId()));
this.builder.setStatus(Status.ABORT_UNEXPECTED);
}
this.run(parameter.getPartitionId());
}
}