/* Copyright (c) 2009 Google Inc.
*
* 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 com.google.appengine.demos.sticky.client.model;
import com.google.gwt.user.client.Timer;
/**
* Provides a way to control retry-on-failure schemes. Clients override
* {@link RetryTimer#retry()} to provide the task that needs to be performed on
* a retry, then invocations of {@link RetryTimer#retryLater()} will schedule
* retries on a progressively longer schedule.
*
* @author knorton@google.com (Kelly Norton)
*/
public abstract class RetryTimer {
private static final int MAX_RETRY_DELAY = 60000 /* ms. */;
private static final int MIN_RETRY_DELAY = 10000 /* ms. */;
private static final int RETRY_DELAY_GROWTH_RATE = 20000 /* ms. */;
private int retryCount;
private Timer timer = new Timer() {
@Override
public void run() {
retry();
}
};
/**
* Resets the internal counter (and the progressively lengthening retry
* timer).
*/
public void resetRetryCount() {
retryCount = 0;
}
/**
* Determine the amount of delay before another retry should be issued. The
* delay after the first failure is {@link RetryTimer#MIN_RETRY_DELAY}
* milliseconds. The delay is then increased by
* {@link RetryTimer#RETRY_DELAY_GROWTH_RATE} milliseconds on each failure
* until it reaches {@link RetryTimer#MAX_RETRY_DELAY} where it will remain
* constant for any subsequent failures.
*
* @param count
* the number of failures that have occurred
* @return the delay to use, in milliseconds
*/
private int getRetryDelay(int count) {
return Math.min(MAX_RETRY_DELAY, MIN_RETRY_DELAY + RETRY_DELAY_GROWTH_RATE
* count);
}
/**
* Clients override {@link RetryTimer#retry()} to provide the task that will
* be retried.
*/
protected abstract void retry();
/**
* Clients should call {@link RetryTimer#retryLater()} when they encounter
* failure to schedule a retry.
*/
protected void retryLater() {
timer.schedule(getRetryDelay(retryCount++));
}
}