/** * Copyright 2011-2017 Asakusa Framework Team. * * 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.asakusafw.runtime.util.lock; import java.text.MessageFormat; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * An implementation of {@link RetryStrategy} with constant time. * @since 0.7.0 */ public class ConstantRetryStrategy implements RetryStrategy { static final Log LOG = LogFactory.getLog(ConstantRetryStrategy.class); private final int maxAttemptNumber; private final long minInterval; private final long maxInterval; /** * Creates a new instance for do not retry tasks. */ public ConstantRetryStrategy() { this(0, 0, 0); } /** * Creates a new instance for do not retry tasks. * @param maxRetryCount maximum retry count ({@code >= 0}) */ public ConstantRetryStrategy(int maxRetryCount) { this(maxRetryCount, 0, 0); } /** * Creates a new instance. * @param maxRetryCount maximum retry count ({@code >= 0}) * @param interval retry interval (ms) */ public ConstantRetryStrategy(int maxRetryCount, long interval) { this(maxRetryCount, interval, interval); } /** * Creates a new instance. * @param maxRetryCount maximum retry count ({@code >= 0}) * @param minInterval minimum retry interval (ms) * @param maxInterval maximum retry interval (ms) */ public ConstantRetryStrategy(int maxRetryCount, long minInterval, long maxInterval) { this.maxAttemptNumber = Math.max(0, maxRetryCount) + 1; this.minInterval = Math.max(0, minInterval); this.maxInterval = Math.max(this.minInterval, maxInterval); } @Override public RetryObject newInstance(String taskName) { return new Retry(taskName, maxAttemptNumber, minInterval, maxInterval); } private static final class Retry implements RetryObject { private final String taskName; private final int maxAttemptNumber; private final long minInterval; private final long maxInterval; private int attemptNumber = 1; Retry(String taskName, int maxAttemptNumber, long minInterval, long maxInterval) { this.taskName = taskName; this.maxAttemptNumber = maxAttemptNumber; this.minInterval = minInterval; this.maxInterval = maxInterval; } @Override public boolean waitForNextAttempt() throws InterruptedException { if (attemptNumber >= maxAttemptNumber) { if (LOG.isDebugEnabled()) { LOG.debug(MessageFormat.format( "exceeded max attempt number ({2}): {0}", //$NON-NLS-1$ taskName, maxAttemptNumber)); } return false; } if (LOG.isDebugEnabled()) { LOG.debug(MessageFormat.format( "waiting for next attempt ({1}/{2}): {0}", //$NON-NLS-1$ taskName, attemptNumber, maxAttemptNumber)); } long interval; if (minInterval == maxInterval) { interval = minInterval; } else { interval = minInterval + (long) ((maxInterval - minInterval) * Math.random()); } if (interval > 0) { Thread.sleep(interval); } attemptNumber++; return true; } } }