Long HTTP POST Response Time - http

I have a web app that has some fairly hefty data processing on the backend. A current example workflow is:
User POSTS a form
Server receives form, starts processing
2-4 minutes pass
The server responds
The reason i'm asking this is that initially a web proxy on the user side was killing idle POSTs after 2 minutes. The more I think about it the more this seemed like a reasonable default.
This leaves the question, should I increase the timeout and not fix the problem? Or is this bad practice? It is currently at 2-4 minutes but could easily get longer. Should the application be responding with something rather than just leaving the connection open? If so other than completely redesigning the UI to be asynchronous submit/check back later what options are there?

Generally, if I were to submit a form and it would take that long, I would think something would have gone wrong and attempt to submit again. I think that you should collect the data and give the user some sort of success message. Then create another page that allows them to check on the status of the processing (if the user needs to get the results from that processing).

Related

Should POST data have a re-try on timeout condition or not?

When POSTing data - either using AJAX or from a mobile device or what have you - there is often a "retry" condition, so that should something like a timeout occue, the data is POSTed again.
Is this actually a good idea?
POST data is meant to be idempotent, so if you
make a POST to the server,
the server receives the request,
takes time to execute and
then sends the data back
if the timeout is hit sometime after 3. then the next retry will send data that was meant to be idempotent.
The question then is that should a retry (when calling from the client side) be set for POST data, or should the server be designed to always handle POST data appropriately (with tokens and so on), or am i missing something?
update as per the questions - this is for a mobile app. As it happens, during testing it was noticed that with too short a timeout, the app would retry. Meanwhile, the back-end server had in fact accepted and processed the initial request, and got v. upset when the new (otherwise identical) re-request came in.
nonce's are a (partial) solution to this. The server generates a nonce and gives it to the client. The client sends the POST including the nonce, the server checks if the nonce is valid and unused and if so, acts on the POST and invalidates the nonce, if not, it reports back that the nonce is used and discards the data. Also very usefull to avoid the 'double post' problem by users clicking a submit button twice.
However, it is moving the problem from the client to a different one on the server. If you invalidate the nonce before the action, the action might still fail / hang, if you invalidate it after, the nonce is still valid for requests during the processing. So, a possible scenario on the server becomes on receiving.
Lock nonce
Do action
On any processing error preventing action completion, rollback, release lock on nonce.
On no errors, invalidate / remove nonce.
Semaphores on the server side are most helpfull with this, most backend languages have libraries for these.
So, implementing all these:
It is safe to retry, if the action is already performed it won't be done again.
A reply that the nonce has already been used can be understood as a a confirmation that the original POST has been acted upon.
If you need the result of an action where the second requests shows that the first came through, a short-lived cache would be needed server-sided.
Up to you to set a sane limit on subsequent tries (what if the 2nd fails? or the 3rd?).
The issue with automatic retries is the server needs to know if the prior POST was successfully processed to avoid unintended consequences. For example, if each POST inserts a DB record, but the last POST timed out after the insert, the automatic re-POST will cause a duplicate DB record, which is probably not what you want.
In a robust setup you may be able to catch that there was a timeout and rollback any POSTed updates. That would safely allow an automatic re-POST. But many (most?) web systems aren't this elaborate, so you'll typically require human intervention to determine if the POST should happen again.
If you can't avoid the long wait until the server responds, a better practice would be to return an immediate response (200OK with the message "processing") and have the client, later on, send a new request that checks if the action was performed.
AJAX was not designed to be used in such a way ("heavy" actions).
By the way, the default HTTP timeout is 7200 secs so I don't think you'll reach it easily - but regardless, you should avoid having the user wait for long periods of time.
Providing more information about the process (like what exactly you're trying to do) would help in suggesting ways to avoid such obstacles.
If your requests are failing enough to instigate something like this, you have major problems that have nothing to do with implementing a retry condition. I have never seen a Web app that needed this type of functionality. Programming your app to automatically beat an overloaded sever with the F5 hammer is not the solution to anything.
If this ajax request is triggered from a button click, disable that button until it returns, successful or not. If it failed, let the user click it again.

Trigger a series of SMS alerts over time using Twilio/ASP.NET

I didn't see a situation quite like mine, so here goes:
Scenario highlights: The user wants a system that includes custom SMS alerts. A component of the functionality is to have a way to identify a start based on user input, then send SMS with personalized message according to a pre-defined interval after the trigger. I've never used Twilio before and am noodling around with the implementation.
First Pass Solution: Using Twilio account, I designated the .aspx that will receive the inbound triggering alert/SMS via GET. The receiving page declares and instantiates my SMSAlerter object within page load, which responds immediately with a first SMS and kicks off the System.Timer.Timer. Elementary, and functional to a point.
Problem: The alerts continue to be sent if the interval for the timer is a short time span. I tested it at a minute interval and was successful. When I went to 10 minutes, the immediate SMS is sent and the first message 10 minutes later is sent, but nothing after that.
My Observation: Since there is no interaction with the resource after the inbound text, the Session times out if left at default 20 minutes. Increasing Session timeout doesn't work, and even if it did does not seem correct since the interval will be on the order of hours, not minutes.
Using Cache to store each new SMSAlerter might be the way to go. For any SMSAlerter that is created, the schedule is used for roughly 12 hours and is replaced with a new SMSAlerter object when the same user notifies the system the following day. Is there a better way? Am I over/under-simplifying? I am not anticipating heavy traffic now (tens of users), but the user is thinking big.
Thank you for comments, suggestions. I didn't include the code, because the question is about design, not syntax.
I think your timer is going out of scope about 20 minutes after the original request, killing the timer. I have a feeling that if you keep refreshing the aspx page it won't happen - but obviously that doesn't help much.
You could launch a new thread that has the System.Timers.Timer object so it stays alive, and doesn't go out of scope when there are no follow up requests to the server. But this isn't a great idea to be honest - although it might help with understanding the issue.
Ultimately, you'll need some sort of continuously running service - as you don't want to depend on the app pool for this, so I'd suggest a Windows Service running in the background to handle it, which is going to be suitable for a long term solution.
Hope this helps!
(Edited slightly to make the windows service aspect clearer)

Multiple postbacks of ASPX page

I have an aspx page with a simple form to send emails to pre-defined lists of users. On the longer lists the page usually times out before the emails finish sending but this has never been an issue.
Today something weird happened and each user got four emails. In the log I could see three new threads crank up one at a time and start over sending from the beginning of the list.
Any ideas? I absolutely know I didn't intentionally refresh the Web page myself, and certainly not three times. But could the browser (IE8) have done it? Would it post again trying to re-establish a connection when it timed out? Or when I switched back to the browser window from another app? I have never seen behavior like this before.
First question would be whether there is any reason to do a long-running task syncronously, i.e. lock up a thread that should be serving web requests for something that could be done in the background, while the browser sits and waits for a response that its probably not going to get. I'd look into running this asynchronously unless there's a very deliberate reason not to.
Secondly have you looked into creating some kind of locking mechanism such that the process can't be started more than once? I have processes where I add a token to the application cache (and remove it when I'm done) so that if the token exists the process won't run again (the call to the asynch task isn't made), and that does the job. That way it doesn't matter how many clients call your code, you prevent things happening more than they should.

