From 6b55b8dbe64851ad7e53f2ccba5b73935033da98 Mon Sep 17 00:00:00 2001 From: Zhihong Yu Date: Sat, 16 Jul 2011 01:18:36 +0000 Subject: [PATCH] HBASE-4087 HBaseAdmin should perform validation of connection it holds git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1147352 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES.txt | 1 + .../hadoop/hbase/client/HBaseAdmin.java | 34 ++++++++++++++----- .../hbase/client/HConnectionManager.java | 30 ++++++++++++---- 3 files changed, 50 insertions(+), 15 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 28f888d0f4e..b3a3f063e4f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -160,6 +160,7 @@ Release 0.91.0 - Unreleased HRegion.delete (Adam Warrington via Ted Yu) HBASE-3893 HRegion.internalObtainRowLock shouldn't wait forever HBASE-4075 A bug in TestZKBasedOpenCloseRegion (Jieshan Bean via Ted Yu) + HBASE-4087 HBaseAdmin should perform validation of connection it holds IMPROVEMENTS HBASE-3290 Max Compaction Size (Nicolas Spiegelberg via Stack) diff --git a/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java b/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java index 8c44fde3a2d..567eb3c003b 100644 --- a/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java +++ b/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java @@ -1,5 +1,5 @@ /** - * Copyright 2010 The Apache Software Foundation + * Copyright 2011 The Apache Software Foundation * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -22,12 +22,11 @@ package org.apache.hadoop.hbase.client; import java.io.Closeable; import java.io.IOException; import java.io.InterruptedIOException; +import java.lang.reflect.UndeclaredThrowableException; import java.net.SocketTimeoutException; import java.util.Arrays; import java.util.LinkedList; import java.util.List; -import java.util.Map; -import java.util.TreeMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Pattern; @@ -76,7 +75,7 @@ import org.apache.hadoop.util.StringUtils; public class HBaseAdmin implements Abortable, Closeable { private final Log LOG = LogFactory.getLog(this.getClass().getName()); // private final HConnection connection; - private final HConnection connection; + private HConnection connection; private volatile Configuration conf; private final long pause; private final int numRetries; @@ -84,7 +83,7 @@ public class HBaseAdmin implements Abortable, Closeable { // numRetries is for 'normal' stuff... Mutliply by this factor when // want to wait a long time. private final int retryLongerMultiplier; - + /** * Constructor * @@ -95,11 +94,30 @@ public class HBaseAdmin implements Abortable, Closeable { public HBaseAdmin(Configuration c) throws MasterNotRunningException, ZooKeeperConnectionException { this.conf = HBaseConfiguration.create(c); - this.connection = HConnectionManager.getConnection(this.conf); + this.connection = HConnectionManager.getConnection(this.conf); this.pause = this.conf.getLong("hbase.client.pause", 1000); this.numRetries = this.conf.getInt("hbase.client.retries.number", 10); - this.retryLongerMultiplier = this.conf.getInt("hbase.client.retries.longer.multiplier", 10); - this.connection.getMaster(); + this.retryLongerMultiplier = this.conf.getInt( + "hbase.client.retries.longer.multiplier", 10); + int tries = 0; + for (; tries < numRetries; ++tries) { + try { + this.connection.getMaster(); + break; + } catch (UndeclaredThrowableException ute) { + HConnectionManager.deleteStaleConnection(this.connection); + this.connection = HConnectionManager.getConnection(this.conf); + } + try { // Sleep + Thread.sleep(getPauseTime(tries)); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new MasterNotRunningException("Interrupted"); + } + } + if (tries >= numRetries) { + throw new MasterNotRunningException("Retried " + numRetries + " times"); + } } /** diff --git a/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java b/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java index f5c2e88219f..0b9deac2550 100644 --- a/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java +++ b/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java @@ -199,7 +199,21 @@ public class HConnectionManager { * . */ public static void deleteConnection(Configuration conf, boolean stopProxy) { - deleteConnection(new HConnectionKey(conf), stopProxy); + deleteConnection(new HConnectionKey(conf), stopProxy, false); + } + + /** + * Delete stale connection information for the instance specified by configuration. + * This will then close connection to + * the zookeeper ensemble and let go of all resources. + * + * @param conf + * configuration whose identity is used to find {@link HConnection} + * instance. + * . + */ + public static void deleteStaleConnection(HConnection connection) { + deleteConnection(connection, true, true); } /** @@ -212,31 +226,33 @@ public class HConnectionManager { Set connectionKeys = new HashSet(); connectionKeys.addAll(HBASE_INSTANCES.keySet()); for (HConnectionKey connectionKey : connectionKeys) { - deleteConnection(connectionKey, stopProxy); + deleteConnection(connectionKey, stopProxy, false); } HBASE_INSTANCES.clear(); } } - private static void deleteConnection(HConnection connection, boolean stopProxy) { + private static void deleteConnection(HConnection connection, boolean stopProxy, + boolean staleConnection) { synchronized (HBASE_INSTANCES) { for (Entry connectionEntry : HBASE_INSTANCES .entrySet()) { if (connectionEntry.getValue() == connection) { - deleteConnection(connectionEntry.getKey(), stopProxy); + deleteConnection(connectionEntry.getKey(), stopProxy, staleConnection); break; } } } } - private static void deleteConnection(HConnectionKey connectionKey, boolean stopProxy) { + private static void deleteConnection(HConnectionKey connectionKey, + boolean stopProxy, boolean staleConnection) { synchronized (HBASE_INSTANCES) { HConnectionImplementation connection = HBASE_INSTANCES .get(connectionKey); if (connection != null) { connection.decCount(); - if (connection.isZeroReference()) { + if (connection.isZeroReference() || staleConnection) { HBASE_INSTANCES.remove(connectionKey); connection.close(stopProxy); } else if (stopProxy) { @@ -1699,7 +1715,7 @@ public class HConnectionManager { } public void close() { - HConnectionManager.deleteConnection(this, stopProxy); + HConnectionManager.deleteConnection((HConnection)this, stopProxy, false); LOG.debug("The connection to " + this.zooKeeper + " has been closed."); }