From 86f8282befd085dc07b43def62a3168666ed8852 Mon Sep 17 00:00:00 2001 From: larsh Date: Sat, 31 Mar 2012 00:26:22 +0000 Subject: [PATCH] HBASE-5084 Clow different HTable instances to share one ExecutorService git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1307661 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/hadoop/hbase/client/HTable.java | 35 ++++++++++++++++-- .../apache/hadoop/hbase/client/TestHCM.java | 37 +++++++++++++++---- 2 files changed, 60 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/apache/hadoop/hbase/client/HTable.java b/src/main/java/org/apache/hadoop/hbase/client/HTable.java index fb201e772da..3db02955ef2 100644 --- a/src/main/java/org/apache/hadoop/hbase/client/HTable.java +++ b/src/main/java/org/apache/hadoop/hbase/client/HTable.java @@ -119,7 +119,8 @@ public class HTable implements HTableInterface { private boolean closed; private int operationTimeout; private static final int DOPUT_WB_CHECK = 10; // i.e., doPut checks the writebuffer every X Puts. - private final boolean cleanupOnClose; // close the connection in close() + private final boolean cleanupPoolOnClose; // shutdown the pool in close() + private final boolean cleanupConnectionOnClose; // close the connection in close() /** * Creates an object to access a HBase table. @@ -150,7 +151,7 @@ public class HTable implements HTableInterface { public HTable(Configuration conf, final byte [] tableName) throws IOException { this.tableName = tableName; - this.cleanupOnClose = true; + this.cleanupPoolOnClose = this.cleanupConnectionOnClose = true; if (conf == null) { this.connection = null; return; @@ -177,6 +178,30 @@ public class HTable implements HTableInterface { this.finishSetup(); } + /** + * Creates an object to access a HBase table. + * Shares zookeeper connection and other resources with other HTable instances + * created with the same conf instance. Uses already-populated + * region cache if one is available, populated by any other HTable instances + * sharing this conf instance. + * Use this constructor when the ExecutorService is externally managed. + * @param conf Configuration object to use. + * @param tableName Name of the table. + * @param pool ExecutorService to be used. + * @throws IOException if a remote or network exception occurs + */ + public HTable(Configuration conf, final byte[] tableName, final ExecutorService pool) + throws IOException { + this.connection = HConnectionManager.getConnection(conf); + this.configuration = conf; + this.pool = pool; + this.tableName = tableName; + this.cleanupPoolOnClose = false; + this.cleanupConnectionOnClose = true; + + this.finishSetup(); + } + /** * Creates an object to access a HBase table. * Shares zookeeper connection and other resources with other HTable instances @@ -197,7 +222,7 @@ public class HTable implements HTableInterface { throw new IllegalArgumentException("Connection is null or closed."); } this.tableName = tableName; - this.cleanupOnClose = false; + this.cleanupPoolOnClose = this.cleanupConnectionOnClose = false; this.connection = connection; this.configuration = connection.getConfiguration(); this.pool = pool; @@ -965,8 +990,10 @@ public class HTable implements HTableInterface { return; } flushCommits(); - if (cleanupOnClose) { + if (cleanupPoolOnClose) { this.pool.shutdown(); + } + if (cleanupConnectionOnClose) { if (this.connection != null) { this.connection.close(); } diff --git a/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java b/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java index bf6b49a2ba2..e7ceac2107c 100644 --- a/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java +++ b/src/test/java/org/apache/hadoop/hbase/client/TestHCM.java @@ -23,22 +23,19 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertEquals; -import java.io.IOException; -import java.lang.reflect.Field; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Random; -import java.util.Set; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; -import org.apache.commons.httpclient.HostConfiguration; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.*; +import org.apache.hadoop.hbase.client.HTable.DaemonThreadFactory; import org.apache.hadoop.hbase.util.Bytes; import org.junit.AfterClass; import org.junit.Assert; @@ -54,6 +51,7 @@ public class TestHCM { private static final Log LOG = LogFactory.getLog(TestHCM.class); private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); private static final byte[] TABLE_NAME = Bytes.toBytes("test"); + private static final byte[] TABLE_NAME1 = Bytes.toBytes("test1"); private static final byte[] FAM_NAM = Bytes.toBytes("f"); private static final byte[] ROW = Bytes.toBytes("bbb"); @@ -136,10 +134,33 @@ public class TestHCM { conn.deleteCachedLocation(TABLE_NAME, ROW); HRegionLocation rl = conn.getCachedLocation(TABLE_NAME, ROW); assertNull("What is this location?? " + rl, rl); - conn.close(); table.close(); } + /** + * Test that Connection or Pool are not closed when managed externally + * @throws Exception + */ + @Test + public void testConnectionManagement() throws Exception{ + TEST_UTIL.createTable(TABLE_NAME1, FAM_NAM); + HConnection conn = HConnectionManager.createConnection(TEST_UTIL.getConfiguration()); + ThreadPoolExecutor pool = new ThreadPoolExecutor(1, 10, + 60, TimeUnit.SECONDS, + new SynchronousQueue(), + new DaemonThreadFactory()); + + HTable table = new HTable(TABLE_NAME1, conn, pool); + table.close(); + assertFalse(conn.isClosed()); + assertFalse(pool.isShutdown()); + table = new HTable(TEST_UTIL.getConfiguration(), TABLE_NAME1, pool); + table.close(); + assertFalse(pool.isShutdown()); + conn.close(); + pool.shutdownNow(); + } + /** * Make sure that {@link HConfiguration} instances that are essentially the * same map to the same {@link HConnection} instance.