3

I have a JavaScript application that can allow a user to fire off multiple, overlapping read-only requests to my Tomcat server, such that later requests should cancel and override any earlier requests. I could disable all my client side controls until the request comes in, but I would rather keep them enabled and let the user click whenever they want, and cancel previous requests.

What I would like to do, is cancel all but the latest request, so that my server does not waste time completing requests that will never be seen. I want the server to abort the thread it is running for that request in order to reduce server resources.

What's the best way do this?

Danger
  • 2,043
  • 2
  • 21
  • 24
  • 1
    You can't do this on the server - instead you should do it on the client. Use AJAX and cancel previous call when initiating a new one if the previous one hasn't completed. See [this question](http://stackoverflow.com/questions/446594/abort-ajax-requests-using-jquery) – Aleks G Jul 05 '13 at 15:09
  • @AleksG Thank you for that fast repy! Excellent link there. As you say, you can't do this on the server. But I don't accept "can't" very easily. – Danger Jul 05 '13 at 15:24

2 Answers2

2

If it's all about saving server CPU time, client side cancelling of the request will not help you. The easy way is: Ignore it, accept that the request will still compute until the server side request processor realizes that its output stream is closed and will fail.

If you have some heavy duty operation that indeed takes quite a while to complete, I'd opt for doing the server side work in chunks and - intermediary - check if the request is still required to continue. Any new request could set the flag that other threads for the same user are checking for.

Interacting on a java thread level (e.g. Thread.stop etc) is not a nice way to interact in application logic. However, if you have some application logic that determines which user needs which operation done, and each operation can check if it's still required, that might help you. You'll still waste a few cycles, but not necessarily the full amount.

Also, if you interact on a java thread level, keep in mind that the threads are most likely owned by the application server and are used in a thread pool for request handling - thus you shouldn't mess with them (from the outside).

Olaf Kock
  • 46,930
  • 8
  • 59
  • 90
0

I think you could do this on the server, but it's going to be a little impractical, as implied in the comments.

You'll need a data structure (maybe a HashMap) that keeps track of

  • The user making the request
  • The current Thread object servicing the request
  • Any other contextual things that would help identify the request

On an incoming HTTP request to the servlet, consult the lookup table and find out if there's already a Thread object stored. If so, then stop the thread, and continue the execution in the current thread. Before the thread returns the content back to the client, be sure to remove the Thread's entry from the HashMap.

This is a fairly complicated situation. Any time you deal with concurrency, you run the risk of really messing things up. I would only follow this route if you really, really want to conserve server side resources. Otherwise, just using AJAX to cancel the previous call on the client side would be probably be much easier, as Aleks G suggested.

Community
  • 1
  • 1
austin
  • 5,816
  • 2
  • 32
  • 40