decal
decal

Reputation: 1017

Setting a Timeout for a download link in Wicket?

I just started using Wicket (and really am not too familiar with a lot of web development) and have a question with regards to a download link. I have a web app that simply allows users to upload particular files, processes some of the information in the files, and offers downloads of different formats of the processed information. However this is really supposed to be a lite version of some software I am working on, so I really don't want to do much processing. I am wondering if there is a way to set something like a timeout for the download link, so that if the user clicks on the link and the processing takes longer than 20 seconds or so, it will simply quit the processing and send them an error instead. Thanks!

Upvotes: 2

Views: 1006

Answers (2)

Carl-Eric Menzel
Carl-Eric Menzel

Reputation: 1266

I agree with Xavi that the processing (and possible termination of the processing) should be done with a thread.

However, especially if it takes more than just a few seconds, it is much better to not just wait with the open connection, but rather to check at regular intervals to see whether the thread is done.

I'd do something like this:

  1. Start the thread doing the actual work
  2. Show a Panel that says "Processing your download" or something like that.
  3. Attach an AbstractAjaxTimerBehavior to the panel with a timer duration of, say, 10 seconds or so.
  4. In the timer behavior's onTimer method, check the state of the processing:
    • If it's still working, do nothing.
    • If it's canceled because it took too long, show a message like "Canceled" to the user, e.g. by replacing the panel or setting a warning label to visible.
    • If it's done, show a message like "Your download is starting" and start the download. See this document for how to do an AJAX response and at the same time initiate a download

Upvotes: 4

Xavi López
Xavi López

Reputation: 27880

To be able to cancel processing if it takes more than a given amount of time, it would be appropriate to perform it in a separate thread. This matter is addressed in the following question: How to timeout a thread.

Now for the Wicket part of it: If I understood what you're trying to achieve, you could for instance roll your own Link that would perform the processing, and respond with the results in case it doesn't timeout. In case the processing takes too much time, you can simply throw an error (remember to have a FeedbackPanel so that it can be shown).

The processing, or generation of the file to download, could be implemented in a LoadableDetachableModel for efficiency. See this question for more details: How to use Wicket's DownloadLink with a file generated on the fly?

For instance:

IModel<File> processedFileModel = new LoadableDetachableModel<File>(){
    protected File load(){
        // Implement processing in a separate thread. 
        // If it times out it could return null, for instance
    }

}

Link<File> downloadLink = new Link<File>("yourID", processedFileModel) {
        @Override
        public void onClick() {
            File processedFile = getModelObject();
            if (file != null) {
                IResourceStream rs = new FileResourceStream(file);
                getRequestCycle().setRequestTarget(new ResourceStreamRequestTarget(rs));
            } else {
                error("Processing took too long");
            }
        }
    };

Upvotes: 2

Related Questions