From b81c8ba8bc6ce48691930722ae5d4ea20ad5d9af Mon Sep 17 00:00:00 2001 From: Brett Wooldridge Date: Fri, 11 Oct 2013 19:20:25 +0900 Subject: [PATCH] Start of work to allow loading from a Properties file. --- .../java/com/zaxxer/hikari/HikariConfig.java | 58 ++++++++++++++----- .../com/zaxxer/hikari/HikariDataSource.java | 18 ++++-- .../java/com/zaxxer/hikari/HikariPool.java | 16 ++--- .../java/com/zaxxer/hikari/CreationTest.java | 6 +- .../zaxxer/hikari/performance/Benchmarks.java | 29 +++++++--- 5 files changed, 84 insertions(+), 43 deletions(-) diff --git a/src/main/java/com/zaxxer/hikari/HikariConfig.java b/src/main/java/com/zaxxer/hikari/HikariConfig.java index f8c50107..14f51061 100644 --- a/src/main/java/com/zaxxer/hikari/HikariConfig.java +++ b/src/main/java/com/zaxxer/hikari/HikariConfig.java @@ -3,6 +3,10 @@ */ package com.zaxxer.hikari; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Properties; import java.util.concurrent.TimeUnit; import org.slf4j.Logger; @@ -31,15 +35,15 @@ public class HikariConfig private String connectionUrl; private int acquireIncrement; private int acquireRetries; - private int acquireRetryDelay; - private int connectionTimeout; + private long acquireRetryDelay; + private long connectionTimeout; private String connectionTestQuery; private String dataSourceClassName; private String proxyFactoryType; private boolean isJdbc4connectionTest; - private int maxLifetime; - private int leakDetectionThreshold; - private int idleTimeout; + private long maxLifetime; + private long leakDetectionThreshold; + private long idleTimeout; /** * Default constructor @@ -49,10 +53,32 @@ public class HikariConfig acquireIncrement = 1; maxPoolSize = 1; connectionTimeout = Integer.MAX_VALUE; - idleTimeout = (int) TimeUnit.MINUTES.toMillis(30); + idleTimeout = TimeUnit.MINUTES.toMillis(30); proxyFactoryType = "auto"; } + public HikariConfig(String propertyFileName) + { + this(); + + File propFile = new File(propertyFileName); + if (!propFile.isFile()) + { + throw new IllegalArgumentException("Property file " + propertyFileName + " was not found."); + } + + try + { + FileInputStream fis = new FileInputStream(propFile); + Properties props = new Properties(); + props.load(fis); + } + catch (IOException io) + { + throw new RuntimeException("Error loading properties file", io); + } + } + public int getAcquireIncrement() { return acquireIncrement; @@ -81,12 +107,12 @@ public class HikariConfig this.acquireRetries = acquireRetries; } - public int getAcquireRetryDelay() + public long getAcquireRetryDelay() { return acquireRetryDelay; } - public void setAcquireRetryDelay(int acquireRetryDelayMs) + public void setAcquireRetryDelay(long acquireRetryDelayMs) { if (acquireRetryDelayMs < 0) { @@ -105,12 +131,12 @@ public class HikariConfig this.connectionTestQuery = connectionTestQuery; } - public int getConnectionTimeout() + public long getConnectionTimeout() { return connectionTimeout; } - public void setConnectionTimeout(int connectionTimeoutMs) + public void setConnectionTimeout(long connectionTimeoutMs) { if (connectionTimeoutMs < 0) { @@ -139,12 +165,12 @@ public class HikariConfig this.dataSourceClassName = className; } - public int getIdleTimeout() + public long getIdleTimeout() { return idleTimeout; } - public void setIdleTimeout(int idleTimeoutMs) + public void setIdleTimeout(long idleTimeoutMs) { this.idleTimeout = idleTimeoutMs; } @@ -159,22 +185,22 @@ public class HikariConfig this.isJdbc4connectionTest = useIsValid; } - public int getLeakDetectionThreshold() + public long getLeakDetectionThreshold() { return leakDetectionThreshold; } - public void setLeakDetectionThreshold(int leakDetectionThresholdMs) + public void setLeakDetectionThreshold(long leakDetectionThresholdMs) { this.leakDetectionThreshold = leakDetectionThresholdMs; } - public int getMaxLifetime() + public long getMaxLifetime() { return maxLifetime; } - public void setMaxLifetime(int maxLifetimeMs) + public void setMaxLifetime(long maxLifetimeMs) { this.maxLifetime = maxLifetimeMs; } diff --git a/src/main/java/com/zaxxer/hikari/HikariDataSource.java b/src/main/java/com/zaxxer/hikari/HikariDataSource.java index be4f8c5b..910a5f10 100644 --- a/src/main/java/com/zaxxer/hikari/HikariDataSource.java +++ b/src/main/java/com/zaxxer/hikari/HikariDataSource.java @@ -26,6 +26,11 @@ import javax.sql.DataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * The HikariCP pooled DataSource. + * + * @author Brett Wooldridge + */ public class HikariDataSource implements DataSource { private static final Logger LOGGER = LoggerFactory.getLogger(HikariDataSource.class); @@ -35,13 +40,14 @@ public class HikariDataSource implements DataSource // Package scope for testing HikariPool pool; - public HikariDataSource() - { - } - - public void setConfiguration(HikariConfig configuration) + /** + * Construct a HikariDataSource with the specified configuration. + * + * @param configuration a HikariConfig instance + */ + public HikariDataSource(HikariConfig configuration) { - this.pool = new HikariPool(configuration); + pool = new HikariPool(configuration); } /** {@inheritDoc} */ diff --git a/src/main/java/com/zaxxer/hikari/HikariPool.java b/src/main/java/com/zaxxer/hikari/HikariPool.java index 914a4782..e20bfd05 100644 --- a/src/main/java/com/zaxxer/hikari/HikariPool.java +++ b/src/main/java/com/zaxxer/hikari/HikariPool.java @@ -46,8 +46,8 @@ public class HikariPool private final AtomicInteger idleConnectionCount; private final DataSource dataSource; - private final int maxLifeTime; - private final int leakDetectionThreshold; + private final long maxLifeTime; + private final long leakDetectionThreshold; private final boolean jdbc4ConnectionTest; private final Timer houseKeepingTimer; @@ -84,10 +84,10 @@ public class HikariPool houseKeepingTimer = new Timer("Hikari Housekeeping Timer", true); - int idleTimeout = configuration.getIdleTimeout(); + long idleTimeout = configuration.getIdleTimeout(); if (idleTimeout > 0 || maxLifeTime > 0 || leakDetectionThreshold > 0) { - houseKeepingTimer.scheduleAtFixedRate(new HouseKeeper(), idleTimeout, idleTimeout); + houseKeepingTimer.scheduleAtFixedRate(new HouseKeeper(), TimeUnit.MINUTES.toMillis(1), TimeUnit.MINUTES.toMillis(1)); } System.setProperty("hikariProxyGeneratorType", configuration.getProxyFactoryType()); @@ -102,7 +102,7 @@ public class HikariPool { try { - int timeout = configuration.getConnectionTimeout(); + long timeout = configuration.getConnectionTimeout(); final long start = System.currentTimeMillis(); do { @@ -240,13 +240,13 @@ public class HikariPool } } - private boolean isConnectionAlive(Connection connection, int timeoutMs) + private boolean isConnectionAlive(Connection connection, long timeoutMs) { try { if (jdbc4ConnectionTest) { - return connection.isValid(timeoutMs * 1000); + return connection.isValid((int) timeoutMs * 1000); } Statement statement = connection.createStatement(); @@ -287,7 +287,7 @@ public class HikariPool houseKeepingTimer.purge(); final long now = System.currentTimeMillis(); - final int idleTimeout = configuration.getIdleTimeout(); + final long idleTimeout = configuration.getIdleTimeout(); final int idleCount = idleConnectionCount.get(); for (int i = 0; i < idleCount; i++) diff --git a/src/test/java/com/zaxxer/hikari/CreationTest.java b/src/test/java/com/zaxxer/hikari/CreationTest.java index 50f8c802..9f5d5a24 100644 --- a/src/test/java/com/zaxxer/hikari/CreationTest.java +++ b/src/test/java/com/zaxxer/hikari/CreationTest.java @@ -43,8 +43,7 @@ public class CreationTest config.setDataSourceClassName("com.zaxxer.hikari.mocks.MockDataSource"); config.setProxyFactoryType(System.getProperty("testProxy", "auto")); - HikariDataSource ds = new HikariDataSource(); - ds.setConfiguration(config); + HikariDataSource ds = new HikariDataSource(config); Assert.assertSame("Totals connections not as expected", 1, ds.pool.getTotalConnectionCount()); Assert.assertSame("Idle connections not as expected", 1, ds.pool.getIdleConnectionCount()); @@ -84,8 +83,7 @@ public class CreationTest config.setDataSourceClassName("com.zaxxer.hikari.mocks.MockDataSource"); config.setProxyFactoryType(System.getProperty("testProxy", "auto")); - HikariDataSource ds = new HikariDataSource(); - ds.setConfiguration(config); + HikariDataSource ds = new HikariDataSource(config); Assert.assertSame("Totals connections not as expected", 1, ds.pool.getTotalConnectionCount()); Assert.assertSame("Idle connections not as expected", 1, ds.pool.getIdleConnectionCount()); diff --git a/src/test/java/com/zaxxer/hikari/performance/Benchmarks.java b/src/test/java/com/zaxxer/hikari/performance/Benchmarks.java index 2b04b3c9..35350511 100644 --- a/src/test/java/com/zaxxer/hikari/performance/Benchmarks.java +++ b/src/test/java/com/zaxxer/hikari/performance/Benchmarks.java @@ -6,6 +6,7 @@ import java.sql.ResultSet; import java.util.Arrays; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.TimeUnit; import javax.sql.DataSource; @@ -14,9 +15,18 @@ import com.jolbox.bonecp.BoneCPDataSource; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; +/** + * This test requires the Javassist library to be present in the classpath. + * To reproduce our results, it should be run as follows: + * + * JVM parameters: -server -XX:+UseParallelGC -Xss256k -Dthreads=200 + * + * @author Brett Wooldridge + */ public class Benchmarks { private static final int THREADS = Integer.getInteger("threads", 100); + private static final int POOL_MAX = Integer.getInteger("poolMax", 100); private DataSource ds; @@ -43,11 +53,11 @@ public class Benchmarks System.out.println("\nMixedBench"); System.out.println(" Warming up JIT"); benchmarks.startMixedBench(); - System.out.println(" MixedBench Final Timing Runs"); - benchmarks.startMixedBench(); - benchmarks.startMixedBench(); - benchmarks.startMixedBench(); - benchmarks.startMixedBench(); +// System.out.println(" MixedBench Final Timing Runs"); +// benchmarks.startMixedBench(); +// benchmarks.startMixedBench(); +// benchmarks.startMixedBench(); +// benchmarks.startMixedBench(); System.out.println("\nBoneBench"); System.out.println(" Warming up JIT"); @@ -64,14 +74,14 @@ public class Benchmarks HikariConfig config = new HikariConfig(); config.setAcquireIncrement(5); config.setMinimumPoolSize(20); - config.setMaximumPoolSize(200); + config.setMaximumPoolSize(POOL_MAX); config.setConnectionTimeout(5000); + config.setIdleTimeout(TimeUnit.MINUTES.toMillis(30)); config.setJdbc4ConnectionTest(true); config.setDataSourceClassName("com.zaxxer.hikari.performance.StubDataSource"); config.setProxyFactoryType(System.getProperty("testProxy", "javassist")); - HikariDataSource ds = new HikariDataSource(); - ds.setConfiguration(config); + HikariDataSource ds = new HikariDataSource(config); return ds; } @@ -89,8 +99,9 @@ public class Benchmarks BoneCPConfig config = new BoneCPConfig(); config.setAcquireIncrement(5); config.setMinConnectionsPerPartition(20); - config.setMaxConnectionsPerPartition(200); + config.setMaxConnectionsPerPartition(POOL_MAX); config.setConnectionTimeoutInMs(5000); + config.setIdleMaxAgeInMinutes(30); config.setConnectionTestStatement("VALUES 1"); config.setCloseOpenStatements(true); config.setDisableConnectionTracking(true);