Rebus Publish Exception Handling - rebus

Lets assume rebus could not publish message to rabbitmq or some other queue, what is the best practice to handle this exception.
I stopped rabbitmq service and rebus threw Aggregate exception. I can manually cacth this exception in try - catch block but is there a better solution to catch exceptions when such situations happened ?

First off: If you get an exception when initially sending/publishing a message (e.g. while handling a web request), there's nothing you can do, really. Sorry ;)
You should probably log - thoroughly - all the information you can, and then be sure to set up logging so that the information ends up in a file or in some other persistent log. And then you should have some kind of notification or a process in place that ensures that someone will at some point look at the log.
You should probably have this kind of logging in place, regardless of the type of work you do.
Depending on how important your information is, you could also set up some kind of retry mechanism (although you should be careful that you do not consume threads and too much memory while retrying). Also, since your web application should be able to be recycled at any time, you probably should not rely (too much) on retries.
You can do some things, though, in order to minimize the risk of ending up in a situation where you can't send/publish.
I can recommend that you use some kind of high-availability transport, like MSMQ (because it has local outgoing queues), RabbitMQ (with a shovel on each machine), or Azure Service Bus or Azure Storage Queues if you're in Azure.
Moreover - if you were using MSMQ, and you want to publish an event - I would recommend that you await bus.Send(theEvent) first, and then when you handle the message, you await bus.Publish(theEvent). This is because Rebus (with the MSMQ transport) needs to do a lookup in the subscription storage in order to get all subscribers for the given event. This is not a problem with RabbitMQ though, because Rebus will use Rabbit's topics to do pub/sub and will be just as safe as doing an ordinary send.
When you're sending/publishing from within a Rebus message handler, there is of course no problem, since the receive operation will be rolled back, and eventually the incoming message will end up in an error queue.
I hope that cast some light on the situation :)

Related

In my Rebus handler I am performing a database operation and then send commands to other three handlers

I want to execute database operation in a handler and then send three commands to other handlers.
I want to make sure that all the execution of database operation together with sending commands occur in a transaction and whether all succeed or all fail.
I am using .net core and when I try to do this I get an exception that "This platform does not support distributed Transactions"
I was using RabbitMQ Transport and then SQL server transport but still getting the same problem.
I would like to know the best way to ensure that all the execution is ATOMIC under .NET Core and RabbitMQ or SQL Server transport.
Thanks
I am surprised that you get this particular exception, because Rebus does not participate in distributed transactions (at least not with any of the supported transports, and especially not with RabbitMQ).
Could you maybe update your question to include the full exception details (with stack trace and everything)? And maybe tell a little bit about how you're performing your database operations?

Does gRPC resend messages

A question related to the idempotence of serverside code, or the necessity of it. Either for gRPC in general, or specifically to the java implementation.
Is it possible that when we send a message once from a client, that it is handled twice by our service implementation?
Maybe this would be related to retries when service seems unavailable; or could be configured by some policy?
Right now, when you send a message from a client it will be seen (at most) once by the server. If you have idempotent methods, you will soon be able to specify a policy for automatic retries (design doc) but these retry attempts will not be enabled by default. You do not have to worry about the gRPC library sending your RPCs more than once unless you have this configured in your retry policy.
According to grpc-java/5724, the retry logic has already been implemented. The OP does it using a Map, that is not type safe. A better way would be as follows:
NettyChannelBuilder builder = NettyChannelBuilder.forAddress(host, port)
.enableRetry()
.maxRetryAttempts(3);
There are other retry configurations available on the NettyChannelBuilder.
There's also an example here, although it's pretty hard to find.

Rebus: Check if a message is already on the bus in a deferred state

I'm trying to figure out if rebus supports querying of the queue.
I want to peek in the queue, to find out if a message is already on the queue in a deferred state.
the reason is that we are doing a fairly expensive operation that we want executed once a day and we may have multiple instances of a service, so we want to make sure that we only have on message of this type on the bus.
Is this possible with rebus or should i use the azure service bus api for this?
It's not possible with Rebus :(
To me it sounds more like you want to use some kind of scheduler, e.g. like Quartz .NET, or maybe something you code yourself.
Querying the Azure Service Bus queue sounds like a bad idea to me, because it's kind of backwards, considering that it sounds like you simply want to execute some task daily.
This would suddenly tie you to the ASB transport and its quirks, also tying yourself to the fact that Rebus' deferred messages are implemented using the delayed visibility feature of ASB, thus making your code less portable.
Lastly, I fear that you would run into concurrency issues, because it would not be trivial to avoid race conditions around who gets to put the deferred message into the queue.
If I were you I would code a simple scheduling thing myself, and then have it send Rebus messages periodically as needed.

Architecture Queuing asp.NET - MSMQ

