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#.
Related
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.
I am trying to understand observer pattern and stuck at one particular point. In my understanding, once an observer subscribes to notify them on any event change, the subscription is stored somewhere and then when event changes the subscriber is notified.
In practical scenarios I should store the values in a database or a file for persistence reasons and inform them once event occurs by getting from db and looping through the list.
Is this correct understanding? I do not see any example involving database but, every example uses list.
And again publisher/subscriber pattern is also similar except with the change that there is no exact knowledge of who the publisher and subscribers are and intermediate technologies like MQ or some sort is used to establish communication between two.
My question is : When we use DB in observer pattern wont it become publisher/subscriber ( except there is knowledge of observers and publishers here). Is it correct understanding?
In most examples for Observer pattern you would see use lists but how that list is initialized depends on your application. For example, application with huge number of subscribers would have to store these subscribers for persistence reasons just like your case. We can't expect such high number of subscribers to be in memory all the time. So the list of observers is initialized from DBs only although not all entries in one go. This is a different discussion altogether.
Secondly, simply by using DB, observer pattern and pub-sub pattern don't become similar. Even using DB, you are simply initializing your list of observers which are to be notified. There is no broker in between which would keep identities of subject and keep observer hidden from the Subject class. Here is good article that explains it nicely:
https://hackernoon.com/observer-vs-pub-sub-pattern-50d3b27f838c
Suppose due to network failure redis went down for some time . How will i figure out after it up. Is there any event that i can subscribe in the Client (StackExchange.Redis ) so that it notifies me?
There are several events on the ConnectionMultiplexer of the StackExchange.Redis client you can subscribe to, for example the ConnectionRestored event, which is probably the one you want.
To use that together with CacheManager, you might want to instantiate the Multiplexer and pass that into the .WithRedisConfiguration part of your configuration.
Then, you can subscribe to all those events.
CacheManager itself doesn't expose those events nor the client. This means, there is no other way to get to those objects then creating the Multiplexer in the beginning.
If you think that this is a feature you need, feel free to add a feature request on GitHub.
Let's imagine I have a hot observable that is a source of weather events. This source is a socket connection to a remote server that provides information about the weather in my current location.
That remote server can also send me events about other related topics as traffic, extreme weather warnings, etc... if I send a command to indicate this desire.
How can I model this with Reactive Extensions without creating coupling between observable and observer?
The idea is that when I subscribe ExtremeWeatherWarnings (observer) to my WeatherServerConnection (observable), somehow the first issue some commands to the second, so it enables the subscription.
I have tried to implement an special interface in the observer, that tells the observable the commands it needs to execute in subscription and unsubscription, but it does not work in the moment I put a Where in the middle because LINQ RX is wrapping the observable, and that wrapper does not implement any interface.
I can also require an instance of the WeatherServerConnection object on the ExtremeWeatherWarnings constructor, but that will create coupling and I would like to avoid that.
Cheers.
If your observables is designed to send generic messages, and your observer is design to translate them, you also need a way of indicating to the producer what kinds of messages you're interested in.
One way to do this is "requesting an observable".
ObservableWeatherSource GetNotifications(WeatherWarnings warningTypes, string location);
Another way might be to lazily indicate what notifications you're interested in.
ObservableWeatherSource source = GetWeatherSource();
source
.Where(x => x.WeatherWarningType === WeatherWarnings.Rain)
.Subscribe(new WeatherObserver());
source.ExpressInterestIn(WeatherWarnings.Rain, "San Francisco");
Or, possibly, you might be interested in writing a specialized query language for weather. You could probably do this through the IQbservable and a query provider, but I have little knowledge of this area of Rx.
It all depends on how you think of your observables.
If it's a stream of events independent of the observers, you can just expose the observable to anyone that want's to subscribe to.
That was the approach I followed on my reactive GeoCoordinateWatcher. The wrapped GeoCoordinateWatcher class will generate events independent of the subscription.
For the reactive Geolocator I chose to follow the same approach. But because the Geolocator needs parameterization to produce events, I could have chosen to implement an observable factory.
The bottom line is (as #Christopher said) that you send commands to something that exposes an observable and not to the observale itself.
You migth do something like sending commands to the observable by applying Rx operators. If those filters are to be applied remotely, you can implement (as #Christopher said) an IQbservale instead.
I need to implement a notification mechanism for a system that has one manager and multiple consumers/clients. A manager should poll a database and fire an event whenever there are changes in the data. Now, it'd be easy if all clients would be interested in the same data, and it would be sufficient to implement a single event and subscribe all clients to that event. However, clients should only receive the events for the data they are responsible for.
For example, there are multiple clients that add new customers. This happens through the manager in a thread-safe way. Now, these clients that created the customers need to know of any changes that happen only to those customers. The manager polls the Customers table every N seconds and gets a list of all customers that changed. Then, the manager will need to "route" (for a lack of a better word) the notifications to the interested clients.
Will this have to be implemented with some sort of a callback that each client will have to supply to the manager? This sounds like something I need, but I dont know how I can pass parameters to this callback (here, these are the customers Im interested in, dont bother me when you have updates for any other customer)
Im using C#, .NET 2.0. Thanks!
This is a good description of the Observer pattern. Typically a client registers interest with the manager for a set of data that is relevant for it, providing a means of notification (this would be your callback). A client may also unregister if it's no longer interested in previously-useful data. Then the manager's job is to propagate changes to all interested Observers (i.e. clients).
In C#, the required infrastructure is available as first-class language features - events and delegates. There is good (if simple) example code here.
In .Net 4 this convenience is taken a step further with ObservableCollection<T> available to automate the notification process.
By the way - I would avoid polling the database if possible. Is there no way you can get notified on the necessary changes in your DB? In C#/SQL Server you can use SqlDependency.