001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.client; 019 020import java.io.IOException; 021 022import org.apache.yetus.audience.InterfaceAudience; 023 024/** 025 * This class is designed to fit into the RetryingCaller class which forms the 026 * central piece of intelligence for the client side retries for most calls. 027 * 028 * One can extend this class and intercept the RetryingCaller and add additional 029 * logic into the execution of a simple HTable operations like get, delete etc. 030 * 031 * Concrete implementations of this calls are supposed to the thread safe. The 032 * object is used across threads to identify the fast failing threads. 033 * 034 * For a concrete use case see {@link PreemptiveFastFailInterceptor} 035 * 036 * Example use case : 037 * try { 038 * interceptor.intercept 039 * doAction() 040 * } catch (Exception e) { 041 * interceptor.handleFailure 042 * } finally { 043 * interceptor.updateFaulireInfo 044 * } 045 * 046 * The {@link RetryingCallerInterceptor} also acts as a factory 047 * for getting a new {@link RetryingCallerInterceptorContext}. 048 * 049 */ 050 051@InterfaceAudience.Private 052abstract class RetryingCallerInterceptor { 053 054 protected RetryingCallerInterceptor() { 055 // Empty constructor protected for NoOpRetryableCallerInterceptor 056 } 057 058 /** 059 * This returns the context object for the current call. 060 * 061 * @return context : the context that needs to be used during this call. 062 */ 063 public abstract RetryingCallerInterceptorContext createEmptyContext(); 064 065 /** 066 * Call this function in case we caught a failure during retries. 067 * 068 * @param context 069 * : The context object that we obtained previously. 070 * @param t 071 * : The exception that we caught in this particular try 072 * @throws IOException 073 */ 074 public abstract void handleFailure(RetryingCallerInterceptorContext context, 075 Throwable t) throws IOException; 076 077 /** 078 * Call this function alongside the actual call done on the callable. 079 * 080 * @param abstractRetryingCallerInterceptorContext 081 * @throws IOException 082 */ 083 public abstract void intercept( 084 RetryingCallerInterceptorContext abstractRetryingCallerInterceptorContext) 085 throws IOException; 086 087 /** 088 * Call this function to update at the end of the retry. This is not necessary 089 * to happen. 090 * 091 * @param context 092 */ 093 public abstract void updateFailureInfo( 094 RetryingCallerInterceptorContext context); 095 096 @Override 097 public abstract String toString(); 098}