Search in sources :

Example 1 with QuietCloseable

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();
    }
}
Also used : ContainerException(net.dempsy.container.ContainerException) KeyedMessage(net.dempsy.messages.KeyedMessage) QuietCloseable(net.dempsy.util.QuietCloseable)

Aggregations

ContainerException (net.dempsy.container.ContainerException)1 KeyedMessage (net.dempsy.messages.KeyedMessage)1 QuietCloseable (net.dempsy.util.QuietCloseable)1