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; 021import java.io.InterruptedIOException; 022import org.apache.hadoop.hbase.DoNotRetryIOException; 023import org.apache.hadoop.hbase.ServerName; 024import org.apache.hadoop.hbase.TableName; 025import org.apache.yetus.audience.InterfaceAudience; 026 027import org.apache.hbase.thirdparty.com.google.protobuf.RpcController; 028 029import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos; 030 031/** 032 * This class is used to unify HTable calls with AsyncProcess Framework. HTable can use AsyncProcess 033 * directly though this class. Also adds global timeout tracking on top of RegionServerCallable and 034 * implements Cancellable. Global timeout tracking conflicts with logic in RpcRetryingCallerImpl's 035 * callWithRetries. So you can only use this callable in AsyncProcess which only uses 036 * callWithoutRetries and retries in its own implementation. 037 */ 038@InterfaceAudience.Private 039abstract class CancellableRegionServerCallable<T> extends ClientServiceCallable<T> 040 implements Cancellable { 041 private final RetryingTimeTracker tracker; 042 private final int rpcTimeout; 043 044 CancellableRegionServerCallable(Connection connection, TableName tableName, byte[] row, 045 RpcController rpcController, int rpcTimeout, RetryingTimeTracker tracker, int priority) { 046 super(connection, tableName, row, rpcController, priority); 047 this.rpcTimeout = rpcTimeout; 048 this.tracker = tracker; 049 } 050 051 /* 052 * Override so can mess with the callTimeout. (non-Javadoc) 053 * @see org.apache.hadoop.hbase.client.RegionServerCallable#rpcCall(int) 054 */ 055 @Override 056 public T call(int operationTimeout) throws IOException { 057 if (isCancelled()) return null; 058 if (Thread.interrupted()) { 059 throw new InterruptedIOException(); 060 } 061 // It is expected (it seems) that tracker.start can be called multiple times (on each trip 062 // through the call when retrying). Also, we can call start and no need of a stop. 063 this.tracker.start(); 064 int remainingTime = tracker.getRemainingTime(operationTimeout); 065 if (remainingTime <= 1) { 066 // "1" is a special return value in RetryingTimeTracker, see its implementation. 067 throw new DoNotRetryIOException("Operation rpcTimeout"); 068 } 069 return super.call(Math.min(rpcTimeout, remainingTime)); 070 } 071 072 @Override 073 public void prepare(boolean reload) throws IOException { 074 if (isCancelled()) return; 075 if (Thread.interrupted()) { 076 throw new InterruptedIOException(); 077 } 078 super.prepare(reload); 079 } 080 081 @Override 082 protected void setStubByServiceName(ServerName serviceName) throws IOException { 083 setStub(getConnection().getClient(serviceName)); 084 } 085 086 @Override 087 public void cancel() { 088 getRpcController().startCancel(); 089 } 090 091 @Override 092 public boolean isCancelled() { 093 return getRpcController().isCanceled(); 094 } 095 096 protected ClientProtos.MultiResponse doMulti(ClientProtos.MultiRequest request) 097 throws org.apache.hbase.thirdparty.com.google.protobuf.ServiceException { 098 return getStub().multi(getRpcController(), request); 099 } 100 101 protected ClientProtos.ScanResponse doScan(ClientProtos.ScanRequest request) 102 throws org.apache.hbase.thirdparty.com.google.protobuf.ServiceException { 103 return getStub().scan(getRpcController(), request); 104 } 105 106 protected ClientProtos.PrepareBulkLoadResponse 107 doPrepareBulkLoad(ClientProtos.PrepareBulkLoadRequest request) 108 throws org.apache.hbase.thirdparty.com.google.protobuf.ServiceException { 109 return getStub().prepareBulkLoad(getRpcController(), request); 110 } 111 112 protected ClientProtos.BulkLoadHFileResponse 113 doBulkLoadHFile(ClientProtos.BulkLoadHFileRequest request) 114 throws org.apache.hbase.thirdparty.com.google.protobuf.ServiceException { 115 return getStub().bulkLoadHFile(getRpcController(), request); 116 } 117 118 protected ClientProtos.CleanupBulkLoadResponse 119 doCleanupBulkLoad(ClientProtos.CleanupBulkLoadRequest request) 120 throws org.apache.hbase.thirdparty.com.google.protobuf.ServiceException { 121 return getStub().cleanupBulkLoad(getRpcController(), request); 122 } 123}