Wikipedia states that message queue can be configured in among others in following particular aspects:
"Delivery policies - do we need to guarantee that a message is delivered at least once, or no more than once?"
"Queuing criteria - when should a message be considered "enqueued"? When one queue has it? Or when it has been forwarded to at least one remote queue? Or to all queues?"
"Message filtering - some systems support filtering data so that a subscriber may only see messages matching some pre-specified criteria of interest"
"Receipt notification - A publisher may need to know when some or all subscribers have received a message."
Tell me please where can I configure these aspects when using Rebus with MSMQ or RabbitMQ?
UPDATE:
I wanted yet to ask about one more feature:
"Batching policies - should messages be delivered immediately? Or should the system wait a bit and try to deliver many messages at once?"
The Wikipedia article describes common traits of message queues, i.e. features that may/may not be available on a given message queue implementation.
When you configure Rebus to use MSMQ and RabbitMQ as the transport, it will default to settings that have the following properties:
Delivery policies: Strict at-least-once all the way through. That's the best guarantee a queueing system can give, because exactly-once would require that the queueing system could work in the same transaction as whatever work you're doing, and that is impossible (at least generally).
Queueing criteria: Rebus considers a message enqueued when it has been delivered to the queueing system without any exceptions. Both with RabbitMQ and MSMQ, Rebus will send all outgoing messages in the same queue transaction as was used when receiving the message, and thus the receive/send operation can be committed atomically to the queueing system.
Rebus defaults to using RabbitMQ with message durabilit ON, which means that messages are considered delivered when RabbitMQ has then written to disk. RabbitMQ may/may not have some extra durability options that I am not aware of, so it might be possible to configure your RabbitMQ server to replicate messages to other nodes.
With MSMQ, the message is considered delivered when it is written to disk. Since MSMQ operates locally, that means that the message is always stored locally before it is forwarded to the (possibly remote) receiving message queue.
Message filtering: With Rebus there's currently no way of "filtering" messages, other than subscribing to the message types of interest.
Receipt notification: Rebus does not support any kind of receipt - it is assumed that the queueing system is reliable and durable (which it is, because Rebus only uses its transports in a reliable and durable manner) - therefore, all messages are sent in a fire-and-forget-manner.
You are free to use bus.Reply
though, if you want to implement some kind of receipt mechanism yourself.
Conclusion: These things cannot (and most likely should not) be tweaked when using Rebus - Rebus uses its transports in certain ways in order to provide its delivery guarantees, and you might accidentally break that if you circumvent it.
I hope that helps :)
.
Amendment regarding delivery policies - does the at-least-once guarantee mean that the receiving end must check whether a given message has been received before:
Yes, in some cases it does - but it depends on the nature of the work you're performing on the receiving end.
In some cases, you may be lucky that the operation is idempotent in itself and thus it does not matter whether that operation is performed 1 or more times.
In other cases, you might need to e.g. store domain information like timestamps, or maybe even a bunch of IDs of handled messages, in order to make your endpoint work in an idempotent manner.
It should be noted though that Rebus always handles your message in a queue transaction, and if you do your own work in e.g. a database where you can roll back your work in the case of an exception, then everything gets rolled back as it should.
The only case where Rebus will end up delivering the same message twice is when the following sequence of events occurs:
In this case, the message will be delivered again some time later. With Rebus on a queueing system like MSMQ, where all inter-process communication is between local processes, this sequence of events is very unlikely to occur.
It should be noted though that if your data is important enough and the consistency is paramount, you must always make your endpoint idempotent in one way or another.