I have a situation where the Maxtries in my MSMQ is 5. After 5 times nservicebus sends the message to the Error que that I have defined. Now I want to perfomr some further action when this happens (I have to update status of some processes to Error)
Is it possible to write a handler in my Saga class to read these error queues?
Thanks in Advance
Haris
If your are using 2.x you may want to consider writing a separate endpoint where the error queue is its input queue. The downside to this is that the messages will come off the queue. Assuming you still want to store them, you'll have to push them off to a database or some other type of storage.
You could also write a Saga that polls the error queue to check for messages and updates the appropriate status. After each time you check the queue, you would need to request another Timeout.
In 3.0, you have more control over the exceptions, and can implement your own way to handle the errors. If you implement the interface IManageMessageFailures, you can do your work there.
As an alternative to the solutions provided by Adam, you can subscribe to events raised by ServiceControl which are raisesd when a messages is sent to the errorqueue. See the official documentation about this here: http://docs.particular.net/servicecontrol/contracts
Another approach would be the notification API as described here: http://docs.particular.net/nservicebus/errors/subscribing-to-error-notifications. It allows you to subscribe to certain events (not event messages) like "MessageSentToErrorQueue" directly on the endpoint, so you wouldn't need to consume the error queue.
Related
Currently I have an IErrorHandler implementation dealing with messages going to the Rebus error queue. That handler then publishes messages to a saga that throttles output to a Slack notification channel. I think there may be an easier way to do this though. I would like to have the saga implement an IHandleMessages against messages from the Rebus error queue itself. Is that possible? Currently, we have the FleetManager process enabled and for my custom IErrorHandler to work it has to dual publish errors both to the error queue and to FleetManager using the FleetManager API options. This allows my IErrorHandler to be called so I can publish a custom message to start the slack saga and also feeds FleetManager with the data it needs. The problem with my approach is that the Rebus error queue just grows with data I no longer care about. So I guess my question is: is there a way to handle those Rebus error queue messages? Or perhaps even better, is there a simple way to make those error queue messages go away once I know I have them in my saga?
Note: the reason for the saga and to not simply use a FleetManager Slack web hook is to notify based on custom count thresholds of errors, rather than for every error encountered.
I think I just realized one approach I could take, which is to still use my custom IErrorHandler, yet not actually handle the poison message so that it never makes it to the error queue regardless. Instead I would just publish my custom message that is handled by the saga.
I am reading through the documentation and the following confuses me because it states at the top of the document with version 5 we get reliability without using the DTC.
These feature has been implemented using both the Outbox pattern and the Deduplication pattern. As a message is dequeued we check to see if we have previously processed it. If so, we then deliver any messages in the outbox for that message but do not invoke message-processing logic again. If the message wasn't previously processed, then we invoke the regular handler logic, storing all outgoing message in a durable storage in the same transaction as the users own database changes. Finally we send out all outgoing messages and update the deduplication storage.
I'm sure it's probably due to my lack of understanding, but wouldn't the fact that NServiceBus is opening it's own connection and transaction separate from the message handler (ex; calling repository for saving) database connection the transaction would be escalated to a full 2PC using the DTC?
Here is the documentation:
http://docs.particular.net/nservicebus/outbox/
Thanks!
Yes, it would. Which is why it shares them with you instead.
NServiceBus expose these to you in the message handlers so you can reuse them and avoid the escalation.
Simply take a dependency on NHibernateStorageContext
in your message handler constructor and it gives you access to the correct NHibernate.ISession and NHibernate.ITransaction.
I need to implement a logic on Retry. Inbound endpoint pushes the messages to Rest (Outbound). If the REST is unavailable, I need to retry for 1 time and put it in the queue. But the second upcoming messages should not do any retry, it has to directly put the messages in to queue until the REST service is available.
Once the service is available, I need to pushes all the messages from QUEUE to REST Service (in ordering) via batch job.
Questions:
How do I know the service is unavailable for my second message? If I use until Successful, for every message it do retry and put in queue. Plm is 2nd message shouldn't do retry.
For batch, I thought of using poll, but how to tell to poll, when the service becomes available to begin the batch process. (bcz,Poll is more of with configuring timings to run batch)?
Other ticky confuses me is - Here ordering has to be preserved. once the service is available. Queue messages ( i,e Batch) has to move first to REST Services then with real time. I doubt whether Is it applicable.
It will be very helpful for the quick response to implement the logic.
Using Mule: 3.5.1
I could try something like below: using flow controls
process a message; if exception or bad response code, set a variable/property like serviceAvailable=false.
subsequent message processing will first check the property serviceAvailable to process the messages. if property is false, en-queue the messages to a DB table with status=new/unprocessed
create a flow/scheduler to process the messages from DB sequentially, but it will not check the property serviceAvailable and call the rest service.
If service throws exception it will not store the messages in db again but if processes successfully change the property serviceAvailable=true and de-queue the messages or change the status. Add another property and set it to true if there are more messages in db table like moreDBMsg=true.
New messages should not be processed/consumed until moreDBMsg=false
once moreDBMsg=false and serviceAvailable=true start processing the messages from queue.
For the timeout I would still look at the response code and catch time-outs to determine if the call was successful or requires a retry. Practically you normally do multi threading anyway, so you have multiple calls in parallel anyway. Or simply one call starts before the other ends.
That is just quite normal.
But you can simply retry calls in a queue that time out. And after x amounts of time-outs you "skip" or defer the retry.
But all of this has been done using actual Mule flow components like either:
MEL http://www.mulesoft.org/documentation/display/current/Mule+Expression+Language+Reference
Or flow controls: http://www.mulesoft.org/documentation/display/current/Choice+Flow+Control+Reference
Or for example you reference a Spring Bean and do it in native Java code.
One possibility for the queue would be to persist it in a database. Mule has database connector that has a "poll" feature, see: http://www.mulesoft.org/documentation/display/current/JDBC+Transport+Reference#JDBCTransportReference-PollingTransport
I am using RabbitMQ version 3.0.2 & I see close to 1000 message in Error queue. I want to know
At what point messages are moved to the error queues?
Is there a way to know why a certain message is being moved to an error queue?
Is there any way to move message from error queue to normal queue?
Thank you
a) they fail to deserialize or b) the consumer throws an exception processing that message five times
Not really... If you peek at the message in the queue, the payload headers might contain a note but I don't think we did that. If you turn logging on (NLog, log4net, etc) you should be able to see the exceptions in your log. You'll have to correlate message ids at that point to figure out exactly why.
There is no built in way via MassTransit. Mostly because there doesn't seem to be a great, generic way to handle this. Everyone wants some process around this. Dru did create a BusDriver app (in the main MT source repo) that could be used to move messages back to the exchange in question. This default behaviour is there so you at least know things have been failing if you don't put in the infrastructure to handle it.
To add to Travis' answer, During my development I found some other reasons for messages going onto the error queue:
The published message type has no consumer
A SAGA and a consumer are expecting the same concrete message type. Even if you try and differentiate using "Accepts" and ".Selected", both a SAGA and a Consumer should not be programmed to receive the same message type.
I have a requirement for an endpoint to receive commands from a client and also to subscribe to events from another endpoint such as:
1- the received command is tried only once then sent to the error queue if an exception occurred
2- the received event is tried indefinitely until it is processed
Could the MaxRetries bet set differently depending on the message type?
NServiceBus MaxRetries setting is to handle things like deadlocks, so not really what you want for this scenario.
What you want is to use SLRs to handle this situation.
To filter based on an exception type, have a look at http://andreasohlund.net/2012/09/26/disabling-second-level-retries-for-specific-exceptions/
Hope this helps!
I looked into NSB source and I notice that MaxRetries can't take different values for different messages in NSB 3.3. Happily you can override class that forward messages to error queue and implement your own version that checking if failed message is event and then instead forward to error queue you can send it again to current endpoint.