Queuing mechanism for server-side AJAX requests - c#

I have been struggling with a situation on a site where users' clicks generate AJAX requests, e.g. with some visual effect when the response comes. It sometimes happens that the user doesn't wait until the request is done (although he sees a loading indicator) and starts clicking other elements like crazy. Because in principle I cannot and don't want to disable that possibility, I have tried (more or less successfully) to ensure that anytime a new request is fired, the previous one is aborted (client-side) and its handlers are no longer called - whichever request comes last wins.
Although somewhat successfull on client-side, I'm now wondering whether there is some way to simulate a similar behavior at the server. As I cannot really kill the previous request, only disconnect from it, it will still run to the end and consume valuable resources. If the user clicks on 20 elements, he will only see the result of the very last request, but there will still be 20 requests on the server wasting the CPU doing useless work.
Is there some way to implement a last-win strategy for multiple requests of the same resource in the ASP.NET / IIS ? I guess the requests are anyway internally queued, and what I would need is for the IIS when it tries to dequeue the next one, simply have a look whether there are some others and only serve the very last one from the same session.

I know that in ASP on IIS you could test for isClientConnected and abort if client had disconnected.
I believe something similar would exist in most plattforms.
But I do not know how it works with ajax?

Related

How would I run a continuous task on an ASP.Net Server?

I've tried researching this, but haven't found much that sounds similar to something I'm needing to implement. In short, we'll be running an ASP Website on a server that will be accessed by clients. Ideally, we have a function that we want to initialize upon the start of a user's session, and stop when the session ends. While the session is happening, this function sends and receives messages via socket communication, meaning we need to access the send/receive functions of this class from pages in order to move information. What's the best way to go about this?
Look into SignalR. That's probably what you're wanting. Its "hubs" are effectively what you're looking for to spin up on session initiation, and spin down when the user disappears. It has a client-side JS library that automatically chooses the best connection method available (e.g., websockets > server-sent-events > long-polling), and it allows you to send messages both from the client to the server, and from the server to the client.
http://www.asp.net/signalr
Another alternative that I've played around with in the past is XSockets:
https://xsockets.net/
It's similar to SignalR in many respects, but it's not free.
It's hard to tell from you description, are you looking to communicate with the client browser via sockets? Or are you trying to communicate with some other service via sockets?
Web applications are not ideally suited for deterministic types of actions. It's difficult for the web server to know whether or not the client has actually closed their browser or not. In most cases, sessions simply time out after a period of inactivity (20+ minutes in most cases). So you cannot reliably know when the users session has actually ended.
To top it off, there are certain edge cases where Session_End will not fire. For instance, if the app pool recycles, then no Session_End event will fire. This may not be an issue, since if the app pool recycles your other connections would also recycle, but it's still an issue to keep in mind.
Finally, Web apps are not intended to be long running.

Asp.net Kill request after session is closed

I searched threads here and couldn't really find what I wanted. I know asp.net web forms is an old technology, but I need to work on it for now. Let's say I have a method which does some heavy processing. For example, there is a function which creates 300 PDF Invoices, zip it and downloads it to user computer.
Sample Code:
for(int i = 1; i <= 300;i++)
{
PrintPDF(i);
}
Now let's say PrintPDF takes about 30 seconds to print one record, so it will take around 150 minutes to print 300 PDFs. Now from a user point of view, I may choose to quit in between if I don't like. If user closes the browser then
Does the request to print PDF get aborted instantly after user closes the session?
If it doesn't, what can we do to ensure that the request is immediately aborted as soon as user closes the browser.
Http is stateless. That means you can never relay on fact that you'll get notification when user is closing the browser. However you can always implement Dead man's switch. I.E. make a javascript that will send pings to your server every ten seconds or so & treat user that haven't sent "ping" for more than twenty seconds as logged of. As for heavy processing on server side - that's really unfortunate way to go; for instance ASP.NET have maximum time it can spend serving request - check executionTimeout of httpRuntime web.config element (by default 110s). You can increase this value of course - but the application pool can be recycled anyway and also if there will be lot of requests on "heavy processing" you can run out of available processing threads. If the site is accessible over internet that is also great place for DDos attack.
Better way is to create queue (in db/cloud) and windows service that will process this queue asynchronously. Still you can implement this "force kill request mechanism" by storing "close" flag in queue item that will service check periodically & will stop processing if it is set.
Other workaround is to use websockets (SignalR).

