/** * Copyright (C) 2009-2012 the original author or authors. * See the notice.md file distributed with this work for additional * information regarding copyright ownership. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.restygwt.client.callback; import java.util.logging.Logger; import org.fusesource.restygwt.client.FailedStatusCodeException; import org.fusesource.restygwt.client.Method; import com.google.gwt.core.client.GWT; import com.google.gwt.http.client.Request; import com.google.gwt.http.client.RequestCallback; import com.google.gwt.http.client.RequestException; import com.google.gwt.http.client.Response; import com.google.gwt.logging.client.LogConfiguration; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.Window; public class RetryingFilterawareRequestCallback extends DefaultFilterawareRequestCallback { /** * Used by RetryingCallback * default value is 5 */ protected int numberOfRetries = 5; /** * time to wait for reconnect upon failure */ protected int gracePeriod = 1000; protected int currentRetryCounter = 0; public RetryingFilterawareRequestCallback(Method method) { super(method); } public RetryingFilterawareRequestCallback(Method method, int gracePeriodMillis, int numberOfRetries) { super(method); this.gracePeriod = gracePeriodMillis; this.numberOfRetries = numberOfRetries; } @Override public final void doError(Request request, Response response) { int code = response.getStatusCode(); /* * retry only on GET requests that are no redirects (301, 302, 303) */ if (code != 301 && code != 302 && code != 303 && code != 404 && (method.builder == null // jsonp method do not have a builder !! || method.builder.getHTTPMethod().equalsIgnoreCase("get"))) { handleErrorGracefully(request, response, requestCallback); } else { if (LogConfiguration.loggingIsEnabled()) { Logger.getLogger(RetryingFilterawareRequestCallback.class.getName()).severe( "ERROR with non-GET method: " + method.builder.getHTTPMethod() + " " + method.builder.getUrl() + ", " + response.getStatusText()); } /* * RuntimeException token from * com.google.gwt.http.client.Request#fireOnResponseReceived() */ requestCallback.onError(request, new FailedStatusCodeException(response.getStatusText(), response.getStatusCode())); } } private void handleErrorGracefully(Request request, Response response, RequestCallback requestCallback) { // error handling...: if (currentRetryCounter < numberOfRetries) { if (GWT.isClient() && LogConfiguration.loggingIsEnabled()) { Logger.getLogger(RetryingFilterawareRequestCallback.class.getName()).severe( "error handling in progress for: " + method.builder.getHTTPMethod() + " " + method.builder.getUrl()); } currentRetryCounter++; Timer t = new Timer() { @Override public void run() { try { method.builder.send(); } catch (RequestException ex) { if (GWT.isClient() && LogConfiguration.loggingIsEnabled()) { Logger.getLogger(RetryingFilterawareRequestCallback.class.getName()) .severe(ex.getMessage()); } } } }; t.schedule(gracePeriod); gracePeriod = gracePeriod * 2; } else { if (GWT.isClient() && LogConfiguration.loggingIsEnabled()) { Logger.getLogger(RetryingFilterawareRequestCallback.class.getName()).severe("Request failed: " + method.builder.getHTTPMethod() + " " + method.builder.getUrl() + " after " + currentRetryCounter + " tries."); } if (null != request && null != response && null != requestCallback) { // got the original callback, call error here requestCallback.onError(request, new RuntimeException("Response " + response.getStatusCode() + " for " + method.builder.getHTTPMethod() + " " + method.builder.getUrl() + " after " + numberOfRetries + " retries.")); } else { // got no callback - well, goodbye if (Window.confirm("something severly went wrong - error - reload page ?")) { // Super severe error. // reload app or redirect. // ===> this breaks the app but that's by intention. Window.Location.reload(); } } } } }