NServiceBus: Can I limit the endpoints to which an Event is send - c#

I have a doubt about sending/publishing NServicebus events and commands.
Commands seem pretty straightforward. According to the documentation they "They should be sent direct to their logical owner." So I guess the destination is decided either by the defined routing, or by the overriding the default routing:
using options.SetDestination("MyDestination")
So far I am correct?
But I am not sure I am understanding how events actually work:
"An event, on the other hand, is sent by one logical sender, and received by many receivers, or maybe one receiver, or even zero receivers. This makes it an announcement that something has already happened."
Does that mean that an event would be processed by ANY endpoint that implements IHandleMessages[SomethingHappened]? Regardless of the routing configuration? I mean if I have these endpoints A,B,C,D,E and A is configured to send to B can still C,D,E get the event? What If I have no explicit routing configuration because I am using options.SetDestination to send my commands? There is any way to say I want this Event to be published only to D and E?
Thank you for any light you can shed on this subject.

Commands require routing. A command is always destined for a specific endpoint to be processed as there's an expectation for the outcome and knowledge of what destination can process the command at hand.
Events have no routing. Events are notifications about something that already happened. Anyone can receive and process events. It won't change the outcome of what has happened in the first place, causing the event to be raised.
An event can be analogous to a radio broadcast to understand the 'how' part and why routing is unnecessary. When a radio station is broadcasting, the radio host doesn't know who'll be tuning in to listen. Listeners can tune in (subscribe) and tune out (unsubscribe). All these listeners (subscribers) need to know the radio station frequency (a 'topic' or 'exchange') where the broadcast is taking place (events published to).
To sum it up - events are notifications, allowing loosely coupled distribution of events among endpoints. It's subscribers that choose wherever to receive events or not, not the publisher.

Related

How to guarantee delivery of messages in MassTransit?

I'm trying to figure out how to implement a fault-tolerant message publication solution using MassTransit. We'll focus on the simple scenario where we only need to commit a database change, and publish an event indicating that change. Because there is no (built-in) mechanism that allows an atomic "commit and publish", when our process crashes, we will get into an inconsistent state (some messages would only be committed to the database, and some might only be published to the message queue).
This documentation page offers a solution, where because we assume message handling is idempotent, we can rely on the entire operation to be retried in case of failure, and these partial commits will be resolved eventually. This is a great solution, but it only has one caveat: it assumes that the operation we are performing was triggered by a message, and if we won't send an ack, processing will be retried. This is not a reasonable assumption, as messaging is typically used only for internal communication inside the system, not for communication with the outside world. What should I do when I need to save-and-publish when handling an HTTP request from an external client?
One possible solution is to hack our way into the approach presented in the article, by only publishing (or sending) a message, and listening to it ourselves, then in the message handler we do the commit and the publishing of the actual event we want others to listen to. The main problem I have with this is that it assumes we never have to return anything in the HTTP response. What if we need to indicate the success or failure of the database transaction back to the HTTP client? (example: if we rely on a UNIQUE constraint to tell us whether or not we should accept the request, and we want to indicate failure to the client). We could solve it by using request-response over the message queue (with ourselves), but this is ugly and increases latency and complexity considerably, for what is actually a very common scenario.
The approach I see the most over the internet to solve this problem, is to use an outbox that is persisted to the same database we need to write to anyway, and thus we can wrap the two operations in a regular ACID database transaction. Then a background task polls this database for new events and publishes them to the message broker. Unlike other frameworks, I understand that MassTransit does not support this behavior out of the box. So I guess my question boils down to: before rushing to implement this relatively complex mechanism myself (once per database technology), is there another solution I'm missing? what is the accepted solution to this problem in the MassTransit community?
This has been asked several times, in a variety of forms, here and other places. But the short answer is simple.
In your controller, write to the message broker only. Let the consumer deal with the database, in the context of consuming a reliable message, with all the nice retry and redelivery options that are available in that context. Then you get all the benefits of the InMemoryOutbox, without adding extreme complexity related to having a third-party (HTTP, database, and broker) in a single conversation.

NetworkInformation NetworkStatusChanged event fired twice

I am listening for a network change in my WinRT application using what I believe is the recommended approach.
I subscribe to the event using this code. (I have tried in a number of places but currently I have it in the page OnNavigatedTo method).
NetworkInformation.NetworkStatusChanged += NetworkInformation_NetworkStatusChanged;
Then in the OnNvaigatedFrom method I remove it:
NetworkInformation.NetworkStatusChanged -= NetworkInformation_NetworkStatusChanged;
When I remove the network cable the NetworkInformation_NetworkStatusChanged event is fired correctly. However, when I plug back in (go back online) the event is fired twice and my data (stored locally while offline) gets uploaded to the server twice.
Has anybody come across this before/know why it might be happening - its driving me mad.
Many thanks
Chris
I remember this being an issue. Seems like it still is.
http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/520ea5e2-cc17-486d-815e-528ca041d77f/
To solve your problem, keep track of the network availability with a flag and only update if the previous network status was unavailable.
In our testing we found that you will receive the event once per available adapter. We have 5 adapters so every time we plug a cable back in we seem to get an event as many times as there are active (enabled) adapters. We tested this by disabling one of the adapters and the number of the events reduced by exactly one and vice versa. It seems we only get one event for disconnect though.
The other reason for your event to be firing more than once is the fact that your network does actually drops and reconnects.
In any case it's on you to write the code defensively to deal with the reality of the implementation and general unreliability associated with network connections.

