service.getUpdate(AsyncCallBack callback), which takes a long time to
return
On the client side, there are cases when I would like to cancel this
service call before it actually returns. Something like:
service.cancelCall(callId)
or maybe even:
GWT.cancelAllServiceCalls()
Is there any way to accomplish this?
Currently, we're sending in a call reference ID from the client to the
server during the service call:
service.getUpdate(int callId, AsyncCallBack callback)
Then, we're cancelling the call from the server-side via a call from
the client-side:
service.cancelCall(callId)
However, this becomes complicated when multiple back-end servers are
involved, since they all have to know about the unique callIds and
react when one of the back-ends gets a cancel message. It seems more
efficient if we can cancel the call from the client-side and cut off
the connection in GWT. (Sort of like hitting the STOP button on the
browser during a long page-load.)
Any ideas?
Erez
With the amount of information that you have provided, I could not
understand what your application is actually trying to do. But yeah
getting control over fate of "Dispatched Request" is an accepted issue
with GWT. For more details you can refer to following thread:
and it has already been filed as a bug at:
http://code.google.com/p/google-web-toolkit/issues/detail?id=535&can=2&q=
Also, Scot Blum from Google has given a sample code which could be
helpful in your case. I have not actually gone through it.
I hope this might be helpful.
-Rahul
RPCCall call = service.getUpdate(AsyncCallBack callback);
...
later on... if we don't need the result anymore:
call.cancel();
This way, the call immediately dies and stops using up a connection.
Erez
Thanks,
Rahul
I added my 2cents to the ticket. I hope they raise the priority on
this and release this with the next version. Maybe they can find a way
to add this in without breaking existing clients.
Erez
is there some standard way to preempt server-side requests?
is just marking your AsyncCallback instance to ignore the onSuccess()
call enough? I'm assuming the answer is "no"
We can send a "cancel" message from client to server, asking the server
to stop waiting for a change. This prevents the server-side resource
use and eventually will kill the client connection. I guess it's
preferable to actually killing off the connection from the client side.
However, if too many such calls happen at once, then the client may
hang waiting for the "cancel" messages to take effect and kill off the
long-running calls. It would be nice to be able to simply kill the
long-running calls from the client side so we're not waiting for the
server to cancel and clean up.
Maybe there's a better way to achieve what we're trying to do.
We're basically calling the request and letting the server-side thread
wait until there's a change. Then, returning the value and handling on
the client side. Then, we run the request again. Requests wait up to
a minute on the server-side before returning "no change" and starting
again.
The alternative (what we were doing before) is brute-force calling the
server-side every second to check for changes. We assumed the
long-running request method is better since it causes fewer
connections/sec on our web server and app server.
I'm curious how Google applications (like Gmail chat) refresh in near
real-time.
Erez
2. We're currently running about 200 concurrent users and will probably
reach 10,000 in a few years, so I guess we're pretty tiny. We could
spread the load onto multiple servers, but I would think 10,000
concurrent threads shouldn't be too much of an issue for a single JVM
with 4GB RAM. (I wonder if epoll-enabled JVMs be better able to handle
this level of dormant concurrency?)
3. That's sounds like a nice client-side management framework. I would
think part of it could be implemented in the return object from the RPC
call. What would be really neat would be for the CallBack object to be
able to receive multiple onSuccess() calls from the server as long as
the connection was active (like COMET?)
Possibly a more scalable solution would be able to pass off dormant
long-lived requests to a single (or pooled) thread that would handle
all of the sleepers. That thread(s) would then be responsible for
responding to the long-running requests instead of letting the
connection-handling threads deal with everything. I would think this
would have to be more tightly integrated into the servlet framework,
though.
On Dec 27, 4:46 am, "Jon" <jon.we...@gmail.com> wrote:
> What does it mean to cancel the call on the server side?
Pretty simple... When you close the connection on the client side, the
server side code will receive a SocketException (Broken pipe) and can
handle that, for instance rolling back a pending transaction.
Sascha
1. like you said that the client can close the connection and the
server will fail when it tries to write back the method return value
(after 20 mins of sucking up server-side resources)
2. the server should rollback anything its done (not currently possible
to catch those SocketExceptions on the server since they're thrown in
the GWT base servlet),
3. the service method should abort its processing ASAP sparing you the
wasted server resources.
4. You could also mean that the client will simply ignore the onSuccess
callback
Even I am facing the same problem as you have mentioned in step 2.
>2. the server should rollback anything its done (not currently possible
>to catch those SocketExceptions on the server since they're thrown in
>the GWT base servlet),
There should be a cleaner way to handle such situation. Even my
application is refreshing the content of page in every 5 seconds. But
then few calls to server are running afoul and throwing
SocketTimeoutException on serverside.Whenever there is a
SocketTimeoutException on server side you can register it on client
side inside onFailure() method as,
public void onFailure(Throwable caught)
{
try {
throw caught;
}
catch (InvocationException ie) {
// Invocation failed on server side.
}
catch (Throwable th) {
// Exception for some other reason.
}
}
But then there is no way we can make sure that this InvocationException
has come because of a SocketTimeoutException on serverside and deal it
as a special case. InvocationException can come because of many
reasons.
Rahul
I recommend that anyone doing client-server programming read the
excellent book "Java Concurrency in Practice." Among its topics is
extensive treatment of how to handle the cancellation of long-running
tasks.
> ...
Randall Schulz