}
protected Object executeCommand(ReplicableCommand cmd, Message req) throws Throwable
{
boolean unlock = false;
FlushTracker flushTracker = rpcManager.getFlushTracker();
try
{
if (cmd == null) throw new NullPointerException("Unable to execute a null command! Message was " + req);
if (trace) log.trace("Executing command: " + cmd + " [sender=" + req.getSrc() + "]");
boolean replayIgnored = false;
if (configuration.isNonBlockingStateTransfer() && !(cmd instanceof StateTransferControlCommand))
{
int flushCount = flushTracker.getFlushCompletionCount();
flushTracker.lockProcessingLock();
unlock = true;
flushTracker.waitForFlushCompletion(configuration.getStateRetrievalTimeout());
// If this thread blocked during a NBST flush, then inform the sender
// it needs to replay ignored messages
replayIgnored = flushTracker.getFlushCompletionCount() != flushCount;
}
Object ret;
if (cmd instanceof VisitableCommand)
{
InvocationContext ctx = invocationContextContainer.get();
ctx.setOriginLocal(false);
if (!componentRegistry.invocationsAllowed(false))
{
return new RequestIgnoredResponse();
}
try
{
ret = interceptorChain.invoke(ctx, (VisitableCommand) cmd);
}
catch (CacheNotReadyException cnre)
{
// this could happen, even though we check the state earlier on. There is still a window
// for the cache to be shut down in the meanwhile.
if (log.isDebugEnabled()) log.debug("Cache not in a state to respond!", cnre);
return new RequestIgnoredResponse();
}
}
else
{
if (trace) log.trace("This is a non-visitable command - so performing directly and not via the invoker.");
// need to check cache status for all except buddy replication commands.
if (requiresRunningCache(cmd) && !componentRegistry.invocationsAllowed(false))
{
return new RequestIgnoredResponse();
}
ret = cmd.perform(null);
}
if (replayIgnored)
{
ExtendedResponse extended = new ExtendedResponse(ret);
extended.setReplayIgnoredRequests(true);
ret = extended;
}
return ret;
}
finally
{
if (replicationObserver != null)
replicationObserver.afterExecutingCommand(cmd);
if (unlock)
flushTracker.unlockProcessingLock();
}
}