how to make web service run to finish even if user leaves page

I have a website where I need to take a bit of data from the user, make an ajax call to a .net webservice, and then the webservice does some work for about 5-10 minutes.
I naturally dont want the user to have to sit there that whole time, so I have made it an asynchronous ajax call to the webservice, and after the call has been sent, I redirect the user to a "you are done!" page.
What I want to happen is for the webservice to keep running to finish--and not abort--after it receives the information from the user.
From my testing, this is more or less what happens, but now I'm finding that this might be limited by time? I.e. if the webservice runs past a certain amount of time, it will abort if the user isnt still connected.
I might be off here in this assessment, but this is what I THINK is going on from my testing.
So my question is whether with .net web services, if this is indeed what happens? Does it get aborted after some time if the user isnt still on the other end? Is there any way to disable this abort?
Thanks in advance!
when you invoke a web service, it will always finish its work, even if user leaves the page that invoked it.
Of course webservices have their own configuration and one of them sets timeout.
If you're creating a WCF service (SOAP Service) you can set it in its contract (changing binding properties), if you're creating a service with WebApi or MVC (REST/Http Service) then you can either add to its config file or programmatically set in its controller as it follows.
HttpContext.Server.ScriptTimeout = 3600; //Number of seconds
That can be a reason causing webservice to interrupt its work but it is not related to what happens on client side.
Have a nice day,
Alberto
Whilst I agree that the answer here is technically correct, I just
wanted to post a more robust alternative approach that avoids some of
the pitfalls possible with your current approach such as
Web Server being bounced during the long-running processing of request
Web Server App pool being recycled during processing
Web server running out of threads due to too many long-running requests and not being able to process any more requests
I would recommend you take a thoroughly ansynchronous approach and use
Message Queues (MSMQ for example) with a trigger on the queue that
will execute the work.
The process would be:
Your page makes Ajax call to the Webservice
Webservice writes a message into the Queue and returns right away. The message contains details of what work needs to be carried out.
User continues on your site as usual, or goes home, etc.
A trigger on the Queue is watching for messages and when a message
arrives in the queue, it activates a process which:
Reads the message
Performs the necessary work
Updates any back-end storage, etc, with the results of the work
This is much more robust because it totaly decouples the Web service from any long-running work and means that if the user makes a request and the web server goes down a moment later (for whatever reason) then the work will still be queued up when the server comes back online, etc.
You can read more about it here (MSMQ is the MS Message Queue tech; there are many others!)
Just my 2c

Webservice response time After Idle Timeout

I have a webservice which returns the content of a pdf.
I've noticed that when I've left the website for a while and I call the method of the service it takes a long time to respond. Any subsequent calls take less than a second which is great.
Can someone tell me why this is? Has the service gone to sleep and needs to reinitialise?
What would be a good way around this? Is there something I could do each time that page gets visited to tell the service a request could come through very soon?
I'm assuming you're hosting the service in IIS.
Like any other web-based application, the AppDomain in which the service runs can be recycled for several reasons. One possible reason is an idle timeout.
If you don't want it to time out due to idleness, you can change the IIS settings appropriately.

.NET 3.5 - Calling a webservice asynchonously multiple times from a WPF app

Following on from my previous question [link text][1] , I have a new problem.
I have a WPF application that will call a webservice. This web service will be called asynchronously by pushing the 'GO' button. The results may take 30 seconds or so to come back.
The issue is that I want the users to be able to click the 'GO' button as many times as they like to issue multiple requests.
What I dont want is for the client to open up a new connection to the webservice every time the button is pressed. The web service method is very simple:
invokeExecutionRequest(int executionID)
This method just returns a flag specfying success or failure of the execution request.
Now if possible I dont really want to queue these requests on the client, because a queue has already been established on the server. What is the most elegant way to achieve this?
If you are using WCF for communication to your web service then you can control the connection open/close:
Have one universal WCF connection (likely a global variable for the scope of the window)
On each click of the Go button, check if the connection is open. If not open the connection, if it is then there is nothing to do.
At some logical point (closing the window, doing some action that means Go wouldn't be clicked) close the connection.
I ended up just using BackGroundWorkers to fire off the web service requests. I think we are still openining multiple connections this way, however the number of requests is not large and we are considering changing our architecture so that one master request sent to the queue handler can initiate all other requests.
If I had more time to solve this I think WCF would have been the best option.

Categories

Resources