From 08e2c9354d72f060ba530ad6982ee9288741ae91 Mon Sep 17 00:00:00 2001 From: moparisthebest Date: Mon, 3 Jul 2017 01:57:52 -0400 Subject: [PATCH] QueryRunner re-factor --- .../com/moparisthebest/jdbc/QueryRunner.java | 81 ++++++++++++------- .../moparisthebest/jdbc/QueryRunnerTest.java | 5 +- 2 files changed, 56 insertions(+), 30 deletions(-) diff --git a/common/src/main/java/com/moparisthebest/jdbc/QueryRunner.java b/common/src/main/java/com/moparisthebest/jdbc/QueryRunner.java index 2170360..e13ddee 100644 --- a/common/src/main/java/com/moparisthebest/jdbc/QueryRunner.java +++ b/common/src/main/java/com/moparisthebest/jdbc/QueryRunner.java @@ -13,52 +13,70 @@ import static com.moparisthebest.jdbc.TryClose.tryClose; */ public class QueryRunner { - private static final int defaultRetryCount = 10; private static final DelayStrategy defaultDelayStrategy = exponentialBackoff(1000, 30000, 2000, 10); - private static final ExecutorService defaultExecutorService = Executors.newCachedThreadPool(); // todo: good or bad default? + private static final ExecutorService defaultExecutorService = + Executors.newCachedThreadPool() + //ForkJoinPool.commonPool() + ; // todo: good or bad default? private final Factory factory; private final DelayStrategy delayStrategy; private final int retryCount; private final ExecutorService executorService; - public QueryRunner(final Factory factory, final DelayStrategy delayStrategy, final ExecutorService executorService, final int retryCount) { + private QueryRunner(final Factory factory, final int retryCount, final DelayStrategy delayStrategy, final ExecutorService executorService) { if (factory == null) throw new NullPointerException("factory must be non-null"); if (delayStrategy == null) throw new NullPointerException("delayStrategy must be non-null"); if (executorService == null) throw new NullPointerException("executorService must be non-null"); - if (retryCount < 1) - throw new IllegalArgumentException("retryCount must be > 0"); + if (retryCount < 0) + throw new IllegalArgumentException("retryCount must be >= 0"); this.factory = factory; this.delayStrategy = delayStrategy; this.retryCount = retryCount; - this.executorService = Executors.newSingleThreadExecutor(); + this.executorService = executorService; } - public QueryRunner(final Factory factory) { - this(factory, defaultDelayStrategy, defaultExecutorService, defaultRetryCount); + public static QueryRunner noRetry(final Factory factory, final ExecutorService executorService) { + return new QueryRunner(factory, 0, defaultDelayStrategy, executorService); } - public QueryRunner(final Factory factory, final DelayStrategy delayStrategy) { - this(factory, delayStrategy, defaultExecutorService, defaultRetryCount); + public static QueryRunner noRetry(final Factory factory) { + return noRetry(factory, defaultExecutorService); } - public QueryRunner(final Factory factory, final int retryCount) { - this(factory, defaultDelayStrategy, defaultExecutorService, retryCount); + public static QueryRunner withRetry(final Factory factory, final int retryCount, final DelayStrategy delayStrategy, final ExecutorService executorService) { + return new QueryRunner(factory, retryCount, delayStrategy, executorService); } - public QueryRunner(final Factory factory, final ExecutorService executorService) { - this(factory, defaultDelayStrategy, executorService, defaultRetryCount); + public static QueryRunner withRetry(final Factory factory, final int retryCount, final DelayStrategy delayStrategy) { + return withRetry(factory, retryCount, delayStrategy, defaultExecutorService); } - public QueryRunner(final Factory factory, final DelayStrategy delayStrategy, final ExecutorService executorService) { - this(factory, delayStrategy, executorService, defaultRetryCount); + public static QueryRunner withRetry(final Factory factory, final int retryCount) { + return withRetry(factory, retryCount, defaultDelayStrategy, defaultExecutorService); } - public QueryRunner(final Factory factory, final ExecutorService executorService, final int retryCount) { - this(factory, defaultDelayStrategy, executorService, retryCount); + public static QueryRunner withRetry(final Factory factory, final int retryCount, final ExecutorService executorService) { + return withRetry(factory, retryCount, defaultDelayStrategy, executorService); + } + + public QueryRunner withRetryCount(final int retryCount) { + return new QueryRunner(factory, retryCount, delayStrategy, executorService); + } + + public QueryRunner withDelayStrategy(final DelayStrategy delayStrategy) { + return new QueryRunner(factory, retryCount, delayStrategy, executorService); + } + + public QueryRunner withExecutorService(final ExecutorService executorService) { + return new QueryRunner(factory, retryCount, delayStrategy, executorService); + } + + public QueryRunner withFactory(final Factory factory) { + return new QueryRunner(factory, retryCount, delayStrategy, executorService); } public E run(final Runner query) throws SQLException { @@ -109,21 +127,20 @@ public class QueryRunner { } public E runRetry(final Runner query) throws SQLException { - SQLException lastException = null; int x = 0; - do { + while(true) { try { return runInTransaction(query); } catch (SQLException e) { - lastException = e; + if(x == retryCount) + throw e; try { Thread.sleep(delayStrategy.getDelay(++x)); } catch (InterruptedException e2) { Thread.interrupted(); } } - } while (x <= retryCount); - throw lastException; + } } public Future runRetryFuture(final Runner query) { @@ -170,6 +187,9 @@ public class QueryRunner { return QueryRunner.withJitter(this, maxJitterMs); } //IFJAVA8_END + /*IFJAVA6_START + DelayStrategy withJitter(final int maxJitterMs); + IFJAVA6_END*/ } public static DelayStrategy exponentialBackoff() { @@ -186,7 +206,7 @@ public class QueryRunner { public static DelayStrategy exponentialBackoff(final long minBackoff, final long maxBackoff, final long slotTime, final long maxContentionPeriods) { return /*IFJAVA6_START - new DelayStrategy() { + new AbstractDelayStrategy() { @Override public long getDelay(final int attempt) { return @@ -204,7 +224,7 @@ public class QueryRunner { public static DelayStrategy fixedDelay(final long delay) { return /*IFJAVA6_START - new DelayStrategy() { + new AbstractDelayStrategy() { @Override public long getDelay(final int attempt) { return @@ -222,7 +242,7 @@ public class QueryRunner { public static DelayStrategy incrementalDelay(final long initialInterval, final long incrementalInterval) { return /*IFJAVA6_START - new DelayStrategy() { + new AbstractDelayStrategy() { @Override public long getDelay(final int attempt) { return @@ -237,10 +257,10 @@ public class QueryRunner { IFJAVA6_END*/ } - public static DelayStrategy withJitter(final DelayStrategy toWrap, final int maxJitterMs) { + private static DelayStrategy withJitter(final DelayStrategy toWrap, final int maxJitterMs) { return /*IFJAVA6_START - new DelayStrategy() { + new AbstractDelayStrategy() { @Override public long getDelay(final int attempt) { return @@ -269,6 +289,11 @@ public class QueryRunner { return randomThreadLocal.get(); } } + private static abstract class AbstractDelayStrategy implements DelayStrategy { + public DelayStrategy withJitter(final int maxJitterMs) { + return QueryRunner.withJitter(this, maxJitterMs); + } + } IFJAVA6_END*/ } diff --git a/querymapper/src/test/java/com/moparisthebest/jdbc/QueryRunnerTest.java b/querymapper/src/test/java/com/moparisthebest/jdbc/QueryRunnerTest.java index 6f173f0..799cccc 100644 --- a/querymapper/src/test/java/com/moparisthebest/jdbc/QueryRunnerTest.java +++ b/querymapper/src/test/java/com/moparisthebest/jdbc/QueryRunnerTest.java @@ -14,14 +14,15 @@ import static com.moparisthebest.jdbc.QueryMapperTest.*; * Created by mopar on 7/1/17. */ public class QueryRunnerTest { - public static final QueryRunner qr = new QueryRunner(new JdbcMapperFactory(QueryMapper.class, new Factory() { + public static final QueryRunner qr = QueryRunner.withRetry(new JdbcMapperFactory(QueryMapper.class, new Factory() { @Override public Connection create() throws SQLException { return QueryMapperTest.getConnection(); } - }), QueryRunner.withJitter(QueryRunner.fixedDelay(5), 5)); + }), 10, QueryRunner.fixedDelay(5).withJitter(5)); private void testPerson(final Person expected, final String query) throws Throwable { + //final QueryRunner lqr = qr.withFactory(() -> new ListQueryMapper(QueryMapperTest::getConnection)); final Person actual = //qr.run( //qr.runRetry(