Problem: Some 300 candidates make a test using Flex. A test consist of some 100 exercises. After each exercise a .NET service is called to store the result. If a candidate finishes a test, all the data of his/her test is denormalized by Asp.NET. This denormalization can take some cpu and can take 5 to 10 seconds. Now, most of the times, some of the candidates have finished their test earlier than the rest, but still some 200 of them wait until their time is up. At that moment, 200 candidates finish their test and 200 sessions are denormalized at the same time. At this point, server load (cpu) is too high and cause calls to the webserver to go wrong. Now, instead of all these sessions being normalized concurrently, I would like to add them to a queue using MSMQ.
Question:
How do you process the Queue?
Do you start a separate thread in the Application_Start of global.asax that listens to the queue? If there are messages, they are dealt one at the time.
Is it necessary to do this in a separate thread? What if in the global.asax you just call a singleton for instance that starts listening to the queue? In what thread will this singleton run? (what's the thread that calls global.asax)
What are best practices to implement this? Links? Resources? Tutorials? Examples?
I don't like the idea, but could you put an exe on the root of your website, an exe that starts a process listening to the queue...
If you get a message out of the queue, do you remove it when you pull it out or do you remove it if denormalization for this session was successful? If you remove it when you pull it out and something goes wrong...
I could also create my own queue in memory, but restarting the webserver would empty the queue and a lot of sessions would end up not being normalized, so I guess this is really a bad idea.
Is MSMQ a good choice or are there better alternatives?
You could consider using a WCF-Service with MSMQ transport. I used this approach in an application that calculates commissions:
User completes asp.net wizard configuring calculation parameters
Calculation Job is sent to WCF-Service using MSMQ transport
Service transaction is completed as soon as Job entered MSMQ
New transaction scope is created for processing Job instances
One drawback is that the transaction will require MSDTC which will add some overhead when targeting MS SQL Server and even more when dealing with Oracle.
IDesign provides a lot of useful samples and best practices on WCF queueing.
Personally, I use a servicebus for scenario's like that. I know this sounds like an overkill, but I think the .net servicebusses are so good that they require the least amount of code written by you, because it's not easy to create a good scheduler for background processes without disturbing the threads of the application pool the webapp is running in. NServicebus and MassTransit are both good an well enough documented servicebuses for your scenario. With a servicebus, you have a framework that writes to msmq and listens to msmq in several apps connected by the messagequeue. The bus makes it easy for you to create a separate app that runs as a background service and is connected with your web-app by the message queue. When you use topself (included in nservicebus and masstransit), an installer/uninstaller for the seperate apps is automatically generated by the service bus.
Question: Why don't you like the idea of having a separate exe?
How do you process the Queue?
Do you start a separate thread in the Application_Start of global.asax
that listens to the queue? If there are messages, they are dealt one at
the time.
Is it necessary to do this in a separate thread? What if in the
global.asax you just call a singleton for instance that starts listening to
the queue? In what thread will this singleton run? (what's the thread that
calls global.asax)
[skip]
I don't like the idea, but could you put an exe on the root of your website, an exe that > starts a process listening to the queue...
Normally another program processes the queue - not ASP.NET. Either a windows service or an executable that you run under a scheduler (and there's no reason to put it in the root of your website).
If you get a message out of the queue, do you remove it when you pull
it out or do you remove it if denormalization for this session was
successful? If you remove it when you pull it out and something goes
wrong...
For critical work, you perform a transactional read. Items aren't removed from the queue until you commit your read operation, but while the transaction is open, no other process can get the item.
What are best practices to implement this? Links? Resources? Tutorials? Examples?
This tutorial is a good introduction and John Breakwell's blog is excellent and offers a lot of good links (including the ones in his easy-to-find sidebar "MSMQ Documentation").

Which is better in this case - sync or async web service?

I'm setting up a web service in Axis2 whose job it will be to take a bunch of XML and put it on to a queue to be processed later. I understand its possible to set up a client to invoke a synchronous web service asynchronously by creating a using an "invokeNonBlocking" operation on the "Call" instance. (ref http://onjava.com/pub/a/onjava/2005/07/27/axis2.html?page=4)
So, my question is, is there any advantage to using an asynchronous web service in this case? It seems redundant because 1) the client isn't blocked and 2) the service has to accept and write the xml to queue regardless if it's synchronous or asynchronous
In my opinion, asynchronous is the appropriate way to go. A couple of things to consider:
Do you have multiple clients accessing this service at any given moment?
How often is this process occurring?
It does take a little more effort to implement the async methods. But I guarantee, in the end you will be much happier with the result. For one, you don't have to manage threading. Your primary concern might just be the volatility of the data in the que (i.e. race/deadlock conditions).
A "sync call" seems appropriate, I agree.
If the request from the client isn't time consuming, then I don't see the advantage either in making the call asynchronous. From what I understand of the situation in question here, the web-service will perform its "processing" against the request some time in the future.
If, on the contrary, the request had required a time consuming process, then an async call would haven been appropriate.
After ruminating some more about it, I'm thinking that the service should be asynchronous. The reason is that it would put the task of writing the data to the queue into a separate thread, thus lessening the chances of a timeout. It makes the process more complicated, but if I can avoid a timeout, then it's got to be done.

Resources