mirror of
https://github.com/moparisthebest/JdbcMapper
synced 2024-11-24 10:02:14 -05:00
QueryRunner re-factor
This commit is contained in:
parent
345a4120c8
commit
08e2c9354d
@ -13,52 +13,70 @@ import static com.moparisthebest.jdbc.TryClose.tryClose;
|
|||||||
*/
|
*/
|
||||||
public class QueryRunner<T extends JdbcMapper> {
|
public class QueryRunner<T extends JdbcMapper> {
|
||||||
|
|
||||||
private static final int defaultRetryCount = 10;
|
|
||||||
private static final DelayStrategy defaultDelayStrategy = exponentialBackoff(1000, 30000, 2000, 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<T> factory;
|
private final Factory<T> factory;
|
||||||
private final DelayStrategy delayStrategy;
|
private final DelayStrategy delayStrategy;
|
||||||
private final int retryCount;
|
private final int retryCount;
|
||||||
private final ExecutorService executorService;
|
private final ExecutorService executorService;
|
||||||
|
|
||||||
public QueryRunner(final Factory<T> factory, final DelayStrategy delayStrategy, final ExecutorService executorService, final int retryCount) {
|
private QueryRunner(final Factory<T> factory, final int retryCount, final DelayStrategy delayStrategy, final ExecutorService executorService) {
|
||||||
if (factory == null)
|
if (factory == null)
|
||||||
throw new NullPointerException("factory must be non-null");
|
throw new NullPointerException("factory must be non-null");
|
||||||
if (delayStrategy == null)
|
if (delayStrategy == null)
|
||||||
throw new NullPointerException("delayStrategy must be non-null");
|
throw new NullPointerException("delayStrategy must be non-null");
|
||||||
if (executorService == null)
|
if (executorService == null)
|
||||||
throw new NullPointerException("executorService must be non-null");
|
throw new NullPointerException("executorService must be non-null");
|
||||||
if (retryCount < 1)
|
if (retryCount < 0)
|
||||||
throw new IllegalArgumentException("retryCount must be > 0");
|
throw new IllegalArgumentException("retryCount must be >= 0");
|
||||||
this.factory = factory;
|
this.factory = factory;
|
||||||
this.delayStrategy = delayStrategy;
|
this.delayStrategy = delayStrategy;
|
||||||
this.retryCount = retryCount;
|
this.retryCount = retryCount;
|
||||||
this.executorService = Executors.newSingleThreadExecutor();
|
this.executorService = executorService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryRunner(final Factory<T> factory) {
|
public static <T extends JdbcMapper> QueryRunner<T> noRetry(final Factory<T> factory, final ExecutorService executorService) {
|
||||||
this(factory, defaultDelayStrategy, defaultExecutorService, defaultRetryCount);
|
return new QueryRunner<T>(factory, 0, defaultDelayStrategy, executorService);
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryRunner(final Factory<T> factory, final DelayStrategy delayStrategy) {
|
public static <T extends JdbcMapper> QueryRunner<T> noRetry(final Factory<T> factory) {
|
||||||
this(factory, delayStrategy, defaultExecutorService, defaultRetryCount);
|
return noRetry(factory, defaultExecutorService);
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryRunner(final Factory<T> factory, final int retryCount) {
|
public static <T extends JdbcMapper> QueryRunner<T> withRetry(final Factory<T> factory, final int retryCount, final DelayStrategy delayStrategy, final ExecutorService executorService) {
|
||||||
this(factory, defaultDelayStrategy, defaultExecutorService, retryCount);
|
return new QueryRunner<T>(factory, retryCount, delayStrategy, executorService);
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryRunner(final Factory<T> factory, final ExecutorService executorService) {
|
public static <T extends JdbcMapper> QueryRunner<T> withRetry(final Factory<T> factory, final int retryCount, final DelayStrategy delayStrategy) {
|
||||||
this(factory, defaultDelayStrategy, executorService, defaultRetryCount);
|
return withRetry(factory, retryCount, delayStrategy, defaultExecutorService);
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryRunner(final Factory<T> factory, final DelayStrategy delayStrategy, final ExecutorService executorService) {
|
public static <T extends JdbcMapper> QueryRunner<T> withRetry(final Factory<T> factory, final int retryCount) {
|
||||||
this(factory, delayStrategy, executorService, defaultRetryCount);
|
return withRetry(factory, retryCount, defaultDelayStrategy, defaultExecutorService);
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryRunner(final Factory<T> factory, final ExecutorService executorService, final int retryCount) {
|
public static <T extends JdbcMapper> QueryRunner<T> withRetry(final Factory<T> factory, final int retryCount, final ExecutorService executorService) {
|
||||||
this(factory, defaultDelayStrategy, executorService, retryCount);
|
return withRetry(factory, retryCount, defaultDelayStrategy, executorService);
|
||||||
|
}
|
||||||
|
|
||||||
|
public QueryRunner<T> withRetryCount(final int retryCount) {
|
||||||
|
return new QueryRunner<T>(factory, retryCount, delayStrategy, executorService);
|
||||||
|
}
|
||||||
|
|
||||||
|
public QueryRunner<T> withDelayStrategy(final DelayStrategy delayStrategy) {
|
||||||
|
return new QueryRunner<T>(factory, retryCount, delayStrategy, executorService);
|
||||||
|
}
|
||||||
|
|
||||||
|
public QueryRunner<T> withExecutorService(final ExecutorService executorService) {
|
||||||
|
return new QueryRunner<T>(factory, retryCount, delayStrategy, executorService);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends JdbcMapper> QueryRunner<T> withFactory(final Factory<T> factory) {
|
||||||
|
return new QueryRunner<T>(factory, retryCount, delayStrategy, executorService);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <E> E run(final Runner<T, E> query) throws SQLException {
|
public <E> E run(final Runner<T, E> query) throws SQLException {
|
||||||
@ -109,21 +127,20 @@ public class QueryRunner<T extends JdbcMapper> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <E> E runRetry(final Runner<T, E> query) throws SQLException {
|
public <E> E runRetry(final Runner<T, E> query) throws SQLException {
|
||||||
SQLException lastException = null;
|
|
||||||
int x = 0;
|
int x = 0;
|
||||||
do {
|
while(true) {
|
||||||
try {
|
try {
|
||||||
return runInTransaction(query);
|
return runInTransaction(query);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
lastException = e;
|
if(x == retryCount)
|
||||||
|
throw e;
|
||||||
try {
|
try {
|
||||||
Thread.sleep(delayStrategy.getDelay(++x));
|
Thread.sleep(delayStrategy.getDelay(++x));
|
||||||
} catch (InterruptedException e2) {
|
} catch (InterruptedException e2) {
|
||||||
Thread.interrupted();
|
Thread.interrupted();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (x <= retryCount);
|
}
|
||||||
throw lastException;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <E> Future<E> runRetryFuture(final Runner<T, E> query) {
|
public <E> Future<E> runRetryFuture(final Runner<T, E> query) {
|
||||||
@ -170,6 +187,9 @@ public class QueryRunner<T extends JdbcMapper> {
|
|||||||
return QueryRunner.withJitter(this, maxJitterMs);
|
return QueryRunner.withJitter(this, maxJitterMs);
|
||||||
}
|
}
|
||||||
//IFJAVA8_END
|
//IFJAVA8_END
|
||||||
|
/*IFJAVA6_START
|
||||||
|
DelayStrategy withJitter(final int maxJitterMs);
|
||||||
|
IFJAVA6_END*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DelayStrategy exponentialBackoff() {
|
public static DelayStrategy exponentialBackoff() {
|
||||||
@ -186,7 +206,7 @@ public class QueryRunner<T extends JdbcMapper> {
|
|||||||
public static DelayStrategy exponentialBackoff(final long minBackoff, final long maxBackoff, final long slotTime, final long maxContentionPeriods) {
|
public static DelayStrategy exponentialBackoff(final long minBackoff, final long maxBackoff, final long slotTime, final long maxContentionPeriods) {
|
||||||
return
|
return
|
||||||
/*IFJAVA6_START
|
/*IFJAVA6_START
|
||||||
new DelayStrategy() {
|
new AbstractDelayStrategy() {
|
||||||
@Override
|
@Override
|
||||||
public long getDelay(final int attempt) {
|
public long getDelay(final int attempt) {
|
||||||
return
|
return
|
||||||
@ -204,7 +224,7 @@ public class QueryRunner<T extends JdbcMapper> {
|
|||||||
public static DelayStrategy fixedDelay(final long delay) {
|
public static DelayStrategy fixedDelay(final long delay) {
|
||||||
return
|
return
|
||||||
/*IFJAVA6_START
|
/*IFJAVA6_START
|
||||||
new DelayStrategy() {
|
new AbstractDelayStrategy() {
|
||||||
@Override
|
@Override
|
||||||
public long getDelay(final int attempt) {
|
public long getDelay(final int attempt) {
|
||||||
return
|
return
|
||||||
@ -222,7 +242,7 @@ public class QueryRunner<T extends JdbcMapper> {
|
|||||||
public static DelayStrategy incrementalDelay(final long initialInterval, final long incrementalInterval) {
|
public static DelayStrategy incrementalDelay(final long initialInterval, final long incrementalInterval) {
|
||||||
return
|
return
|
||||||
/*IFJAVA6_START
|
/*IFJAVA6_START
|
||||||
new DelayStrategy() {
|
new AbstractDelayStrategy() {
|
||||||
@Override
|
@Override
|
||||||
public long getDelay(final int attempt) {
|
public long getDelay(final int attempt) {
|
||||||
return
|
return
|
||||||
@ -237,10 +257,10 @@ public class QueryRunner<T extends JdbcMapper> {
|
|||||||
IFJAVA6_END*/
|
IFJAVA6_END*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DelayStrategy withJitter(final DelayStrategy toWrap, final int maxJitterMs) {
|
private static DelayStrategy withJitter(final DelayStrategy toWrap, final int maxJitterMs) {
|
||||||
return
|
return
|
||||||
/*IFJAVA6_START
|
/*IFJAVA6_START
|
||||||
new DelayStrategy() {
|
new AbstractDelayStrategy() {
|
||||||
@Override
|
@Override
|
||||||
public long getDelay(final int attempt) {
|
public long getDelay(final int attempt) {
|
||||||
return
|
return
|
||||||
@ -269,6 +289,11 @@ public class QueryRunner<T extends JdbcMapper> {
|
|||||||
return randomThreadLocal.get();
|
return randomThreadLocal.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private static abstract class AbstractDelayStrategy implements DelayStrategy {
|
||||||
|
public DelayStrategy withJitter(final int maxJitterMs) {
|
||||||
|
return QueryRunner.withJitter(this, maxJitterMs);
|
||||||
|
}
|
||||||
|
}
|
||||||
IFJAVA6_END*/
|
IFJAVA6_END*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,14 +14,15 @@ import static com.moparisthebest.jdbc.QueryMapperTest.*;
|
|||||||
* Created by mopar on 7/1/17.
|
* Created by mopar on 7/1/17.
|
||||||
*/
|
*/
|
||||||
public class QueryRunnerTest {
|
public class QueryRunnerTest {
|
||||||
public static final QueryRunner<QueryMapper> qr = new QueryRunner<QueryMapper>(new JdbcMapperFactory<QueryMapper>(QueryMapper.class, new Factory<Connection>() {
|
public static final QueryRunner<QueryMapper> qr = QueryRunner.withRetry(new JdbcMapperFactory<QueryMapper>(QueryMapper.class, new Factory<Connection>() {
|
||||||
@Override
|
@Override
|
||||||
public Connection create() throws SQLException {
|
public Connection create() throws SQLException {
|
||||||
return QueryMapperTest.getConnection();
|
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 {
|
private void testPerson(final Person expected, final String query) throws Throwable {
|
||||||
|
//final QueryRunner<ListQueryMapper> lqr = qr.withFactory(() -> new ListQueryMapper(QueryMapperTest::getConnection));
|
||||||
final Person actual =
|
final Person actual =
|
||||||
//qr.run(
|
//qr.run(
|
||||||
//qr.runRetry(
|
//qr.runRetry(
|
||||||
|
Loading…
Reference in New Issue
Block a user