How to use ASP.NET with "Redirect after POST" pattern? [Edited]

I'm trying to implement Redirect After Post for the first time in ASP.NET. Assuming my business objects may take several seconds to a minute to complete, in what order, and what syntax do I use?
For example:
User POST's
Server issues Server.Transfer or Response.Redirect
Server does something that takes a minute or two Thread.Sleep
What is the best way to handle this type of situation?
In this case, it is probably best to just stick with Response.Redirect() so that the user's client is issued a redirect, rather than Server.Transfer() which performs a purely server-side redirect to a different context.
Regarding the process which requires the user to wait, you may want to use some sort of asynchronous implementation where the time-consuming operation is placed in a background thread; meanwhile the user, instead of waiting on a blank loading screen, is given Response.Redirect() to a "Processing" page that polls the server for completion of the current operation and updates the user. For added polish, consider implementing something like Facebook's image uploader which overlays a progress bar in the corner of the screen while the user continues normal use of the website.
From what I can see you need to do:
User POSTs form to server script
Server does something that takes a minute or two using Thread.Sleep
Server issues a Response.Redirect
However, the obvious drawbacks here are that the user is kept waiting whilst the server does some work (two minutes is a long delay period, they may well assume that something has gone wrong), and possibly you might hit a HTTP request time out on the browser.
In terms of code, it's pretty straightforward:
This is a standard <FORM METHOD="POST"> code
Do whatever you need to do, can't see why you would need Thread.Sleep at the moment; wouldn't you want to redirect to happen as soon as your server side processing has completed?
Call Response.Redirect("mypage.aspx") to perform the GET
Does that help?

how to save the compose message text in draft automatically?

we have a vb.net application with send and receive mailing also. Now we have added a session timer of 30 min but the users are complaining that they are facing a problem when they write a long text message or while composing they get busy in something else and when they return back to continue composing message , they are redirected to a session expiry page, and their long text message is gone forever. So I am new to this and I was thinking like , when the user is in compose message the text should be automatically saved to drafts like hotmail.
Any help will be appreciated . Thank you.
There are two basic approaches you can take to this:
The proper "web" way would be to remove the need for session and state from at least this part of the application i.e. set up the application so that its resilient if the session expires and can pick up the necessary user details etc from the post if the session has expired - you can do this with a value stored in viewstate or in a cookie. However this doesn't deal with the problem of saving work in progress.
So the more appropriate solution here will be to investigate AJAX solutions to the problem whereby the page uses client side scripting to transparently "save" (post) the message text back to the server at defined intervals. This has the further advantage of prolonging the session as well.
Of course with the AJAX solution your back end data management becomes more complex too... but it that's manageable (limit it to one draft in progress and remember to clear out the draft on "send" and you should be fine) and you may still want to consider some degree of additional resiliency for loss of session for other reasons.

Resources