Does anyone have any suggestions on what I could do to get my servlet to continue running unaffected by this thread?
[ August 09, 2005: Message edited by: Jason Barker ]
You will receive an email when your process has completed.
And then have the service send an email with a link to the user to pickup where they left off with the 5-10 minutes process completed. Does that make sense? Obviously I don't know your project requirements so you might not have the option of doing this or some similar way.
Originally posted by Jason Barker:
Ha, ha! You're right. This would be silly if the user had to sit at their computer and watch it. Actually, the user would get to this point, submit the information and do other tasks at their desk, while keeping an eye on the computer screen. However, the users who choose to sit and wait until this is done will get fired.
Even so, it isn't very user friendly. What if the user is doing other work on the web and closes the "Standby" page by accident? Seriously, if I had to wait 5-10 minutes and "keep an eye on" the process to complete, I'd be very annoyed. What is this long process anyway?
If you go with the Email notification approach, I suggest you either use Ajax to send the request without blocking for the response, or flush the "You may now close this window" message to the output before doing the timeconsuming operation.
Even so, it isn't very user friendly... Seriously, if I had to wait 5-10 minutes and "keep an eye on" the process to complete, I'd be very annoyed.
I appreciate your concern for the end user's time. However, this process has reduced the time to complete this same task by other means from over two hours to 5-10 minutes. They are quite pleased with this solution. In fact, they prefer to not have to be on their computer so much as other items require more of their attention that do not relate to their computer.
What is this long process anyway?
A bunch of database queries, inserts and updates to process customer data in batches.
...that would be eggregiously bad UI...
That's a matter of opinion. The end users would strongly disagree with you.
...either use Gregg's suggestion of a completion e-mail...
So, they would sit and wait for an email to pop up in their in box. This is what my stand by page does -- notifies the user that something is done...and they only wait at most, 30 seconds longer to know that the process is finished (rather than waiting for mail servers to send and receive the message out over the Internet).
...or provide a status page that users can visit at their own volition to monitor the progress of the operation.
This is part of an input process. A status page adds a longer break to the process.
Back to my issue. I'm trying to figure out how to get my servlet to run again, seeing as how it seems to be stuck with the execution of this thread. Any ideas?
IMO the simplest method would be flushing the output before all the DB calls. The servlet still wouldn't complete until the DB stuff is finished, but the user would get a nice "Please Wait" message that could be overwritten with the output after the DB calls complete.
In your first post you said this page sits there for 5-10 minutes. That was the reason for mine and Bear's UI suggestions. Sorry for not helping with your issue more precisely but sometimes the answers lie not in answering the question you've asked but by suggesting alternative means of reaching a similar goal. I'll bow out from here.
I'll bow out from here.
Don't do that. You might know how to figure this out.
Well, let's say that I can possibly get the wait time down to 1-2 minutes. I would still like to approach this with a "stand-by" page that refreshes itself. However, when the initial view of the stand-by page sends the request back to the web server and then to the servlet, it still hangs. I thought that using a thread to do my background database processing would run independently of my servlet. Instead, it seems to lock me out of the servlet until the thread has completed execution. Is this behavior to be expected? Shouldn't I be able to start the thread and have it run asynchronously with the servlet?
Please help. Thanks.
While I've done thread programming outside of the servlet environment, I've not done any in conjunction with servlets and don't know of any special pitfalls that you need to watch for. It almost sounds like your servlet is blocking waiting for the thread -- which doesn't make a lot of sense for subsequent requests since each should fire in their own thread.
...trying to do something in a way that the protocol wasn't really intended for...
Have you been to priceline.com or orbitz.com? Are you familiar with their "Stand-By" page your are sent to when looking up flights, hotels and other travel plans? Are you saying they have poorly designed web sites, that their process of making the user "wait" is a bad idea? Would you rather plug in your travel dates and then wait a while to be notified via email so that you could go back and check on what it was you were looking up?
If the browser crashes or they close the window accidentally before the process is through, they will re-enter the data from before (the whole process could take about 7 to 12 minutes from start to finish). Also, by restarting the process, any old data gathered from their previous session is cleared out (if it was not successfully completed).
Do we still need to debate your opinion of good/bad UI design or can we address the issue of what could be holding up the servlet?
The response's PrintWriter has a flush() method which flushes the writer's buffer to the output. That means that while the servlet has not finished execute, the user's browser receives a part of the response. Note that flushing commits the response, so you'll get an IllegalStateException if you try to do something that requires an uncommited response (setting headers, cookies, forwarding, etc.)
You could do it like this:
barebones results.jsp :
I haven't actually tested this, but it should work. Unless the browser decides to time out while waiting for the servlet to finish - you'll have to test that. What happens is that there is still only one thread, but the user sees the "Please Wait" message before the thread finishes.
Hope this helps,
1. In the servlet init() method, spawn an engine thread to manage the long-running process.
2. In the webapp, initiate the process when requested by posting a request to the engine. Normally, my engines are single-threaded, but it's also possible to spawn sub-threads if parallelization is an advantage.
Having said that, for something that routinely takes 5 minutes or more, an email notification is not a bad idea.
You can do variations on this theme, of course, if you prefer to offload the long-running process via JMS or something similar.
Anyway, since you are very experienced in Ajax technology, I will certainly ask for your help.
Rather than attacking the bartenders here, you may be better served by taking some of their criticism to heart. One of the main reasons they were trying to steer you away from a standby page is because of the extraordinary amount of time the user would be at this page. I think you would find that this is considered bad UI industry wide.
I am also familiar with the standby pages of travel sites, real estate sites, etc., and Tim does an excellent job of explaining a simple process for doing this. But the longest I have ever waited at Orbitz or Travelocity was less than a minute, even on dial up. Your requirements seem to indicate a much longer time:
I would say that 1-2 minutes is much more manageable. Good luck with your solution.
This example shows one way to handle long running processes by kicking off the process in another thread and returning the user to a status screen that refreshes itself every n seconds - letting the user know that the process is still running and giving them an estimate for completion time.
The user can leave the page and come back without interrupting the process and can't kick off another process within their current session until the running one is complete.
This technique has been described several times in this and in the JSP forum in the last few months. Hopefully an example app will help.
Look for LongRunningProcess.war