Search code examples
rebus

Rebus transport, MSMQ / SQL


While publishing in Rebus, if MSMQ is not running or some other errors in MSMQ service, it throws exception. Is there a built-in solution (in Rebus) to check before publishing? Or I must use .Net Service Controller?

About using SQLServer as transport, how is the performance and reliability in WAN? how does Rebus do it? Is there some sample code or something?

Transport(t => t.UseMsmq...)
Transport(t => t.UseSqlServer...)

Solution

  • While publishing in Rebus, if MSMQ is not running or some other errors in MSMQ service, it throws exception. Is there a built-in solution (in Rebus) to check before publishing? Or I must use .Net Service Controller?

    If I were you, I would simply try to await bus.Send(..) and then catch any exception that might be thrown by that. This way, you will be much better covered in terms of types of errors handled, plus it avoids the race condition you would otherwise experience(*)

    I have no general recommendation on what to do when an exception is caught in this case.

    Often the risk is low enough that it doesn't make sense to actually build a mechanism that can overcome it, as you could probably get away with logging the contents of the message you intended to send as an ERROR and than have someone handle it manually.

    But sometimes it might make sense to build some kind of "local outbox" or something that can be used to temporarily store messages that could not be sent. But as MSMQ is a locally running service, which you can monitor like you monitor all other Windows services, and there is no remoting involved when communicating with it, you can make it more reliable than almost anything else.

    About using SQLServer as transport, how is the performance and reliability in WAN? how does Rebus do it? Is there some sample code or something?

    Using SQL Server as the transport can work OK if your requirements are modest. SQL Server is not really a message queue, and it doesn't handle long queues (as in 10s or 100s of thousands of messages) well, as the queue length affects receive performance.

    Moreover, it WILL require you to do remoting, both when you send and receive messages, so my guess is that you will have a hard time making it as reliable as MSMQ when you send (it doesn't matter that much when receiving, because the endpoint will simply recover when a connection is restored again after an outage – but when you SEND the first time, probably in a web request, you really want the transport to be able to take care of the message).

    There's a bunch of samples in the samples repository, and the Rebus.SqlServer repository has a couple of tests that might be interesting to look at if you want to use SQL Server for everything. E.g. the TestSqlAllTheWay test is fun IMO :)


    (*) If you did this:

    1. Check if MSMQ is there
    2. Send

    you would get an exception anyway if MSMQ stopped/broke/whatever right between 1 and 2.