// Must be synchronized since messages may be arriving while handler is being set and might // otherwise end // up not queueing enough executors - so messages get stranded public synchronized ClientConsumerImpl setMessageHandler(final MessageHandler theHandler) throws ActiveMQException { checkClosed(); if (receiverThread != null) { throw ActiveMQClientMessageBundle.BUNDLE.inReceive(); } boolean noPreviousHandler = handler == null; if (handler != theHandler && clientWindowSize == 0) { startSlowConsumer(); } handler = theHandler; // if no previous handler existed queue up messages for delivery if (handler != null && noPreviousHandler) { requeueExecutors(); } // if unsetting a previous handler may be in onMessage so wait for completion else if (handler == null && !noPreviousHandler) { waitForOnMessageToComplete(true); } return this; }
/** * Decodes this TransportConfiguration from a buffer. * * <p>Note this is only used internally by ActiveMQ * * @param buffer the buffer to decode from */ public void decode(final ActiveMQBuffer buffer) { name = buffer.readString(); factoryClassName = buffer.readString(); int num = buffer.readInt(); if (params == null) { if (num > 0) { params = new HashMap<>(); } } else { params.clear(); } for (int i = 0; i < num; i++) { String key = buffer.readString(); byte type = buffer.readByte(); Object val; switch (type) { case TYPE_BOOLEAN: { val = buffer.readBoolean(); break; } case TYPE_INT: { val = buffer.readInt(); break; } case TYPE_LONG: { val = buffer.readLong(); break; } case TYPE_STRING: { val = buffer.readString(); break; } default: { throw ActiveMQClientMessageBundle.BUNDLE.invalidType(type); } } params.put(key, val); } }
@Override public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) throws Exception { if (!active) { return; } // We don't want to log this - since it is normal for this to happen during failover/reconnect // and we don't want to spew out stack traces in that event // The user has access to this exeception anyway via the ActiveMQException initial cause ActiveMQException me = ActiveMQClientMessageBundle.BUNDLE.nettyError(); me.initCause(cause); synchronized (listener) { try { listener.connectionException(channelId(ctx.channel()), me); active = false; } catch (Exception ex) { ActiveMQClientLogger.LOGGER.errorCallingLifeCycleListener(ex); } } }
private void encodeMap(final ActiveMQBuffer buffer, final Map<String, Object> map) { for (Map.Entry<String, Object> entry : map.entrySet()) { buffer.writeString(entry.getKey()); Object val = entry.getValue(); if (val instanceof Boolean) { buffer.writeByte(TransportConfiguration.TYPE_BOOLEAN); buffer.writeBoolean((Boolean) val); } else if (val instanceof Integer) { buffer.writeByte(TransportConfiguration.TYPE_INT); buffer.writeInt((Integer) val); } else if (val instanceof Long) { buffer.writeByte(TransportConfiguration.TYPE_LONG); buffer.writeLong((Long) val); } else if (val instanceof String) { buffer.writeByte(TransportConfiguration.TYPE_STRING); buffer.writeString((String) val); } else { throw ActiveMQClientMessageBundle.BUNDLE.invalidEncodeType(val); } } }
private void checkClosed() throws ActiveMQException { if (closed) { throw ActiveMQClientMessageBundle.BUNDLE.consumerClosed(); } }
private ClientMessage receive(final long timeout, final boolean forcingDelivery) throws ActiveMQException { checkClosed(); if (largeMessageReceived != null) { // Check if there are pending packets to be received largeMessageReceived.discardBody(); largeMessageReceived = null; } if (rateLimiter != null) { rateLimiter.limit(); } if (handler != null) { throw ActiveMQClientMessageBundle.BUNDLE.messageHandlerSet(); } if (clientWindowSize == 0) { startSlowConsumer(); } receiverThread = Thread.currentThread(); // To verify if deliveryForced was already call boolean deliveryForced = false; // To control when to call deliveryForce boolean callForceDelivery = false; long start = -1; long toWait = timeout == 0 ? Long.MAX_VALUE : timeout; try { while (true) { ClientMessageInternal m = null; synchronized (this) { while ((stopped || (m = buffer.poll()) == null) && !closed && toWait > 0) { if (start == -1) { start = System.currentTimeMillis(); } if (m == null && forcingDelivery) { if (stopped) { break; } // we only force delivery once per call to receive if (!deliveryForced) { callForceDelivery = true; break; } } try { wait(toWait); } catch (InterruptedException e) { throw new ActiveMQInterruptedException(e); } if (m != null || closed) { break; } long now = System.currentTimeMillis(); toWait -= now - start; start = now; } } if (failedOver) { if (m == null) { // if failed over and the buffer is null, we reset the state and try it again failedOver = false; deliveryForced = false; toWait = timeout == 0 ? Long.MAX_VALUE : timeout; continue; } else { failedOver = false; } } if (callForceDelivery) { if (isTrace) { ActiveMQClientLogger.LOGGER.trace("Forcing delivery"); } // JBPAPP-6030 - Calling forceDelivery outside of the lock to avoid distributed dead locks sessionContext.forceDelivery(this, forceDeliveryCount++); callForceDelivery = false; deliveryForced = true; continue; } if (m != null) { session.workDone(); if (m.containsProperty(ClientConsumerImpl.FORCED_DELIVERY_MESSAGE)) { long seq = m.getLongProperty(ClientConsumerImpl.FORCED_DELIVERY_MESSAGE); // Need to check if forceDelivery was called at this call // As we could be receiving a message that came from a previous call if (forcingDelivery && deliveryForced && seq == forceDeliveryCount - 1) { // forced delivery messages are discarded, nothing has been delivered by the queue resetIfSlowConsumer(); if (isTrace) { ActiveMQClientLogger.LOGGER.trace( "There was nothing on the queue, leaving it now:: returning null"); } return null; } else { if (isTrace) { ActiveMQClientLogger.LOGGER.trace( "Ignored force delivery answer as it belonged to another call"); } // Ignore the message continue; } } // if we have already pre acked we can't expire boolean expired = m.isExpired(); flowControlBeforeConsumption(m); if (expired) { m.discardBody(); session.expire(this, m); if (clientWindowSize == 0) { startSlowConsumer(); } if (toWait > 0) { continue; } else { return null; } } if (m.isLargeMessage()) { largeMessageReceived = m; } if (isTrace) { ActiveMQClientLogger.LOGGER.trace("Returning " + m); } return m; } else { if (isTrace) { ActiveMQClientLogger.LOGGER.trace("Returning null"); } resetIfSlowConsumer(); return null; } } } finally { receiverThread = null; } }