I require retrying to send a GWT RPC request if it fails (any response code other then HTTP 200). Reasons are complex so I won't elaborate on that. What I have so far is I treat all request responses in the same place like this:
// We override the RpcRequestBuilder.doSetCallback method and force your service to use it
// With this we can read the response headers if we need to.
((ServiceDefTarget)serviceRPC).setRpcRequestBuilder(new RpcRequestBuilder() {
@Override
protected void doSetCallback(RequestBuilder rb, final RequestCallback callback) {
super.doSetCallback(rb, new RequestCallback() {
@Override
public void onResponseReceived(Request request,
Response response) {
httpResponseOkHandler(callback, request, response);
}
@Override
public void onError(Request request, Throwable exception) {
httpResponseErrorHandler(callback, request, exception);
}
});
}
});
So, using httpResponseOkHandler method, I can catch HTTP failures. But, is there a way to "rethrow" the Request, i.e. try again? I don't want to store the high level parameters of the RPC request, I would prefer to use the request content that was already streamed and ready to resend.
Any ideas?
Well, found the answer myself. So it's pretty neat after all. Working in heavily loaded hospital environments, network tend to be unreliable. So that is why I needed to resend rpc requests a few times before giving up. Here is the solution :
1- Set you special request builder to catch all requests responses but keep the request builder.
((ServiceDefTarget)serviceRPC).setRpcRequestBuilder(new RpcRequestBuilder() {
@Override
protected void doSetCallback(RequestBuilder rb, final RequestCallback callback) {
final RequestBuilder requestBuilder = rb;
super.doSetCallback(rb, new RequestCallback() {
@Override
public void onResponseReceived(Request request,
Response response) {
httpResponseOkHandler(requestBuilder, callback, request, response);
}
@Override
public void onError(Request request, Throwable exception) {
httpResponseErrorHandler(requestBuilder, callback, request, exception);
}
});
}
});
2- Now use the request builder to send the request as many times as you want. One great thing is the request builder was already set and data was serialized which avoids having to store POJO unserialized data.
// We had some server HTTP error response (we only expect code 200 from server when using RPC)
if (response.getStatusCode() != Response.SC_OK) {
Integer requestTry = requestValidation.get(requestBuilder.getRequestData());
if (requestTry == null) {
requestValidation.put(requestBuilder.getRequestData(), 1);
sendRequest(requestBuilder, callback, request);
}
else if (requestTry < MAX_RESEND_RETRY) {
requestTry += 1;
requestValidation.put(requestBuilder.getRequestData(), requestTry);
sendRequest(requestBuilder, callback, request);
} else {
InvocationException iex = new InvocationException("Unable to initiate the asynchronous service invocation -- check the network connection", null);
callback.onError(request, iex);
}
} else {
callback.onResponseReceived(request, response);
}
This is working fine for me, use it at your own risK!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With