Closed GoogleCodeExporter closed 9 years ago
Stomp doesn't have transaction receipt of messages that can be rolled back so
that
messages return to the queue on error by the processor.
There is a client ack mode, which sorta does this, but does not have a rollback
method short of severing the connection.
You can read more about this issue here:
http://www.nabble.com/putting-a-message-back-td12367572.html
and here:
http://groups.google.com/group/activemessaging-discuss/browse_thread/thread/57b1
953daf468c60
Original comment by kooks...@gmail.com
on 29 Aug 2008 at 10:01
If the ack mode is client, the message shouldn't be ack'd until the processor's
code
has been executed, IMHO.
In looking at the received method, the ack is sent on receipt of the message,
not on
successful processing of the message. Perhaps the received method can indicate
to a
post-successful-processing method to send the ack?
ALSO, in maxRetry in the example broker.yml file really should be retryMax,
since
that's what in the source code.
Original comment by brian.mo...@gmail.com
on 29 Aug 2008 at 10:32
> If the ack mode is client, the message shouldn't be ack'd until the
processor's
> code has been executed, IMHO.
> In looking at the received method, the ack is sent on receipt of the message,
> not on successful processing of the message. Perhaps the received method can
> indicate to a post-successful-processing method to send the ack?
I used to think that too, and implemented it that way at first, till I actually
tested it.
Answer me this - what do you think the broker does if you don't ack a message?
You never get sent another message - no timeout, no rollback - if you don't
ack, you
stop getting messages, and all processing stops cold, end of story. I don't
mean to
sound dismissive, but I have been dealing with this problem for awhile, believe
me,
I didn't implement it this way by accident or b/c I overlooked this - client
ack mode
is not transactional, you can't roll it back, it is really only good as a
throttle,
and to handle the case that your process dies with messages already received by
the
stomp client connection, but unprocessed, and subsequently lost.
Please review the pages I referenced - this is the crux of the problem - if you
don't
ack the message, you will never get sent another on that
connection/subscription -
not ack'ing the message is not the same thing at all as return it to the queue.
> ALSO, in maxRetry in the example broker.yml file really should be retryMax,
since
> that's what in the source code.
Yeah yeah, my bad. This got pointed out on the list yesterday, and I checked in
a fix
to that comment in the generated yml file already. Apologies for the confusion.
Original comment by kooks...@gmail.com
on 29 Aug 2008 at 10:45
BTW, we use the 'break the connection and the message stays in the queue' for
another
application, and it works well.
Original comment by brian.mo...@gmail.com
on 29 Aug 2008 at 10:46
So now I am confused - what do you want?
Did you ever get the retryMax stuff to work, or do you just not like that
implementation and prefer the connection break method?
If you know about this stuff, why the vague defect report?
For what it is worth - your analysis of how the received messages gets called
is off
a bit - exactly as you are asking for, messages are ack'ed only after the
successful
completion of the message being processed by at least one subscribing
processor, not
on receipt of the message. Look at the gateway lines 227 - 237 - you will see
that
the acknowledge_message method is called in an ensure block after the process
method
is called, so if the ruby process were to die/get disconnected mid-processing,
the
message would get returned to the queue.
My abort logic alters this slightly as it sends the cloned message back to the
destination and sends the ack in a transaction together, so were something to
go bad,
the ack and dupe message would both be lost, and the original message would be
returned to the queue.
You like the 'break the connection' hack? That's a choice you can make in your
app,
but that is a work-around with it's own trade-offs, and I find that returning a
clone
of the message to the queue has trade offs I prefer.
For example: What happens to messages that are supposed to come in to your
subscription while you are breaking the connection, reconnecting, and
resubscribing?
For queues this might be ok - the message will wait for you, or some other
subscribed
client - but what about when you have topics to which you are subscribed, and
now if
you missed that message? And don't tell me the answer is that the reconnect is
usually fast or that you can use durable topics - that's just saying this will
be
rare, and requiring features specific to one stomp broker impl, not a solution
- I
know users throwing pretty high load of messages at their destinations, this
will
happen for them, and I know users not using activemq for their stomp server.
And another trade off - what about possibly infinite retry loops? Let's say
you have
a message that every time it gets processed, it fails, gets put back on the
queue by
connection reset method, and then does the same thing all over again. Perhaps
the
broker will allow for a timeout on the message so eventually this will end, and
the
message will wither expire or go to a dead letter, but then I would be relying
on the
existence of broker capabilities not at all specified or assured by supporting
stomp
- e.g. maybe activemq could be made to behave this way (though most users of
active
messaging would not be quick to know how to configure this), I don't think
StompServer does this at all, and again, I have more than a few users on that
broker.
The downside to my approach is that you lose message order in the destination -
which
for some apps will be unacceptable, but I see fewer people complaining about
that
than about loosing messages from topics or jamming up their pollers with
constant
reprocessing of erroneous messages.
Original comment by kooks...@gmail.com
on 29 Aug 2008 at 11:58
Original issue reported on code.google.com by
brian.mo...@gmail.com
on 29 Aug 2008 at 9:10