org.apache.hadoop.hbase.client.MasterCallable Maven / Gradle / Ivy
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF 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 org.apache.hadoop.hbase.client;
import java.io.Closeable;
import java.io.IOException;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.ipc.HBaseRpcController;
import org.apache.hadoop.hbase.ipc.RpcControllerFactory;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.yetus.audience.InterfaceAudience;
import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
/**
* A RetryingCallable for Master RPC operations.
* Implement the #rpcCall method. It will be retried on error. See its javadoc and the javadoc of
* #call(int). See {@link HBaseAdmin} for examples of how this is used. To get at the
* rpcController that has been created and configured to make this rpc call, use getRpcController().
* We are trying to contain all protobuf references including references to rpcController so we
* don't pollute codebase with protobuf references; keep the protobuf references contained and only
* present in a few classes rather than all about the code base.
* Like {@link RegionServerCallable} only in here, we can safely be PayloadCarryingRpcController
* all the time. This is not possible in the similar {@link RegionServerCallable} Callable because
* it has to deal with Coprocessor Endpoints.
* @param return type
*/
@InterfaceAudience.Private
abstract class MasterCallable implements RetryingCallable, Closeable {
protected final ClusterConnection connection;
protected MasterKeepAliveConnection master;
private final HBaseRpcController rpcController;
MasterCallable(final Connection connection, final RpcControllerFactory rpcConnectionFactory) {
this.connection = (ClusterConnection) connection;
this.rpcController = rpcConnectionFactory.newController();
}
@Override
public void prepare(boolean reload) throws IOException {
this.master = this.connection.getMaster();
}
@Override
public void close() throws IOException {
// The above prepare could fail but this would still be called though masterAdmin is null
if (this.master != null) {
this.master.close();
this.master = null;
}
}
@Override
public void throwable(Throwable t, boolean retrying) {
}
@Override
public String getExceptionMessageAdditionalDetail() {
return "";
}
@Override
public long sleep(long pause, int tries) {
return ConnectionUtils.getPauseTime(pause, tries);
}
/**
* Override that changes the {@link java.util.concurrent.Callable#call()} Exception from {@link Exception} to
* {@link IOException}. It also does setup of an rpcController and calls through to the rpcCall()
* method which callers are expected to implement. If rpcController is an instance of
* PayloadCarryingRpcController, we will set a timeout on it.
*/
@Override
// Same trick as in RegionServerCallable so users don't have to copy/paste so much boilerplate
// and so we contain references to protobuf. We can't set priority on the rpcController as
// we do in RegionServerCallable because we don't always have a Table when we call.
public V call(int callTimeout) throws IOException {
try {
if (this.rpcController != null) {
this.rpcController.reset();
this.rpcController.setCallTimeout(callTimeout);
}
return rpcCall();
} catch (Exception e) {
throw ProtobufUtil.handleRemoteException(e);
}
}
/**
* Run the RPC call. Implement this method. To get at the rpcController that has been created
* and configured to make this rpc call, use getRpcController(). We are trying to contain
* rpcController references so we don't pollute codebase with protobuf references; keep the
* protobuf references contained and only present in a few classes rather than all about the
* code base.
* @throws Exception
*/
protected abstract V rpcCall() throws Exception;
HBaseRpcController getRpcController() {
return this.rpcController;
}
void setPriority(final int priority) {
if (this.rpcController != null) {
this.rpcController.setPriority(priority);
}
}
void setPriority(final TableName tableName) {
if (this.rpcController != null) {
this.rpcController.setPriority(tableName);
}
}
/**
* @param regionName RegionName. If hbase:meta, we'll set high priority.
*/
void setPriority(final byte[] regionName) {
if (isMetaRegion(regionName)) {
setPriority(TableName.META_TABLE_NAME);
}
}
private static boolean isMetaRegion(final byte[] regionName) {
return Bytes.equals(regionName, RegionInfoBuilder.FIRST_META_REGIONINFO.getRegionName()) ||
Bytes.equals(regionName, RegionInfoBuilder.FIRST_META_REGIONINFO.getEncodedNameAsBytes());
}
}