@Override public HandleStatus handle(final MessageReference ref) throws Exception { if (filter != null && !filter.match(ref.getMessage())) { return HandleStatus.NO_MATCH; } synchronized (this) { if (!active || !session.isWritable(this)) { if (logger.isDebugEnabled()) { logger.debug(this + "::Ignoring reference on bridge as it is set to inactive ref=" + ref); } return HandleStatus.BUSY; } if (deliveringLargeMessage) { return HandleStatus.BUSY; } if (logger.isTraceEnabled()) { logger.trace("Bridge " + this + " is handling reference=" + ref); } ref.handled(); synchronized (refs) { refs.put(ref.getMessage().getMessageID(), ref); } final ServerMessage message = beforeForward(ref.getMessage()); final SimpleString dest; if (forwardingAddress != null) { dest = forwardingAddress; } else { // Preserve the original address dest = message.getAddress(); } pendingAcks.countUp(); try { if (message.isLargeMessage()) { deliveringLargeMessage = true; deliverLargeMessage(dest, ref, (LargeServerMessage) message); return HandleStatus.HANDLED; } else { return deliverStandardMessage(dest, ref, message); } } catch (Exception e) { // If an exception happened, we must count down immediately pendingAcks.countDown(); throw e; } } }
/** @param credits */ private void sendCredits(final int credits) { pendingFlowControl.countUp(); flowControlExecutor.execute( new Runnable() { public void run() { try { sessionContext.sendConsumerCredits(ClientConsumerImpl.this, credits); } finally { pendingFlowControl.countDown(); } } }); }
/** Sending an initial credit for slow consumers */ private void startSlowConsumer() { if (isTrace) { ActiveMQClientLogger.LOGGER.trace( "Sending 1 credit to start delivering of one message to slow consumer"); } sendCredits(1); try { // We use an executor here to guarantee the messages will arrive in order. // However when starting a slow consumer, we have to guarantee the credit was sent before we // can perform any // operations like forceDelivery pendingFlowControl.await(10, TimeUnit.SECONDS); } catch (InterruptedException e) { // will just ignore and forward the ignored Thread.currentThread().interrupt(); } }
@Override public void sendAcknowledged(final Message message) { if (logger.isTraceEnabled()) { logger.trace("BridgeImpl::sendAcknowledged received confirmation for message " + message); } if (active) { try { final MessageReference ref; synchronized (refs) { ref = refs.remove(message.getMessageID()); } if (ref != null) { if (logger.isTraceEnabled()) { logger.trace( "BridgeImpl::sendAcknowledged bridge " + this + " Acking " + ref + " on queue " + ref.getQueue()); } ref.getQueue().acknowledge(ref); pendingAcks.countDown(); } else { if (logger.isTraceEnabled()) { logger.trace( "BridgeImpl::sendAcknowledged bridge " + this + " could not find reference for message " + message); } } } catch (Exception e) { ActiveMQServerLogger.LOGGER.bridgeFailedToAck(e); } } }