Repository: phoenix Updated Branches: refs/heads/4.x-HBase-0.98 900f886f2 -> 49b78474e
PHOENIX-2496 Attempt to gracefully close in ShutdownHook, but still exit promptly. The JVM will not exit until all ShutdownHooks have completed. Blocking until a query thread completes might be on the order of minutes which is undesirable. Try to clean up, but exit quickly. Introduces configuration property 'phoenix.shutdown.timeoutMs' with a default value of 5000 (5 seconds). Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/49b78474 Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/49b78474 Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/49b78474 Branch: refs/heads/4.x-HBase-0.98 Commit: 49b78474e9a8d694f861f6af821e01eb795b448d Parents: 900f886 Author: Josh Elser <[email protected]> Authored: Tue Dec 8 10:59:38 2015 -0500 Committer: Thomas D'Silva <[email protected]> Committed: Tue Dec 8 14:11:17 2015 -0800 ---------------------------------------------------------------------- .../org/apache/phoenix/jdbc/PhoenixDriver.java | 43 +++++++++++++++++++- .../org/apache/phoenix/query/QueryServices.java | 1 + .../phoenix/query/QueryServicesOptions.java | 1 + 3 files changed, 44 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/49b78474/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDriver.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDriver.java b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDriver.java index bb0b1e2..0f5d4aa 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDriver.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/jdbc/PhoenixDriver.java @@ -23,16 +23,26 @@ import java.sql.SQLException; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import javax.annotation.concurrent.GuardedBy; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.phoenix.query.ConnectionQueryServices; import org.apache.phoenix.query.ConnectionQueryServicesImpl; import org.apache.phoenix.query.ConnectionlessQueryServicesImpl; +import org.apache.phoenix.query.HBaseFactoryProvider; import org.apache.phoenix.query.QueryServices; import org.apache.phoenix.query.QueryServicesImpl; +import org.apache.phoenix.query.QueryServicesOptions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -64,7 +74,38 @@ public final class PhoenixDriver extends PhoenixEmbeddedDriver { Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { - closeInstance(INSTANCE); + final Configuration config = + HBaseFactoryProvider.getConfigurationFactory().getConfiguration(); + final ExecutorService svc = Executors.newSingleThreadExecutor(); + Future<?> future = svc.submit(new Runnable() { + @Override + public void run() { + closeInstance(INSTANCE); + } + }); + + // Pull the timeout value (default 5s). + long millisBeforeShutdown = config.getLong( + QueryServices.DRIVER_SHUTDOWN_TIMEOUT_MS, + QueryServicesOptions.DEFAULT_DRIVER_SHUTDOWN_TIMEOUT_MS); + + // Close with a timeout. If this is running, we know the JVM wants to + // go down. There may be other threads running that are holding the lock. + // We don't want to be blocked on them (for the normal HBase retry policy). + // + // We don't care about any exceptions, we're going down anyways. + try { + future.get(millisBeforeShutdown, TimeUnit.MILLISECONDS); + } catch (ExecutionException e) { + logger.warn("Failed to close instance", e); + } catch (InterruptedException e) { + logger.warn("Interrupted waiting to close instance", e); + } catch (TimeoutException e) { + logger.warn("Timed out waiting to close instance", e); + } + + // We're going down, but try to clean up. + svc.shutdown(); } }); http://git-wip-us.apache.org/repos/asf/phoenix/blob/49b78474/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java index 0d4d8fe..62d7ba9 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServices.java @@ -50,6 +50,7 @@ public interface QueryServices extends SQLCloseable { public static final String AUTO_COMMIT_ATTRIB = "phoenix.connection.autoCommit"; // joni byte regex engine setting public static final String USE_BYTE_BASED_REGEX_ATTRIB = "phoenix.regex.byteBased"; + public static final String DRIVER_SHUTDOWN_TIMEOUT_MS = "phoenix.shutdown.timeoutMs"; /** * max size to spool the the result into http://git-wip-us.apache.org/repos/asf/phoenix/blob/49b78474/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java index 86da176..a22d64f 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryServicesOptions.java @@ -108,6 +108,7 @@ public class QueryServicesOptions { public static final boolean DEFAULT_USE_INDEXES = true; // Use indexes public static final boolean DEFAULT_IMMUTABLE_ROWS = false; // Tables rows may be updated public static final boolean DEFAULT_DROP_METADATA = true; // Drop meta data also. + public static final long DEFAULT_DRIVER_SHUTDOWN_TIMEOUT_MS = 5 * 1000; // Time to wait in ShutdownHook to exit gracefully. public final static int DEFAULT_MUTATE_BATCH_SIZE = 1000; // Batch size for UPSERT SELECT and DELETE // The only downside of it being out-of-sync is that the parallelization of the scan won't be as balanced as it could be.
