public void onFlowConsumer(Object consumer, int credits, final boolean drain) { ServerConsumerImpl serverConsumer = (ServerConsumerImpl) consumer; if (drain) { // If the draining is already running, then don't do anything if (draining.compareAndSet(false, true)) { final ProtonServerSenderContext plugSender = (ProtonServerSenderContext) serverConsumer.getProtocolContext(); serverConsumer.forceDelivery(1, new Runnable() { @Override public void run() { try { plugSender.reportDrained(); } finally { draining.set(false); } } }); } } else { serverConsumer.receiveCredits(-1); } }
/** * @param ref * @param message */ private void deliverStandardMessage(final MessageReference ref, Message message) throws ActiveMQException { applyPrefixForLegacyConsumer(message); int packetSize = callback.sendMessage(ref, message, ServerConsumerImpl.this, ref.getDeliveryCount()); if (availableCredits != null) { availableCredits.addAndGet(-packetSize); if (logger.isTraceEnabled()) { logger.trace(this + "::FlowControl::delivery standard taking " + packetSize + " from credits, available now is " + availableCredits); } } }
@Override public String toManagementString() { return "ServerConsumer [id=" + getConnectionID() + ":" + getSessionID() + ":" + id + ", filter=" + filter + ", binding=" + binding.toManagementString() + "]"; }
@Override public void promptDelivery() { // largeMessageDeliverer is always set inside a lock // if we don't acquire a lock, we will have NPE eventually if (largeMessageDeliverer != null) { resumeLargeMessage(); } else { forceDelivery(); } }
if (consumer instanceof ServerConsumerImpl) { ServerConsumerImpl serverConsumer = (ServerConsumerImpl) consumer; float consumerRate = serverConsumer.getRate(); if (queueRate < threshold) { if (logger.isDebugEnabled()) { if (potentialConnection.getID().toString().equals(serverConsumer.getConnectionID())) { connection = potentialConnection; serverConsumer.fireSlowConsumer(); ActiveMQServerLogger.LOGGER.slowConsumerDetected(serverConsumer.getSessionID(), serverConsumer.getID(), getName().toString(), connection.getRemoteAddress(), threshold, consumerRate); if (policy.equals(SlowConsumerPolicy.KILL)) { connection.killMessage(server.getNodeID()); props.putLongProperty(ManagementHelper.HDR_CONSUMER_NAME, serverConsumer.getID()); props.putSimpleStringProperty(ManagementHelper.HDR_SESSION_NAME, SimpleString.toSimpleString(serverConsumer.getSessionID()));
/** * Prompt delivery and send a "forced delivery" message to the consumer. * <p> * When the consumer receives such a "forced delivery" message, it discards it and knows that * there are no other messages to be delivered. */ @Override public void forceDelivery(final long sequence) { forceDelivery(sequence, () -> { Message forcedDeliveryMessage = new CoreMessage(storageManager.generateID(), 50); MessageReference reference = MessageReference.Factory.createReference(forcedDeliveryMessage, messageQueue); reference.setDeliveryCount(0); forcedDeliveryMessage.putLongProperty(ClientConsumerImpl.FORCED_DELIVERY_MESSAGE, sequence); forcedDeliveryMessage.setAddress(messageQueue.getName()); applyPrefixForLegacyConsumer(forcedDeliveryMessage); callback.sendMessage(reference, forcedDeliveryMessage, ServerConsumerImpl.this, 0); }); }
setStarted(false); removeItself(); List<MessageReference> refs = cancelRefs(failed, false, null);
ServerConsumerImpl consumerImpl = (ServerConsumerImpl) consumer; long timeout = System.currentTimeMillis() + 5000; while (timeout > System.currentTimeMillis() && consumerImpl.getAvailableCredits() != null) { Thread.sleep(10); Assert.assertNull(consumerImpl.getAvailableCredits());
@Override public void proceedDeliver(MessageReference reference) throws Exception { try { Message message = reference.getMessage(); if (server.hasBrokerMessagePlugins()) { server.callBrokerMessagePlugins(plugin -> plugin.beforeDeliver(this, reference)); } if (message.isLargeMessage() && supportLargeMessage) { if (largeMessageDeliverer == null) { // This can't really happen as handle had already crated the deliverer // instead of throwing an exception in weird cases there is no problem on just go ahead and create it // again here largeMessageDeliverer = new LargeMessageDeliverer((LargeServerMessage) message, reference); } // The deliverer was prepared during handle, as we can't have more than one pending large message // as it would return busy if there is anything pending largeMessageDeliverer.deliver(); } else { deliverStandardMessage(reference, message); } } finally { lockDelivery.readLock().unlock(); callback.afterDelivery(); if (server.hasBrokerMessagePlugins()) { server.callBrokerMessagePlugins(plugin -> plugin.afterDeliver(this, reference)); } } }
ServerConsumer consumer = new ServerConsumerImpl(consumerID, this, (QueueBinding) binding, filter, priority, started, browseOnly, storageManager, callback, preAcknowledge, strictUpdateDeliveryCount, managementService, supportLargeMessage, credits, server); consumers.put(consumer.getID(), consumer);
@Test public void testConsumerWindowSizeAddressSettingsDifferentAddressAndQueueName() throws Exception { ActiveMQServer messagingService = createServer(false, isNetty()); final int defaultConsumerWindowSize = 1024 * 5; final AddressSettings settings = new AddressSettings(); settings.setDefaultConsumerWindowSize(defaultConsumerWindowSize); messagingService.getConfiguration() .getAddressesSettings().put(addressA.toString(), settings); messagingService.start(); messagingService.createQueue(addressA, RoutingType.ANYCAST, queueA, null, true, false); ClientSessionFactory cf = createSessionFactory(locator); ClientSession session = cf.createSession(false, true, true); ClientConsumerImpl consumer = (ClientConsumerImpl) session.createConsumer(queueA); session.start(); assertEquals(defaultConsumerWindowSize / 2, consumer.getClientWindowSize()); ServerSession ss = messagingService.getSessionByID(((ClientSessionImpl)session).getName()); ServerConsumerImpl cons = (ServerConsumerImpl) ss.locateConsumer(consumer.getConsumerContext().getId()); assertTrue(Wait.waitFor(() -> cons.getAvailableCredits().get() == consumer.getClientWindowSize() * 2, 5000, 50)); }
@Override public void onFlow(int currentCredits, boolean drain) { connection.requireInHandler(); setupCredit(); ServerConsumerImpl serverConsumer = (ServerConsumerImpl) brokerConsumer; if (drain) { // If the draining is already running, then don't do anything if (draining.compareAndSet(false, true)) { final ProtonServerSenderContext plugSender = (ProtonServerSenderContext) serverConsumer.getProtocolContext(); serverConsumer.forceDelivery(1, new Runnable() { @Override public void run() { try { connection.runNow(() -> { plugSender.reportDrained(); setupCredit(); }); } finally { draining.set(false); } } }); } } else { serverConsumer.receiveCredits(-1); } }