if (trace.val)
LOG.trace(String.format("Checking lock queue for partition %d [queueSize=%d]",
partition, this.lockQueues[partition].size()));
// Poll the queue and get the next value.
AbstractTransaction nextTxn = null;
this.lockQueueBarriers[partition].lockInterruptibly();
try {
nextTxn = this.lockQueues[partition].poll();
} finally {
this.lockQueueBarriers[partition].unlock();
} // SYNCH
if (nextTxn == null) {
if (hstore_conf.site.queue_profiling) profilers[partition].lock_time.stopIfStarted();
return (nextTxn);
}
PartitionCountingCallback<AbstractTransaction> callback = nextTxn.getInitCallback();
assert(callback.isInitialized()) :
String.format("Uninitialized %s callback for %s [hashCode=%d]",
callback.getClass().getSimpleName(), nextTxn, callback.hashCode());
// HACK
if (nextTxn.isAborted()) {
if (debug.val)
LOG.warn(String.format("The next txn for partition %d is %s but it is marked as aborted.",
partition, nextTxn));
callback.decrementCounter(partition);
nextTxn = null;
}
// If this callback has already been aborted, then there is nothing we need to
// do. Somebody else will make sure that this txn is removed from the queue
else if (callback.isAborted()) {
if (debug.val)
LOG.warn(String.format("The next txn for partition %d is %s but its %s is " +
"marked as aborted. [queueSize=%d]",
partition, nextTxn, callback.getClass().getSimpleName(),
this.lockQueues[partition].size()));
callback.decrementCounter(partition);
nextTxn = null;
}
// We have something we can use
else {
if (trace.val)
LOG.trace(String.format("Good news! Partition %d is ready to execute %s! " +
"Invoking %s.run()",
partition, nextTxn, callback.getClass().getSimpleName()));
this.lockQueueLastTxns[partition] = nextTxn.getTransactionId();
}
if (nextTxn != null) {
// Send the init request for the specified partition
if (debug.val)
LOG.debug(String.format("%s - Invoking %s.run() for partition %d",
nextTxn, nextTxn.getInitCallback().getClass().getSimpleName(), partition));
try {
nextTxn.getInitCallback().run(partition);
} catch (NullPointerException ex) {
// HACK: Ignore...
if (debug.val)
LOG.warn(String.format("Unexpected error when invoking %s for %s at partition %d",
nextTxn.getInitCallback().getClass().getSimpleName(),
nextTxn, partition), ex);
} catch (Throwable ex) {
String msg = String.format("Failed to invoke %s for %s at partition %d",
nextTxn.getInitCallback().getClass().getSimpleName(),
nextTxn, partition);
throw new ServerFaultException(msg, ex, nextTxn.getTransactionId());
}
// Mark the txn being released to the given partition
nextTxn.markReleased(partition);
if (trace.val && nextTxn != null)
LOG.trace(String.format("Finished processing lock queue for partition %d [next=%s]",
partition, nextTxn));
}