activemq-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Martin Baum <p...@flachtaucher.de>
Subject ActiveMQ STOMP: No strict FIFO breaks on unsubscribe/subscribe
Date Thu, 12 Nov 2009 17:59:23 GMT

ActiveMQ STOMP: No strict FIFO on unsubscribe/subscribe

Hi,

I'm using ActiveMQ 5.3 with Stomp adaptor. I access the adaptor with this 
php-module: http://pecl.php.net/package/stomp.

I am using durable messages. I think I am using durable queues - they last 
through server restarts.

In my Stomp subscribe-commands activemq.prefetchSize is set to 1. 

Short version:

I need a consumer to do strict FIFO on a queue. However strict FIFO is not 
adhered: As soon as I unsubscribe this consumer and subscribe it again to 
the same queue my messages get out of FIFO order.

Messages getting out of order are marked as redelivered in ActiveMQ web 
interface.

Connection snooping shows that prefetch seems to be the culprit: When I 
ack one message and before I can send my unsubscribe-command another message 
will get pushed to my client (but not get ack()ed by me). When I unsubscribe
and subscribe again this message will not appear first in queue but will be 
sent to me at some later time - probably because of redelivery. This breaks 
my consumer. 

Is there a way to fix this behaviour? (see end of long version for a list 
of things I already tried)



Long version:

I am writing a consumer that needs to process messages of a single queue. 
The queue contains commands for different servers, identified by
header-field
server_id. For every given server_id the commands need to get processed in 
strict FIFO. My consumer is forking off worker processes in order to process 
the commands. As long as a command is running I do not want to receive 
additional messages for this server. I do this by using subscriptions with 
selectors. So my code looks something like this:


while(1)
  if gotNewFrame(timeout=1sec) {
    ackFrame
    (start fork: runCommandFor_server_id. 
     will not interfere with parent process any more)
    unsubscribe_from_queue
    subscribe_to_queue_using_a_selector_that_excludes_server_id
  }
  if childIsFinished {
    unsubscribe_from_queue
    subscribe_to_queue_with_selector_that_does_not_exclude_server_id_anymore
  }
}

What happens is that I receive commands for a single server_id in different 
order than my insertion in the queue was. This makes the commands fail since 
they all depend on each other. The commands that get out of order are tagged 
as redelivered in the ActiveMQ webinterface.

A network snoop exposes that the commands that get out of order are
delivered 
to me in the timeframe after I send the ackFrame but before 
unsubscribe_from_queue happens. My guess is that this is due to the 
prefetch-behaviour. So maybe ActiveMQ considers those deliveries "failed" 
when it receives my unsubscribe command. However this breaks my consumer.

Is there a way to fix this? Maybe some configuration option that makes sure 
that strict order for messages is kept even in case of redeliveries? Or some 
way to make sure that I do not get pushed another message before the 
unsubscribe-command hits?

Things I tried:

* unsubscribing before I ack my message -> will raise an exception on 
  ActiveMQ server (unexpected ack)

* setting activemq.prefetchSize to 0. Will break my Stomp-client since stomp 
does not have an message polling command.


Any other ideas?

Thanks a lot for your help!

best regards,
Martin



-- 
View this message in context: http://old.nabble.com/ActiveMQ-STOMP%3A-No-strict-FIFO-breaks-on-unsubscribe-subscribe-tp26323341p26323341.html
Sent from the ActiveMQ - User mailing list archive at Nabble.com.


Mime
View raw message