/** * Licensed to Cloudera, Inc. under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. Cloudera, Inc. licenses this file * to you 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.cloudera.util; /** * Wraps the retry logic associated with a BackoffPolicy to * save having to write driver code. */ public class RetryHarness { Retryable retry; BackoffPolicy policy; Exception lastException = null; boolean throwOnFailure = false; volatile boolean abort = false; public RetryHarness(Retryable retry, BackoffPolicy policy) { this.retry = retry; this.policy = policy; retry.setHarness(this); } public RetryHarness(Retryable retry, BackoffPolicy policy, boolean throwOnFailure) { this.retry = retry; this.policy = policy; this.throwOnFailure = throwOnFailure; retry.setHarness(this); } /** * Returns the last exception thrown by the Retryable (or null if there was * none) */ public Exception getLastException() { return lastException; } /** * Calls doTry on a Retryable until either it succeeds or the backoff policy * fails. */ public boolean attempt() throws Exception { boolean success = false; abort = false; policy.reset(); while (!abort && !policy.isFailed()) { policy.waitUntilRetryOk(); try { if (policy.isRetryOk()) { success = retry.doTry(); if (success) { return true; } } } catch (Exception e) { lastException = e; } policy.backoff(); } if (throwOnFailure && lastException != null) { throw lastException; } return false; } public void doAbort() { abort = true; } }