NService Bus - Content based routing & auditing - is my approach ok?

I have a little trouble deciding which way to go for while designing the message flow in our system.
Because the volatile nature of our business processes (i.e. calculating freight costs) we use a workflow framework to be able to change the process on the fly.
The general process should look something like this
The interface is a service which connects to the customers system via whatever interface the customer provides (webservices, tcp endpoints, database polling, files, you name it). Then a command is sent to the executor containing the received data and the id of the workflow to be executed.
The first problem comes at the point where we want to distribute load on multiple worker services.
Say we have different processes like printing parcel labels, calculating prices, sending notification mails. Printing the labels should never be delayed because a ton of mailing workflows is executed. So we want to be able to route commands to different workers based on the work they do.
Because all commands are like "execute workflow XY" we would be required to implement our own content based routing. NServicebus does not support this out of the box, most times because it's an anti pattern.
Is there a better way to do this, when you are not able to use different message types to route your messages?
The second problem comes when we want to add a monitoring. Because an endpoint can only subscribe to one queue for each message type we can not let all executors just publish a "I completed a workflow" message. The current solution would be to Bus.Send the message to a pre configured auditing endpoint. This feels a little like cheating to me ;)
Is there a better way to consolidate published messages of multiple workers into one queue again? If there would not be problem #1 I think all workers could use the same input queue however this is not possible in this scenario.
You can try to make your routing not content-based, but headers-based which should be much easier. You are not interested if the workflow is to print labels or not, you are interested in whether this command is priority or not. So you can probably add this information into the message header...

MSMQ one (queue) to many (listeners) scenario

I have this scenario: One client sends a message into a msmq queue instance and there are 3 processes which listen on this queue. I want to be able to let every one of those instances pick a different message and process it.
I know that is a common usage scenario for queues and i already have working code for this using MSMQ, .NET and C#.
However i am wondering if msmq is my best option here - the documentation clearly states that MSMQ is meant for "one to one" communication, meaning that there shouldnt be more than one listener.
That kind of leaves me wondering, is what i am doing the right solution for my use case? Or is it the other way round, do i have to create one queue per listener and distribute the messages in a preceeding part of the workflow?
A link to a working example demonstrating the usage of MSMQ in this type of scenario would be greatly appreciated.
Thanks
As I understand it you are using multiple listeners to do something like load balancing. This is an absolutely valid scenario and it is often used in clustered environments or in load balancing scenarios where a single listener is not able to consume all incoming messages. Btw. clustered BizTalk consumes MSMQ messages in the same way.
The one-to-one is meant as one message is passed to one listener but it doesn't mean that each queue can have only single listener. If all listeners do the same processing and it doesn't depend which one will pick the message, it is still one-to-one.
It is also possible to use one queue to deliver one message to multiple listeners. This scenario is not recommended with MSMQ even though it is technically possible with triggers.
If your listeners listen only for messages with some special properties, identifying which listener should consume the message (i.e. you search for messages in the queue), you should definitely use three queues instead.
"the documentation clearly states that MSMQ is meant for "one to one" communication, meaning that there shouldn't be more than one listener."
You have a link for this?
MSMQ uses two delivery methods:
1-1 : one sender, one destination queue
1-M : one sender multicasting to many destination queues
Also, you can have multiple listeners on a queue.
The number of listeners is up to you.
Of course, there will be contention between multiple listeners so if you want messages to be processed only once you need to code/configure for that.
It sounds like you need a service bus - however, they tend to be somewhat heavyweight, so it might be overkill. With a service bus, you can set up publish-subscribe scenarios in which any number of listeners can subscribe to messages. NServiceBus is a service bus that is somewhat simple to use (and it is built on top of MSMQ); there is a free version of it that is capped to 30 messages per second. Rhino ESB also claims to be lightweight.

to pass data around using event handling

Anyone can detail the pros and cons to pass data from one class to another using event mechanism? When is the best time to use event to pass data?
Let's take an example. You have a system where 20 people are subscribed to a weather station for changes in weather. Do you want the weather station to keep track of all the people and services that are subscribed?
In my opinion the weather station should not know anything about the people or services that are waiting for weather changes. The weather station should just dispatch an event, and whoever is listening to it will get notified :-)
So the point is, you use events to notify observers about an action or state change that occurred in the object. Observers can be difference type of objects since you don't have to know anything about them. If someone listens to the object, then he takes care of it.
If it was one to one relation and the object waiting for something to happen is always of the same type, then you wouldn't really need an event for that case.
Events are also great to decouple systems, like seen in my example above with the weather station. The weather station can run on its own without knowing about the services or users that are listening to it.
Using events will among other things:
Decouple the event source from the event receiver
Allow multiple event receivers to subscribe to the same event
Provide a well known pattern for implementing eventing
One thing to be aware of is how delegates may create unexpected "leaks" in your code: Memory Leak in C#.

Categories