HBASE-15143 Procedure v2 - Web UI displaying queues Signed-off-by: Michael Stack <st...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/25575064 Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/25575064 Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/25575064 Branch: refs/heads/master Commit: 25575064154fe1cc7ff8970e8f15a3cff648f37a Parents: 1367519 Author: Balazs Meszaros <balazs.mesza...@cloudera.com> Authored: Mon Feb 13 13:50:56 2017 -0800 Committer: Michael Stack <st...@apache.org> Committed: Tue Apr 25 09:39:28 2017 -0700 ---------------------------------------------------------------------- .../org/apache/hadoop/hbase/client/Admin.java | 9 + .../hbase/client/ConnectionImplementation.java | 11 +- .../apache/hadoop/hbase/client/HBaseAdmin.java | 42 +- .../client/ShortCircuitMasterConnection.java | 6 + .../hbase/shaded/protobuf/ProtobufUtil.java | 183 +- .../hadoop/hbase/procedure2/LockInfo.java | 128 + .../hadoop/hbase/procedure2/LockAndQueue.java | 21 +- .../hadoop/hbase/procedure2/LockStatus.java | 1 + .../hbase/procedure2/ProcedureScheduler.java | 7 + .../hadoop/hbase/procedure2/ProcedureUtil.java | 4 +- .../procedure2/SimpleProcedureScheduler.java | 10 +- .../protobuf/generated/LockServiceProtos.java | 2423 +++++++++++++++++- .../shaded/protobuf/generated/MasterProtos.java | 2152 ++++++++++++---- .../src/main/protobuf/LockService.proto | 22 + .../src/main/protobuf/Master.proto | 11 + .../hbase/tmpl/master/MasterStatusTmpl.jamon | 2 +- .../hbase/coprocessor/MasterObserver.java | 19 + .../org/apache/hadoop/hbase/master/HMaster.java | 37 +- .../hbase/master/MasterCoprocessorHost.java | 21 + .../hadoop/hbase/master/MasterRpcServices.java | 147 +- .../hadoop/hbase/master/MasterServices.java | 9 +- .../hbase/master/locking/LockProcedure.java | 8 +- .../procedure/MasterProcedureScheduler.java | 119 +- .../hbase-webapps/master/procedures.jsp | 127 +- .../resources/hbase-webapps/master/snapshot.jsp | 2 +- .../hbase-webapps/master/snapshotsStats.jsp | 2 +- .../resources/hbase-webapps/master/table.jsp | 2 +- .../hbase-webapps/master/tablesDetailed.jsp | 2 +- .../main/resources/hbase-webapps/master/zk.jsp | 2 +- .../hbase/coprocessor/TestMasterObserver.java | 38 + .../hbase/master/MockNoopMasterServices.java | 9 +- .../procedure/TestMasterProcedureScheduler.java | 169 +- .../hadoop/hbase/protobuf/TestProtobufUtil.java | 41 +- .../hbase/shaded/protobuf/TestProtobufUtil.java | 151 ++ hbase-shell/src/main/ruby/hbase/admin.rb | 5 + hbase-shell/src/main/ruby/shell.rb | 3 +- hbase-shell/src/main/ruby/shell/commands.rb | 5 + .../src/main/ruby/shell/commands/list_locks.rb | 60 + hbase-shell/src/main/ruby/shell/formatter.rb | 9 +- .../src/test/ruby/shell/list_locks_test.rb | 152 ++ 40 files changed, 5409 insertions(+), 762 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hbase/blob/25575064/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java ---------------------------------------------------------------------- diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java index f2fc9a5..3e767d2 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java @@ -45,6 +45,7 @@ import org.apache.hadoop.hbase.classification.InterfaceAudience; import org.apache.hadoop.hbase.client.replication.TableCFs; import org.apache.hadoop.hbase.client.security.SecurityCapability; import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel; +import org.apache.hadoop.hbase.procedure2.LockInfo; import org.apache.hadoop.hbase.quotas.QuotaFilter; import org.apache.hadoop.hbase.quotas.QuotaRetriever; import org.apache.hadoop.hbase.quotas.QuotaSettings; @@ -1250,6 +1251,14 @@ public interface Admin extends Abortable, Closeable { throws IOException; /** + * List locks. + * @return lock list + * @throws IOException if a remote or network exception occurs + */ + LockInfo[] listLocks() + throws IOException; + + /** * Roll the log writer. I.e. for filesystem based write ahead logs, start writing to a new file. * * Note that the actual rolling of the log writer is asynchronous and may not be complete when http://git-wip-us.apache.org/repos/asf/hbase/blob/25575064/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java ---------------------------------------------------------------------- diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java index 99feb14..6859cb3 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionImplementation.java @@ -25,8 +25,6 @@ import static org.apache.hadoop.hbase.client.MetricsConnection.CLIENT_SIDE_METRI import static org.apache.hadoop.hbase.util.CollectionUtils.computeIfAbsent; import static org.apache.hadoop.hbase.util.CollectionUtils.computeIfAbsentEx; -import com.google.common.annotations.VisibleForTesting; - import java.io.Closeable; import java.io.IOException; import java.io.InterruptedIOException; @@ -120,6 +118,8 @@ import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher; import org.apache.hadoop.ipc.RemoteException; import org.apache.zookeeper.KeeperException; +import com.google.common.annotations.VisibleForTesting; + import edu.umd.cs.findbugs.annotations.Nullable; /** @@ -1283,6 +1283,13 @@ class ConnectionImplementation implements ClusterConnection, Closeable { } @Override + public MasterProtos.ListLocksResponse listLocks( + RpcController controller, + MasterProtos.ListLocksRequest request) throws ServiceException { + return stub.listLocks(controller, request); + } + + @Override public MasterProtos.AddColumnResponse addColumn( RpcController controller, MasterProtos.AddColumnRequest request) throws ServiceException { http://git-wip-us.apache.org/repos/asf/hbase/blob/25575064/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java ---------------------------------------------------------------------- diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java index e55a95d..7e79c20 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java @@ -25,7 +25,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -80,6 +79,7 @@ import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel; import org.apache.hadoop.hbase.ipc.CoprocessorRpcUtils; import org.apache.hadoop.hbase.ipc.HBaseRpcController; import org.apache.hadoop.hbase.ipc.RpcControllerFactory; +import org.apache.hadoop.hbase.procedure2.LockInfo; import org.apache.hadoop.hbase.quotas.QuotaFilter; import org.apache.hadoop.hbase.quotas.QuotaRetriever; import org.apache.hadoop.hbase.quotas.QuotaSettings; @@ -110,6 +110,7 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.NameStringP import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.ProcedureDescription; import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.RegionSpecifier.RegionSpecifierType; import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.TableSchema; +import org.apache.hadoop.hbase.shaded.protobuf.generated.LockServiceProtos; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.AbortProcedureRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.AbortProcedureResponse; @@ -151,6 +152,8 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsProcedur import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsSnapshotDoneRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.IsSnapshotDoneResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListDrainingRegionServersRequest; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListLocksRequest; +import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListLocksResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListNamespaceDescriptorsRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListProceduresRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListTableDescriptorsByNamespaceRequest; @@ -191,7 +194,6 @@ import org.apache.hadoop.hbase.util.Addressing; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; import org.apache.hadoop.hbase.util.ForeignExceptionUtil; -import org.apache.hadoop.hbase.util.NonceKey; import org.apache.hadoop.hbase.util.Pair; import org.apache.hadoop.hbase.zookeeper.MasterAddressTracker; import org.apache.hadoop.hbase.zookeeper.MetaTableLocator; @@ -201,7 +203,6 @@ import org.apache.hadoop.util.StringUtils; import org.apache.zookeeper.KeeperException; import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.Lists; import com.google.protobuf.Descriptors; import com.google.protobuf.Message; import com.google.protobuf.RpcController; @@ -2096,26 +2097,33 @@ public class HBaseAdmin implements Admin { getRpcController(), ListProceduresRequest.newBuilder().build()).getProcedureList(); ProcedureInfo[] procInfoList = new ProcedureInfo[procList.size()]; for (int i = 0; i < procList.size(); i++) { - procInfoList[i] = convert(procList.get(i)); + procInfoList[i] = ProtobufUtil.toProcedureInfo(procList.get(i)); } return procInfoList; } }); } - private static ProcedureInfo convert(final ProcedureProtos.Procedure procProto) { - NonceKey nonceKey = null; - if (procProto.getNonce() != HConstants.NO_NONCE) { - nonceKey = new NonceKey(procProto.getNonceGroup(), procProto.getNonce()); - } - org.apache.hadoop.hbase.ProcedureState procedureState = - org.apache.hadoop.hbase.ProcedureState.valueOf(procProto.getState().name()); - return new ProcedureInfo(procProto.getProcId(), procProto.getClassName(), procProto.getOwner(), - procedureState, procProto.hasParentId() ? procProto.getParentId() : -1, nonceKey, - procProto.hasException()? - ForeignExceptionUtil.toIOException(procProto.getException()): null, - procProto.getLastUpdate(), procProto.getSubmittedTime(), - procProto.hasResult()? procProto.getResult().toByteArray() : null); + @Override + public LockInfo[] listLocks() throws IOException { + return executeCallable(new MasterCallable<LockInfo[]>(getConnection(), + getRpcControllerFactory()) { + @Override + protected LockInfo[] rpcCall() throws Exception { + ListLocksRequest request = ListLocksRequest.newBuilder().build(); + ListLocksResponse response = master.listLocks(getRpcController(), request); + List<LockServiceProtos.LockInfo> locksProto = response.getLockList(); + + LockInfo[] locks = new LockInfo[locksProto.size()]; + + for (int i = 0; i < locks.length; i++) { + LockServiceProtos.LockInfo lockProto = locksProto.get(i); + locks[i] = ProtobufUtil.toLockInfo(lockProto); + } + + return locks; + } + }); } @Override http://git-wip-us.apache.org/repos/asf/hbase/blob/25575064/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ShortCircuitMasterConnection.java ---------------------------------------------------------------------- diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ShortCircuitMasterConnection.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ShortCircuitMasterConnection.java index 72b2a15..e3b5b12 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ShortCircuitMasterConnection.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ShortCircuitMasterConnection.java @@ -191,6 +191,12 @@ public class ShortCircuitMasterConnection implements MasterKeepAliveConnection { } @Override + public ListLocksResponse listLocks(RpcController controller, + ListLocksRequest request) throws ServiceException { + return stub.listLocks(controller, request); + } + + @Override public ListNamespaceDescriptorsResponse listNamespaceDescriptors(RpcController controller, ListNamespaceDescriptorsRequest request) throws ServiceException { return stub.listNamespaceDescriptors(controller, request); http://git-wip-us.apache.org/repos/asf/hbase/blob/25575064/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java ---------------------------------------------------------------------- diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java index e969ded..04ce040 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java @@ -53,6 +53,8 @@ import org.apache.hadoop.hbase.HRegionInfo; import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.NamespaceDescriptor; +import org.apache.hadoop.hbase.ProcedureInfo; +import org.apache.hadoop.hbase.ProcedureState; import org.apache.hadoop.hbase.ServerLoad; import org.apache.hadoop.hbase.ServerName; import org.apache.hadoop.hbase.TableName; @@ -82,6 +84,7 @@ import org.apache.hadoop.hbase.filter.Filter; import org.apache.hadoop.hbase.io.LimitInputStream; import org.apache.hadoop.hbase.io.TimeRange; import org.apache.hadoop.hbase.master.RegionState; +import org.apache.hadoop.hbase.procedure2.LockInfo; import org.apache.hadoop.hbase.protobuf.ProtobufMagic; import org.apache.hadoop.hbase.quotas.QuotaScope; import org.apache.hadoop.hbase.quotas.QuotaType; @@ -145,11 +148,14 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.RegionInfo; import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.RegionSpecifier; import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.RegionSpecifier.RegionSpecifierType; import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.TableSchema; +import org.apache.hadoop.hbase.shaded.protobuf.generated.LockServiceProtos; import org.apache.hadoop.hbase.shaded.protobuf.generated.MapReduceProtos; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.CreateTableRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetTableDescriptorsResponse; import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ListNamespaceDescriptorsResponse; +import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos; +import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos.Procedure; import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos; import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionServerReportRequest; import org.apache.hadoop.hbase.shaded.protobuf.generated.RegionServerStatusProtos.RegionServerStartupRequest; @@ -166,7 +172,9 @@ import org.apache.hadoop.hbase.util.Addressing; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.DynamicClassLoader; import org.apache.hadoop.hbase.util.ExceptionUtil; +import org.apache.hadoop.hbase.util.ForeignExceptionUtil; import org.apache.hadoop.hbase.util.Methods; +import org.apache.hadoop.hbase.util.NonceKey; import org.apache.hadoop.hbase.util.VersionInfo; import org.apache.hadoop.ipc.RemoteException; @@ -3262,4 +3270,177 @@ public final class ProtobufUtil { int port = Addressing.parsePort(str); return ServerName.valueOf(hostname, port, -1L); } -} \ No newline at end of file + + /** + * @return Convert the current {@link ProcedureInfo} into a Protocol Buffers Procedure + * instance. + */ + public static ProcedureProtos.Procedure toProtoProcedure(ProcedureInfo procedure) { + ProcedureProtos.Procedure.Builder builder = ProcedureProtos.Procedure.newBuilder(); + + builder.setClassName(procedure.getProcName()); + builder.setProcId(procedure.getProcId()); + builder.setSubmittedTime(procedure.getSubmittedTime()); + builder.setState(ProcedureProtos.ProcedureState.valueOf(procedure.getProcState().name())); + builder.setLastUpdate(procedure.getLastUpdate()); + + if (procedure.hasParentId()) { + builder.setParentId(procedure.getParentId()); + } + + if (procedure.hasOwner()) { + builder.setOwner(procedure.getProcOwner()); + } + + if (procedure.isFailed()) { + builder.setException(ForeignExceptionUtil.toProtoForeignException(procedure.getException())); + } + + if (procedure.hasResultData()) { + builder.setResult(UnsafeByteOperations.unsafeWrap(procedure.getResult())); + } + + return builder.build(); + } + + /** + * Helper to convert the protobuf object. + * @return Convert the current Protocol Buffers Procedure to {@link ProcedureInfo} + * instance. + */ + public static ProcedureInfo toProcedureInfo(ProcedureProtos.Procedure procedureProto) { + NonceKey nonceKey = null; + + if (procedureProto.getNonce() != HConstants.NO_NONCE) { + nonceKey = new NonceKey(procedureProto.getNonceGroup(), procedureProto.getNonce()); + } + + return new ProcedureInfo(procedureProto.getProcId(), procedureProto.getClassName(), + procedureProto.hasOwner() ? procedureProto.getOwner() : null, + ProcedureState.valueOf(procedureProto.getState().name()), + procedureProto.hasParentId() ? procedureProto.getParentId() : -1, nonceKey, + procedureProto.hasException() ? + ForeignExceptionUtil.toIOException(procedureProto.getException()) : null, + procedureProto.getLastUpdate(), procedureProto.getSubmittedTime(), + procedureProto.hasResult() ? procedureProto.getResult().toByteArray() : null); + } + + public static LockServiceProtos.ResourceType toProtoResourceType( + LockInfo.ResourceType resourceType) { + switch (resourceType) { + case SERVER: + return LockServiceProtos.ResourceType.RESOURCE_TYPE_SERVER; + case NAMESPACE: + return LockServiceProtos.ResourceType.RESOURCE_TYPE_NAMESPACE; + case TABLE: + return LockServiceProtos.ResourceType.RESOURCE_TYPE_TABLE; + case REGION: + return LockServiceProtos.ResourceType.RESOURCE_TYPE_REGION; + default: + throw new IllegalArgumentException("Unknown resource type: " + resourceType); + } + } + + public static LockInfo.ResourceType toResourceType( + LockServiceProtos.ResourceType resourceTypeProto) { + switch (resourceTypeProto) { + case RESOURCE_TYPE_SERVER: + return LockInfo.ResourceType.SERVER; + case RESOURCE_TYPE_NAMESPACE: + return LockInfo.ResourceType.NAMESPACE; + case RESOURCE_TYPE_TABLE: + return LockInfo.ResourceType.TABLE; + case RESOURCE_TYPE_REGION: + return LockInfo.ResourceType.REGION; + default: + throw new IllegalArgumentException("Unknown resource type: " + resourceTypeProto); + } + } + + public static LockServiceProtos.LockType toProtoLockType( + LockInfo.LockType lockType) { + return LockServiceProtos.LockType.valueOf(lockType.name()); + } + + public static LockInfo.LockType toLockType( + LockServiceProtos.LockType lockTypeProto) { + return LockInfo.LockType.valueOf(lockTypeProto.name()); + } + + public static LockServiceProtos.WaitingProcedure toProtoWaitingProcedure( + LockInfo.WaitingProcedure waitingProcedure) { + LockServiceProtos.WaitingProcedure.Builder builder = LockServiceProtos.WaitingProcedure.newBuilder(); + + ProcedureProtos.Procedure procedureProto = + toProtoProcedure(waitingProcedure.getProcedure()); + + builder + .setLockType(toProtoLockType(waitingProcedure.getLockType())) + .setProcedure(procedureProto); + + return builder.build(); + } + + public static LockInfo.WaitingProcedure toWaitingProcedure( + LockServiceProtos.WaitingProcedure waitingProcedureProto) { + LockInfo.WaitingProcedure waiting = new LockInfo.WaitingProcedure(); + + waiting.setLockType(toLockType(waitingProcedureProto.getLockType())); + + ProcedureInfo procedure = + toProcedureInfo(waitingProcedureProto.getProcedure()); + waiting.setProcedure(procedure); + + return waiting; + } + + public static LockServiceProtos.LockInfo toProtoLockInfo(LockInfo lock) + { + LockServiceProtos.LockInfo.Builder builder = LockServiceProtos.LockInfo.newBuilder(); + + builder + .setResourceType(toProtoResourceType(lock.getResourceType())) + .setResourceName(lock.getResourceName()) + .setLockType(toProtoLockType(lock.getLockType())); + + ProcedureInfo exclusiveLockOwnerProcedure = lock.getExclusiveLockOwnerProcedure(); + + if (exclusiveLockOwnerProcedure != null) { + Procedure exclusiveLockOwnerProcedureProto = + toProtoProcedure(lock.getExclusiveLockOwnerProcedure()); + builder.setExclusiveLockOwnerProcedure(exclusiveLockOwnerProcedureProto); + } + + builder.setSharedLockCount(lock.getSharedLockCount()); + + for (LockInfo.WaitingProcedure waitingProcedure : lock.getWaitingProcedures()) { + builder.addWaitingProcedures(toProtoWaitingProcedure(waitingProcedure)); + } + + return builder.build(); + } + + public static LockInfo toLockInfo(LockServiceProtos.LockInfo lockProto) + { + LockInfo lock = new LockInfo(); + + lock.setResourceType(toResourceType(lockProto.getResourceType())); + lock.setResourceName(lockProto.getResourceName()); + lock.setLockType(toLockType(lockProto.getLockType())); + + if (lockProto.hasExclusiveLockOwnerProcedure()) { + ProcedureInfo exclusiveLockOwnerProcedureProto = + toProcedureInfo(lockProto.getExclusiveLockOwnerProcedure()); + + lock.setExclusiveLockOwnerProcedure(exclusiveLockOwnerProcedureProto); + } + + lock.setSharedLockCount(lockProto.getSharedLockCount()); + + for (LockServiceProtos.WaitingProcedure waitingProcedureProto : lockProto.getWaitingProceduresList()) { + lock.addWaitingProcedure(toWaitingProcedure(waitingProcedureProto)); + } + + return lock; + } +} http://git-wip-us.apache.org/repos/asf/hbase/blob/25575064/hbase-common/src/main/java/org/apache/hadoop/hbase/procedure2/LockInfo.java ---------------------------------------------------------------------- diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/procedure2/LockInfo.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/procedure2/LockInfo.java new file mode 100644 index 0000000..30ecee8 --- /dev/null +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/procedure2/LockInfo.java @@ -0,0 +1,128 @@ +/* + * 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.procedure2; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.hadoop.hbase.ProcedureInfo; +import org.apache.hadoop.hbase.classification.InterfaceAudience; + +@InterfaceAudience.Public +public class LockInfo { + @InterfaceAudience.Public + public enum ResourceType { + SERVER, NAMESPACE, TABLE, REGION + } + + @InterfaceAudience.Public + public enum LockType { + EXCLUSIVE, SHARED + } + + @InterfaceAudience.Public + public static class WaitingProcedure { + private LockType lockType; + private ProcedureInfo procedure; + + public WaitingProcedure() { + } + + public LockType getLockType() { + return lockType; + } + + public void setLockType(LockType lockType) { + this.lockType = lockType; + } + + public ProcedureInfo getProcedure() { + return procedure; + } + + public void setProcedure(ProcedureInfo procedure) { + this.procedure = procedure; + } + } + + private ResourceType resourceType; + private String resourceName; + private LockType lockType; + private ProcedureInfo exclusiveLockOwnerProcedure; + private int sharedLockCount; + private final List<WaitingProcedure> waitingProcedures; + + public LockInfo() { + waitingProcedures = new ArrayList<>(); + } + + public ResourceType getResourceType() { + return resourceType; + } + + public void setResourceType(ResourceType resourceType) { + this.resourceType = resourceType; + } + + public String getResourceName() { + return resourceName; + } + + public void setResourceName(String resourceName) { + this.resourceName = resourceName; + } + + public LockType getLockType() { + return lockType; + } + + public void setLockType(LockType lockType) { + this.lockType = lockType; + } + + public ProcedureInfo getExclusiveLockOwnerProcedure() { + return exclusiveLockOwnerProcedure; + } + + public void setExclusiveLockOwnerProcedure( + ProcedureInfo exclusiveLockOwnerProcedure) { + this.exclusiveLockOwnerProcedure = exclusiveLockOwnerProcedure; + } + + public int getSharedLockCount() { + return sharedLockCount; + } + + public void setSharedLockCount(int sharedLockCount) { + this.sharedLockCount = sharedLockCount; + } + + public List<WaitingProcedure> getWaitingProcedures() { + return waitingProcedures; + } + + public void setWaitingProcedures(List<WaitingProcedure> waitingProcedures) { + this.waitingProcedures.clear(); + this.waitingProcedures.addAll(waitingProcedures); + } + + public void addWaitingProcedure(WaitingProcedure waitingProcedure) { + waitingProcedures.add(waitingProcedure); + } +} http://git-wip-us.apache.org/repos/asf/hbase/blob/25575064/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/LockAndQueue.java ---------------------------------------------------------------------- diff --git a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/LockAndQueue.java b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/LockAndQueue.java index e11c23c..2c307b7 100644 --- a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/LockAndQueue.java +++ b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/LockAndQueue.java @@ -43,7 +43,7 @@ package org.apache.hadoop.hbase.procedure2; * We do not use ReentrantReadWriteLock directly because of its high memory overhead. */ public class LockAndQueue extends ProcedureDeque implements LockStatus { - private long exclusiveLockProcIdOwner = Long.MIN_VALUE; + private Procedure<?> exclusiveLockOwnerProcedure = null; private int sharedLock = 0; // ====================================================================== @@ -57,12 +57,12 @@ public class LockAndQueue extends ProcedureDeque implements LockStatus { @Override public boolean hasExclusiveLock() { - return this.exclusiveLockProcIdOwner != Long.MIN_VALUE; + return this.exclusiveLockOwnerProcedure != null; } @Override public boolean isLockOwner(long procId) { - return exclusiveLockProcIdOwner == procId; + return getExclusiveLockProcIdOwner() == procId; } @Override @@ -76,8 +76,17 @@ public class LockAndQueue extends ProcedureDeque implements LockStatus { } @Override + public Procedure<?> getExclusiveLockOwnerProcedure() { + return exclusiveLockOwnerProcedure; + } + + @Override public long getExclusiveLockProcIdOwner() { - return exclusiveLockProcIdOwner; + if (exclusiveLockOwnerProcedure == null) { + return Long.MIN_VALUE; + } else { + return exclusiveLockOwnerProcedure.getProcId(); + } } @Override @@ -101,7 +110,7 @@ public class LockAndQueue extends ProcedureDeque implements LockStatus { public boolean tryExclusiveLock(final Procedure proc) { if (isLocked()) return hasLockAccess(proc); - exclusiveLockProcIdOwner = proc.getProcId(); + exclusiveLockOwnerProcedure = proc; return true; } @@ -110,7 +119,7 @@ public class LockAndQueue extends ProcedureDeque implements LockStatus { */ public boolean releaseExclusiveLock(final Procedure proc) { if (isLockOwner(proc.getProcId())) { - exclusiveLockProcIdOwner = Long.MIN_VALUE; + exclusiveLockOwnerProcedure = null; return true; } return false; http://git-wip-us.apache.org/repos/asf/hbase/blob/25575064/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/LockStatus.java ---------------------------------------------------------------------- diff --git a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/LockStatus.java b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/LockStatus.java index 9f2aae7..f32ef76 100644 --- a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/LockStatus.java +++ b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/LockStatus.java @@ -29,6 +29,7 @@ public interface LockStatus { boolean isLockOwner(long procId); boolean hasParentLock(final Procedure proc); boolean hasLockAccess(final Procedure proc); + Procedure<?> getExclusiveLockOwnerProcedure(); long getExclusiveLockProcIdOwner(); int getSharedLockCount(); } http://git-wip-us.apache.org/repos/asf/hbase/blob/25575064/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureScheduler.java ---------------------------------------------------------------------- diff --git a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureScheduler.java b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureScheduler.java index 617532b..b5295e7 100644 --- a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureScheduler.java +++ b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureScheduler.java @@ -20,6 +20,7 @@ package org.apache.hadoop.hbase.procedure2; import com.google.common.annotations.VisibleForTesting; +import java.util.List; import java.util.concurrent.TimeUnit; import org.apache.hadoop.hbase.classification.InterfaceAudience; @@ -121,6 +122,12 @@ public interface ProcedureScheduler { boolean waitEvent(ProcedureEvent event, Procedure procedure); /** + * List lock queues. + * @return the locks + */ + List<LockInfo> listLocks(); + + /** * Returns the number of elements in this queue. * @return the number of elements in this queue. */ http://git-wip-us.apache.org/repos/asf/hbase/blob/25575064/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureUtil.java ---------------------------------------------------------------------- diff --git a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureUtil.java b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureUtil.java index b4222c7..7ce7568 100644 --- a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureUtil.java +++ b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/ProcedureUtil.java @@ -17,8 +17,6 @@ */ package org.apache.hadoop.hbase.procedure2; -import com.google.common.base.Preconditions; - import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.Modifier; @@ -33,6 +31,8 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos; import org.apache.hadoop.hbase.util.ForeignExceptionUtil; import org.apache.hadoop.hbase.util.NonceKey; +import com.google.common.base.Preconditions; + /** * Helper to convert to/from ProcedureProtos */ http://git-wip-us.apache.org/repos/asf/hbase/blob/25575064/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/SimpleProcedureScheduler.java ---------------------------------------------------------------------- diff --git a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/SimpleProcedureScheduler.java b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/SimpleProcedureScheduler.java index 788f4ff..176a900 100644 --- a/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/SimpleProcedureScheduler.java +++ b/hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/SimpleProcedureScheduler.java @@ -18,10 +18,13 @@ package org.apache.hadoop.hbase.procedure2; -import com.google.common.annotations.VisibleForTesting; +import java.util.Collections; +import java.util.List; import org.apache.hadoop.hbase.classification.InterfaceAudience; import org.apache.hadoop.hbase.classification.InterfaceStability; +import com.google.common.annotations.VisibleForTesting; + /** * Simple scheduler for procedures */ @@ -73,4 +76,9 @@ public class SimpleProcedureScheduler extends AbstractProcedureScheduler { @Override public void completionCleanup(Procedure proc) { } + + @Override + public List<LockInfo> listLocks() { + return Collections.emptyList(); + } } \ No newline at end of file