You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by st...@apache.org on 2013/05/07 20:41:16 UTC
svn commit: r1480013 - in /hbase/branches/0.95:
hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java
Author: stack
Date: Tue May 7 18:41:15 2013
New Revision: 1480013
URL: http://svn.apache.org/r1480013
Log:
HBASE-8483 HConnectionManager can leak ZooKeeper connections when using deleteStaleConnection
Modified:
hbase/branches/0.95/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java
Modified: hbase/branches/0.95/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java?rev=1480013&r1=1480012&r2=1480013&view=diff
==============================================================================
--- hbase/branches/0.95/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java (original)
+++ hbase/branches/0.95/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HConnectionManager.java Tue May 7 18:41:15 2013
@@ -1579,6 +1579,9 @@ public class HConnectionManager {
throws IOException {
synchronized (masterAndZKLock) {
if (keepAliveZookeeper == null) {
+ if (this.closed) {
+ throw new IOException(toString() + " closed");
+ }
// We don't check that our link to ZooKeeper is still valid
// But there is a retry mechanism in the ZooKeeperWatcher itself
keepAliveZookeeper = new ZooKeeperKeepAliveConnection(
@@ -2640,12 +2643,12 @@ public class HConnectionManager {
}
delayedClosing.stop("Closing connection");
closeMaster();
+ this.closed = true;
closeZooKeeperWatcher();
this.stubs.clear();
if (clusterStatusListener != null) {
clusterStatusListener.close();
}
- this.closed = true;
}
@Override
Modified: hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java?rev=1480013&r1=1480012&r2=1480013&view=diff
==============================================================================
--- hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java (original)
+++ hbase/branches/0.95/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java Tue May 7 18:41:15 2013
@@ -56,6 +56,7 @@ import org.apache.hadoop.hbase.util.Envi
import org.apache.hadoop.hbase.util.ManualEnvironmentEdge;
import org.apache.hadoop.hbase.util.JVMClusterUtil;
import org.apache.hadoop.hbase.util.Threads;
+import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
@@ -75,6 +76,7 @@ public class TestHCM {
private static final byte[] TABLE_NAME1 = Bytes.toBytes("test1");
private static final byte[] TABLE_NAME2 = Bytes.toBytes("test2");
private static final byte[] TABLE_NAME3 = Bytes.toBytes("test3");
+ private static final byte[] TABLE_NAME4 = Bytes.toBytes("test4");
private static final byte[] FAM_NAM = Bytes.toBytes("f");
private static final byte[] ROW = Bytes.toBytes("bbb");
private static final byte[] ROW_X = Bytes.toBytes("xxx");
@@ -799,5 +801,63 @@ public class TestHCM {
assertTrue("Value not within jitter: " + expected + " vs " + actual,
Math.abs(actual - expected) <= (0.01f * jitterBase));
}
+
+ /**
+ * Tests that a closed connection does not have a live zookeeper
+ * @throws Exception
+ */
+ @Test
+ public void testDeleteForZKConnLeak() throws Exception {
+ TEST_UTIL.createTable(TABLE_NAME4, FAM_NAM);
+ final Configuration config = TEST_UTIL.getConfiguration();
+
+ ThreadPoolExecutor pool = new ThreadPoolExecutor(1, 10,
+ 5, TimeUnit.SECONDS,
+ new SynchronousQueue<Runnable>(),
+ Threads.newDaemonThreadFactory("test-hcm-delete"));
+
+ pool.submit(new Runnable() {
+ @Override
+ public void run() {
+ while (!Thread.interrupted()) {
+ try {
+ HConnection conn = HConnectionManager.getConnection(config);
+ HConnectionManager.deleteStaleConnection(conn);
+ } catch (Exception e) {
+ }
+ }
+ }
+ });
+
+ // use connection multiple times
+ for (int i = 0; i < 50; i++) {
+ HConnection c1 = null;
+ try {
+ c1 = HConnectionManager.getConnection(config);
+ HTable table = new HTable(TABLE_NAME4, c1, pool);
+ table.close();
+ } catch (Exception e) {
+ } finally {
+ if (c1 != null) {
+ if (c1.isClosed()) {
+ // cannot use getZooKeeper as method instantiates watcher if null
+ Field zkwField = c1.getClass().getDeclaredField("keepAliveZookeeper");
+ zkwField.setAccessible(true);
+ Object watcher = zkwField.get(c1);
+
+ if (watcher != null) {
+ if (((ZooKeeperWatcher)watcher).getRecoverableZooKeeper().getState().isAlive()) {
+ pool.shutdownNow();
+ fail("Live zookeeper in closed connection");
+ }
+ }
+ }
+ c1.close();
+ }
+ }
+ }
+
+ pool.shutdownNow();
+ }
}