activemq-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Sebastjan Trepca" <tre...@gmail.com>
Subject Stomp protocol problems
Date Mon, 28 Jan 2008 20:02:10 GMT
Hi,

I'm using ActiveMQ(both versions are affected) with STOMP protocol and
noticed a problem with it. At least I hope it's a problem.

When you ACK a message through stomp, all messages until the right one
gets ACKed too.

If we check the code:

    protected void onStompAck(StompFrame command) throws ProtocolException {
        checkConnected();

        // TODO: acking with just a message id is very bogus
        // since the same message id could have been sent to 2 different
        // subscriptions
        // on the same stomp connection. For example, when 2 subs are created on
        // the same topic.

        Map<String, String> headers = command.getHeaders();
        String messageId = headers.get(Stomp.Headers.Ack.MESSAGE_ID);
        if (messageId == null) {
            throw new ProtocolException("ACK received without a
message-id to acknowledge!");
        }

        TransactionId activemqTx = null;
        String stompTx = headers.get(Stomp.Headers.TRANSACTION);
        if (stompTx != null) {
            activemqTx = transactions.get(stompTx);
            if (activemqTx == null) {
                throw new ProtocolException("Invalid transaction id: "
+ stompTx);
            }
        }

        boolean acked = false;
        for (Iterator<StompSubscription> iter =
subscriptionsByConsumerId.values().iterator(); iter.hasNext();) {
            StompSubscription sub = iter.next();
            MessageAck ack = sub.onStompMessageAck(messageId);
            if (ack != null) {
                ack.setTransactionId(activemqTx);
                sendToActiveMQ(ack, createResponseHandler(command));
                acked = true;
                break;
            }
        }

        if (!acked) {
            throw new ProtocolException("Unexpected ACK received for
message-id [" + messageId + "]");
        }

    }


synchronized MessageAck onStompMessageAck(String messageId) {

        if (!dispatchedMessage.containsKey(messageId)) {
            return null;
        }

        MessageAck ack = new MessageAck();
        ack.setDestination(consumerInfo.getDestination());
        ack.setAckType(MessageAck.STANDARD_ACK_TYPE);
        ack.setConsumerId(consumerInfo.getConsumerId());

        int count = 0;
        for (Iterator iter = dispatchedMessage.entrySet().iterator();
iter.hasNext();) {

            Map.Entry entry = (Entry)iter.next();
            String id = (String)entry.getKey();
            MessageId msgid = (MessageId)entry.getValue();

            if (ack.getFirstMessageId() == null) {
                ack.setFirstMessageId(msgid);
            }

            iter.remove();
            count++;

            if (id.equals(messageId)) {
                ack.setLastMessageId(msgid);
                break;
            }

        }

        ack.setMessageCount(count);
        return ack;
    }

It loops through all messages and ACKs them until it finds the correct
message id. So when you send few messages and the last one is the
processed first all previous ones get ACKed?

Is this a feature of STOMP protocol or is it a bug?

Thanks, Sebastjan

Mime
View raw message