use of net.dempsy.util.QuietCloseable in project Dempsy by Dempsy.
the class LockingContainer method dispatch.
// this is called directly from tests but shouldn't be accessed otherwise.
@Override
public void dispatch(final KeyedMessage keyedMessage, final Operation op, final boolean youOwnMessage) throws IllegalArgumentException, ContainerException {
if (keyedMessage == null)
// No. We didn't process the null message
return;
if (keyedMessage.message == null)
throw new IllegalArgumentException("the container for " + clusterId + " attempted to dispatch a null message.");
final boolean callDisposition = !(youOwnMessage || op == Operation.output);
final Object actualMessage = callDisposition ? disposition.replicate(keyedMessage.message) : keyedMessage.message;
final Object messageKey = keyedMessage.key;
if (messageKey == null) {
if (callDisposition)
disposition.dispose(actualMessage);
throw new ContainerException("Message " + objectDescription(actualMessage) + " contains no key.");
}
if (!inbound.doesMessageKeyBelongToNode(messageKey)) {
if (callDisposition)
disposition.dispose(actualMessage);
if (LOGGER.isDebugEnabled())
LOGGER.debug("Message with key " + SafeString.objectDescription(messageKey) + " sent to wrong container. ");
if (op != Operation.output)
statCollector.messageFailed(1);
return;
}
boolean evictedAndBlocking;
try {
numBeingWorked.incrementAndGet();
do {
evictedAndBlocking = false;
final InstanceWrapper wrapper = getInstanceForKey(messageKey, actualMessage);
// wrapper will be null if the activate returns 'false'
if (wrapper != null) {
final Object instance = wrapper.getExclusive();
if (instance != null) {
// null indicates we didn't get the lock
try (QuietCloseable qc = () -> wrapper.releaseLock()) {
if (wrapper.isEvicted()) {
// if we're not blocking then we need to just return a failure. Otherwise we want to try
// again because eventually the current Mp will be passivated and removed from the container
// and a subsequent call to getInstanceForDispatch will create a new one.
Thread.yield();
// we're going to try again.
evictedAndBlocking = true;
} else {
invokeOperationAndHandleDispose(wrapper.getInstance(), op, new KeyedMessage(messageKey, actualMessage));
}
}
} else {
// ... we didn't get the lock
if (LOGGER.isTraceEnabled())
LOGGER.trace("the container for " + clusterId + " failed to obtain lock on " + SafeString.valueOf(prototype));
statCollector.messageCollision(actualMessage);
if (callDisposition)
disposition.dispose(actualMessage);
}
} else {
// if we got here then the activate on the Mp explicitly returned 'false'
if (LOGGER.isDebugEnabled())
LOGGER.debug("the container for " + clusterId + " failed to activate the Mp for " + SafeString.valueOf(prototype));
if (callDisposition)
disposition.dispose(actualMessage);
// leave the do/while loop
break;
}
} while (evictedAndBlocking);
} finally {
numBeingWorked.decrementAndGet();
}
}
Aggregations