Selective change notification for multiple clients (C#) - c#

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.

Related

MediatR publish and MediatR send

I have tried the CQRS pattern using MediatR and am loving the clean state in which applications am working on are transforming.
In all the examples i have seen and used, I always do
await Mediator.Send(command);
It's been same for the queries as well
var data = await Mediator.Send(queryObject);
I just realized there's Mediator.Publish as well which after searching seems to me to be doing the same thing. I am trying to understand what the difference between the Mediator.Send and Mediator.Publish is.
I have read the MediatR library docs and I still don't understand what the difference between these are.
Kindly help me understand the difference.
Thanks for your help
MediatR has two kinds of messages it dispatches:
Request/response messages, dispatched to a single handler
Notification messages, dispatched to multiple handlers
Send may return a response, but do not have to do it.
Publish never return the result.
You are sending requests (sometimes called commands) by _mediator.Send({command}) to exactly one concrete handler. It may be e.g. command that saves a new product to the database. It is often a request from the user (frontend/API) or sometimes it may be internal command in your system given by other service in a synchronous way. It is always expected that the command will be executed immediately and you will receive some proper result or error to immediately inform the client about some failures.
You are publishing notifications (often called events) by _mediator.Publish({event}) to zero, one or many handlers. You used notifications when you want to publish some information and you do not know who needs that. E.g. NewProductEvent which is published after successfully adding product to your Warehouse Module. Few other contexts want to subscribe the information and e.g. send email to a client that a new product is available or create some default configuration for the product in your Store Module (which payment and delivery are available for the product). You may use notifications in a synchronous way. All data will be saved in one transaction (product and store configuration) or you may use some async pattern with service bus or/and sagas. In the second case (asynchronous) you must manually handle cases when something wrong happens in other services or contexts which subscribe to your notification.
Example scenario: Default configuration was not created.
If you have one transaction (synchronous way) for a few contexts, you will receive an error, log the error and return it to the user/client.
In an asynchronous way, you send events after saving a new product to the database. You do not want to have the product in a half-error state in your system. So firstly I recommend creating it in the Draft state and wait for an event that informs you about the successfully created configuration and then changes the state to e.g New/Correct etc.
A good example of using mediatR you will find in e.g. Ordering microservice in EShopOnContainers by Microsoft: github. You will see an example usage of CQRS and DDD with EF core and ASP Net.

does SqlDependency lock table?

I want to use SqlDependency in my project, but the table that I want dependency is being used by several programs for very important purposes. So they have to be able to insert this table while SqlDependency in action. Is that possible?
I've read this question but didn't find my answer.
To answer your question, SqlDependency will not 'lock' the table, but may increase lock contention in high-write environments as it uses the same mechanism as indexed views to detect changes to underlying data.
However, it should be a good fit unless:
The frequency of changes is likely to be high. To define 'high', you really need to test your ecosystem, but a suggested guideline is that if your data changes many times per second, it's probably not a good fit as you: the response time is not guaranteed for SqlDependency, and the callback mechanism is not designed to reliably handle many concurrent changes where you need to be notified of every change. In addition, the SqlDependency can increase blocking/contention on the underlying table as the index used to keep track of changes can form a bottle-neck with a high frequency of writes.
You are intending to build the SqlDependency into a client application (e.g. desktop app) which accesses the database directly, and of which there will be many instances. In this case, the sheer volume of listeners, queues and messages could impact database performance and is just inefficient. In this case you need to put some middleware in between your database and your app before thinking about SqlDependency.
You need to be reliably notified of every single change. The mechanism underlying SqlDependency within SQL Server will generate a notification for every change, but the .NET side of things is not inherently designed to handle them in a multi-threaded way: if a notification arrives while the SqlDependency's worker thread is already handling another notification, it will be missed. In this case, you may be able to use SqlNotificationRequest instead.
You need to be notified immediately of the change (i.e. guaranteed sub-second). SqlDependency is not designed to be low-latency; it's designed for a cache-invalidation scenario.
If SqlDependency is not a good fit, have a look at the Planning for Notifications and underlying Query Notifications pages on MSDN for more guidance and suggestions of alternatives. Otherwise see below for a bit more detail on how to assess performance based on the underlying technologies at play.
SqlDependency largely relies upon two key SQL Server technologies: query notifications (based on indexed views), and service broker. It effectively hooks into the mechanism that updates an indexed view whenever the underlying data changes. It adds a message to a queue for each change, and service broker handles the messaging and notifications. In cases where the write frequency is very high, SQL Server will work hard to handle the writes, keep its 'indexed view' up-to-date, as well as queueing and serving up the many resulting messages. If you need near-instant notification, this may still be the best approach, otherwise have a look at either polling, or using an After Update trigger which perhaps uses Service Broker as suggested on MSDN.

Multiple Clients on 1 server

I am new to GUIs, and i have encountered a problem in my client-server program.
My program is like a "customer-support", where multiple clients can use it from different computers simultaneously.My problem is that when one client changes some info, its inserted into the db but the other client will not see it unless I add a "Refresh" button to my gui.
I want the gui to be dynamic and react to different clients actions. How can you come over this issue?
EDIT:
1. .net4,
2. sql-server,
3. The actions happends after a button click
Basically, you have two options: push or poll. Push (some central server announcing the change to all the listeners) is more immediate, but demands suitable infrastructure. It also depends on the number of clients you need to support, and how many events are passing through the system. Personally, I'm a big fan of redis pub/sub for this (it is actually what we use for the live updates here on stackexchange, coupled with web-sockets). But in some cases you can get the database to provide change notifications directly (personally I prefer not to use this). You may also be able to use events over something like WCF from a central app-server, but that depends on there only being one app-server, which doesn't sound like a good idea to me.
The other option is polling - i.e. have the application automatically query the system periodically (every minute perhaps) to see if the data being displayed has changed. If you can, using the timestamp/rowversion is a cheap way of doing this.

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...

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