1

In the gwt client I can cancel a request by letting the method in the Async interface return a Request object which contains a cancel() method I can call.

So far so good, but is there a way to detect this in the java code running on the server?

My use-case is that I have a rpc call which take a long time to complete on the server, and where the user has a "cancel" button to stop the request.

And If the user cancel the request, the server should stop processing, but there seems to be no way to detect that the client have closed the connection.

MTilsted
  • 5,425
  • 9
  • 44
  • 76

1 Answers1

1

It is usually not a good idea to use server's request threads for long running tasks. You need to redesign them to be executed asynchronously (if you still have not done it). You can utilize java.util.concurent tools like FutureTask and Executors to achieve this. You will also need to use thread pools to make sure to control a max number of concurrent tasks.

When you submit a request for a long task from the client, you need to return a reference key (e.g. UUID or some unique string) to your FutureTask as soon as you schedule it for execution. Then to cancel the task, you need pass the key from the client and look up you task and cancel it:

See javadoc for more details:

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/FutureTask.html

yurgis
  • 4,017
  • 1
  • 13
  • 22
  • Each servlet request is running in its own thread. And I can't see how I can use futures with gwt-rpc. The problem is not stopping the thread. The problem is in detecting that the client have canceled the request. – MTilsted Jan 14 '15 at 08:54
  • Futures are for server side only. As I mentioned, you only need pass a reference key via rpc. A key could be a string, int, or anything you want to store or access your FutureTask with on the server side. For example, ConcurrentMap – yurgis Jan 14 '15 at 16:07
  • So the flow: 1. Client submits long request (via rpc). 2. Server schedules future task, stores it in a map or session, and returns reference key to the client immediately without waiting for task to complete. 3. Client shows cancel button and associate it with reference key. 4 user clicks cancel and client calls server via rpc cancel(reference). 5. Server looks up the task by the key and cancels the task. – yurgis Jan 14 '15 at 16:19
  • Wow: Is that really the only solution? Did Oracle really forget to add a "isSocket/Stream closed by client" call. – MTilsted Jan 14 '15 at 17:06
  • To my knowledge there is no reliable way to abort ajax calls and detect a "client disconnect" on the server side. Please read this topic from top to bottom for the great discussion: http://stackoverflow.com/questions/446594/abort-ajax-requests-using-jquery. The only reliable method is to issue a second call - and one of the possible, reliable, and safe designs is given above. – yurgis Jan 14 '15 at 17:55