Check database for changes via long polling - asp.net

Im creating a chat app in ASP.NET MVC3.
im using long polling and AsyncController to do so
when a user posts a chat its saved in database , to retrieve should i constantly check database for change in record or after definite interval
or is there an better/ efficient way of doing it
i came across this question but could not get a usable answer.

You may take a look at SignalR for an efficient way. Contrary to the standard polling mechanism (in which you are sending requests at regular intervals to check for changes), SignalR uses a push mechanism in which the server sends notifications to connected clients to notify them about changes.

Since you're already using long polling and an asynccontrolller, why not create a message pool? Take a look at this solution.
In a nutshell, instead of just writing the updated chat to the database, you should also stick it in some sort of queue. Then each user's async thread is listening to that pool waiting for a message to appear. When one appears return the data to the user through your normal operation. When all listening threads have picked up the message it can be removed from the queue. This will prevent you from having several threads hammering your database looking for a new message.

You can give PServiceBus(http://pservicebus.codeplex.com/) a try and here is a sample web chat app(http://74.208.226.12/ChatApp/chat.html) running and does not need database in between to pass message between two web clients. If you want to persist data in the database for logging sake, you can always subscribe to the chat message and log it to database.

Related

How to handle data replication lag and event notification

We have a simple application, who upon every update of an entity sends out a notification to SNS(it could very well have been any other queuing system). Clients are listening to these notifications and they do a get of updated entity based on these notifications.
The problem we are facing is, when clients do a get, sometimes data is not replicated and we return 404 or sometimes stale data(even worse).
How can we mitigate this while sending notifications?
Here are Few strategies to mitigate this with pros and cons
Instead of sending notification from application send notification using database streams
For example dynamodb streams ans aws lambda. This pattern can be useful in the case of multiregion deployment as well. where all the subscriber, publisher will subscribe to their regional database streams. And also atomicity of sending message and writing to database is preserved. And we wont loose events in the case of regional failure.
Send delayed messages to your broker
Some borkers like activemq and sqs support this functionality, but SNS does not. A workaround for that could be writing to sqs queue which then writes to sns. This might be a good option when your database does not support streams.
Send special error code for retry-able gets
Since we know that eventual consistency is there we can return special error code to clients, so that they can retry based on this error code. The retry strategy should be exponential backoff. but this may mean giving away your problems to clients. Also we should have some sort of versioning in place.
Fetch from another region
If entity is not found in the same region application can go to another region or master database to fetch it. NOTE Don't do this. as it is an anti pattern. I am mentioning it here just for the sake of completion.
Send the full entity in message
If entities to be fetched by rest service is small and there are no security constrain around who can access what, we can send the full entity in message. This is ensure that client don't have to do explicit fetch of it every time a new message is arrived.

Understanding How to Store Web Push Endpoints

I'm trying to get started implementing Web Push in one of my apps. In the examples I have found, the client's endpoint URL is generally stored in memory with a comment saying something like:
In production you would store this in your database...
Since only registered users of my app can/will get push notifications, my plan was to store the endpoint URL in the user's meta data in my database. So far, so good.
The problem comes when I want to allow the same user to receive notifications on multiple devices. In theory, I will just add a new endpoint to the database for each device the user subscribes with. However, in testing I have noticed that endpoints change with each subscription/unsubscription on the same device. So, if a user subscribes/unsubscribes several times in a row on the same device, I wind up with several endpoints saved for that user (all but one of which are bad).
From what I have read, there is no reliable way to be notified when a user unsubscribes or an endpoint is otherwise invalidated. So, how can I tell if I should remove an old endpoint before adding a new one?
What's to stop a user from effectively mounting a denial of service attack by filling my db with endpoints through repeated subscription/unsubscription?
That's more meant as a joke (I can obvioulsy limit the total endpoints for a given user), but the problem I see is that when it comes time to send a notification, I will blast notification services with hundreds of notifications for invalid endpoints.
I want the subscribe logic on my server to be:
Check if we already have an endpoint saved for this user/device combo
If not add it, if yes, update it
The problem is that I can't figure out how to reliably do #1.
I will just add a new endpoint to the database for each device the user subscribes with
The best approach is to have a table like this:
endpoint | user_id
add an unique constraint (or a primary key) on the endpoint: you don't want to associate the same browser to multiple users, because it's a mess (if an endpoint is already present but it has a different user_id, just update the user_id associated to it)
user_id is a foreign key that points to your users table
if a user subscribes/unsubscribes several times in a row on the same device, I wind up with several endpoints saved for that user (all but one of which are bad).
Yes, unfortunately the push API has a wild unsubscription mechanism and you have to deal with it.
The endpoints can expire or can be invalid (or even malicious, like android.chromlum.info). You need to detect failures (using the HTTP status code, timeouts, etc.) when you try to send the push message from your application server. Then, for some kind of failures (permanent failures, like expiration) you need to delete the endpoint.
What's to stop a user from effectively mounting a denial of service attack by filling my db with endpoints through repeated subscription/unsubscription?
As I described above, you need to properly delete the invalid endpoints, once you realize that they are expired or invalid. Basically they will produce at most one invalid request. Moreover, if you have high throughput, it takes only a few seconds for your server to make requests for thousands of endpoints.
My suggestions are based on a lot of experiments and thinking done when I was developing Pushpad.
Another way is to have a keep alive field on you server and have your service worker update it whenever it receives a push notification. Then regularly purge endpoints which haven't been responded to recently.

Difference between web and desktop applications in database access

i have a bit theoretical question.
When creating web applications, there is difference to desktop applications with working and active connection to database. So im curious if there is some solution, which can provide more desktop-like access to database e.g. transactions on asynchronous requests from client (web browser)?
edit:
So i figured out, that there can be a transaction process of asynchronous request, from client. Is there solution, which can provide it in web apps?
e.g I have assynchronou ajax call, which consist of multiple operations, and i wana to process them as transaction. If everything is okay, operations will be all done. But if one of them fail, just rollback it. Like its in DB. Is it possible?
edit2: maybe im wrong and the issue is not about ajax, but about whole web applications, but i dont think there is a way how to make a asynchronnous request from web client.
Transaction need continuous connection to database. To make it work with web application you need a platform which allow the application to run continuously independent of client request. Java servlet is best fit, php is a no-no. So I asume you will use java servlet.
In java servlet, you can create a db transaction, create an id for it, and then store them in a static variable or in the provided application-wide object, context. Then, return the id to the client.
When the client want to send another request, make it send the id. The application then can locate the transaction variable based on the id. As long as the application doesn't restarted between the two requests, the transaction is still there and active.
Because web application don't know when the user leave the application, you must create a mechanism to check the transactions periodically, and then rollback it if the user leave them for a specified time period.
The database has no knowledge of who is connected outside of authentication.

SignalR with unreliable or paused & reconnected connections?

I'm considering updating an existing site to use SignalR. My site polls a third party service for data changes, does some magic on it, and clients poll it once every few minutes to refresh their view with any updates.
SignalR seems like a great way to eliminate the polling from the client, but I want to know how SignalR handles dropped & reconnected connections, especially with regards to mobile web apps which may have been suspended for some time. Will it automatically negotiate and queue up any updates that were missed in the meantime, or does the client need to resynch from scratch in these cases? I looked but couldn't find any docs on this so guidance would be appreciated.
All this is definitely possible since the client keeps track of the last message id it saw. If it happened to miss messages, it'll get those the next time it goes back to the server (asking for all messages since the last one it saw).
By default the server side of SignalR stores messages in memory (and it purges those every few seconds), but you can change it to persist to some persistent store (see IMessageStore) if you're thinking about clients going offline and catching up.
You could even persist messages yourself in your own app logic while SignalR stores stuff in memory. It really depends on the application.
We haven't added any special support for mobile clients, but you can persist the message id in whatever local storage you need to for your mobile client.
Those details aren't very specific but what you want to do is all possible with SignalR.
Read Understanding and Handling Connection Lifetime Events in SignalR, especially these sections:
How to continuously reconnect - required to recover from a disconnected state;
How to notify the user about disconnections - so your app can not only inform the user, but detect state changes (disconnected, reconnecting, reconnected) to refresh your app's state in other ways.
That document was written in 2014 and basically obsoletes many of the wrong or incomplete StackOverflow SignalR-related questions/answers from the 2011-2012 era.

Saving data in SQL Server database and then sending the email later

I have a data entry and editing form and in every data entry or update event, I have to send an email to a dynamic list of recipients. I have been sending the email as soon as the user clicks the save or edit buttons but am thinking of first saving the data to the database, and then sending the email later. I want to do this partly to improve the response time of the application as the email sending tends to take a long time than desired.
Has any one done some thing some how related to this, is there a better way of implementing something similar or does one know a good tutorial on such.
The email body is html formatted.
You could write a Windows Service that handles sending your emails, then use a Message Queue as the method of passing data from your application to the service. I.e. your applicaiton saves the data, then adds a message to the Queue. The service continually polls the queue for messages, sending each one as an email.
I agree with ck about using a service and a message queue, but there are some alternatives.
One is to use a service that polls the database at a regular interval. This lets you avoid the message queue at the cost of a higher cpu load (the service will do many unnecessary database calls).
You could also do this directly in the database using either a database trigger or a scheduled job in the database. The latest versions of SQL Server supports running stored procedures written in C# or Vb.Net so you could probably reuse much of your existing code here.
Finally you could go for a simple solution where you do the email sending on a separate thread in your asp.net application. This way you avoid the need of a service application and you can reuse your code more or less as it is today.
One way to do this is write to the database, and then put a message on a queue that tells an email service (written as a Windows service) that there are emails to send. The email service then talks to the database to find what it actually needs to do. This decouples the email service from the web application and also avoids polling.
This is slightly different to ck's solution in that the queue message is used as a trigger rather than containing the email information. This decouples the web app and the email service to some extent, and means the email service can be reused by multiple clients without each client having to observe (and keep in step with) the same email message format.

Resources