pull/42/head
Brett Wooldridge 11 years ago
parent 6149affd88
commit 5765ed2116

@ -23,26 +23,75 @@ import java.util.Timer;
import com.zaxxer.hikari.util.ConcurrentBag.IBagManagable;
/**
* The interface used by the Connection proxy and through which all interaction
* by other classes flow.
*
* @author Brett Wooldridge
*/
public interface IHikariConnectionProxy extends Connection, IBagManagable
{
void unclose();
void realClose() throws SQLException;
void untrackStatement(Object statement);
/**
* Catpure the stack and start leak detection.
*
* @param leakThreshold the number of milliseconds before a leak is reported
* @param houseKeepingTimer the timer to run the leak detection task with
*/
void captureStack(long leakThreshold, Timer houseKeepingTimer);
/**
* Check if the provided SQLException contains a SQLSTATE that indicates
* a disconnection from the server.
*
* @param sqle the SQLException to check
*/
void checkException(SQLException sqle);
boolean isBrokenConnection();
/**
* Get the creation timestamp of the connection.
*
* @return the creation timestamp
*/
long getCreationTime();
/**
* Get the last access timestamp of the connection.
*
* @return the last access timestamp
*/
long getLastAccess();
/**
* Return the broken state of the connection. If checkException() detected
* a broken connection, this method will return true, otherwise false.
*
* @return the broken state of the connection
*/
boolean isBrokenConnection();
/**
* Actually close the underlying delegate Connection.
*
* @throws SQLException rethrown from the underlying delegate Connection
*/
void realClose() throws SQLException;
/**
* Reset the delegate Connection back to pristine state.
*
* @throws SQLException thrown if there is an error resetting any of the state
*/
void resetConnectionState() throws SQLException;
/* Leak Detection API */
void captureStack(long leakThreshold, Timer houseKeepingTimer);
/**
* Make the Connection available for use again by marking it as not closed.
*/
void unclose();
/**
* Called by Statement and its subclasses when they are closed to remove them
* from the tracking list.
*
* @param statement the Statement to remove from tracking
*/
void untrackStatement(Object statement);
}

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013 Brett Wooldridge
* Copyright (C) 2013, 2014 Brett Wooldridge
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -36,6 +36,10 @@ import org.slf4j.LoggerFactory;
import com.zaxxer.hikari.util.ClassLoaderUtils;
/**
* This class generates the proxy objects for {@link Connection}, {@link Statement},
* {@link PreparedStatement}, and {@link CallableStatement}. Additionally it injects
* method bodies into the {@link ProxyFactory} class methods that can instantiate
* instances of the generated proxies.
*
* @author Brett Wooldridge
*/
@ -63,9 +67,13 @@ public final class JavassistProxyFactory
}
}
/**
* Simply invoking this method causes the initialization of this class. All work
* by this class is performed in static initialization.
*/
public static void initialize()
{
// simply invoking this method causes the initialization of this class.
// no-op
}
private JavassistProxyFactory()

@ -23,7 +23,7 @@ import org.slf4j.LoggerFactory;
/**
* @author Brett Wooldridge
*/
public class LeakTask extends TimerTask
class LeakTask extends TimerTask
{
private final long leakTime;
private StackTraceElement[] stackTrace;

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013 Brett Wooldridge
* Copyright (C) 2013, 2014 Brett Wooldridge
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -24,13 +24,30 @@ import java.sql.Statement;
import com.zaxxer.hikari.HikariPool;
/**
* Injected proxy factory class.
* A factory class that produces proxies around instances of the standard
* JDBC interfaces.
*
* @author Brett Wooldridge
*/
public final class ProxyFactory
{
public static IHikariConnectionProxy getProxyConnection(HikariPool pool, Connection connection, int defaultIsolationLevel, boolean defaultAutoCommit, String defaultCatalog)
private ProxyFactory()
{
// unconstrucable
}
/**
* Create a proxy for the specified {@link Connection} instance.
*
* @param pool the {@link HikariPool} that will own this proxy
* @param connection the {@link Connection} that will be wrapped by this proxy
* @param defaultIsolationLevel the default transaction isolation level of the underlying {@link Connection}
* @param defaultAutoCommit the default auto-commit state of the underlying {@link Connection}
* @param defaultIReadOnly the default readOnly state of the underlying {@link Connection}
* @param defaultCatalog the default catalog of the underlying {@link Connection}
* @return a proxy that wraps the specified {@link Connection}
*/
public static IHikariConnectionProxy getProxyConnection(HikariPool pool, Connection connection, int defaultIsolationLevel, boolean defaultAutoCommit, boolean defaultIReadOnly, String defaultCatalog)
{
// Body is injected by JavassistProxyFactory
return null;

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013 Brett Wooldridge
* Copyright (C) 2013, 2014 Brett Wooldridge
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -28,12 +28,12 @@ import java.util.concurrent.locks.AbstractQueuedLongSynchronizer;
* to LinkedBlockingQueue and LinkedTransferQueue for the purposes of a
* connection pool. It uses ThreadLocal storage when possible to avoid
* locks, but resorts to scanning a common collection if there are no
* available connections in the ThreadLocal list. Idle connections in
* ThreadLocal lists can be "stolen" when the poll()ing thread has none
* available items in the ThreadLocal list. Not-in-use items in the
* ThreadLocal lists can be "stolen" when the borrowing thread has none
* of its own. It is a "lock-less" implementation using a specialized
* AbstractQueuedLongSynchronizer to manage cross-thread signaling.
*
* Note that objects that are "borrowed" from the bag are not actually
* Note that items that are "borrowed" from the bag are not actually
* removed from any collection, so garbage collection will not occur
* even if the reference is abandoned. Thus care must be taken to
* "requite" borrowed objects otherwise a memory leak will result. Only
@ -64,6 +64,12 @@ public class ConcurrentBag<T extends com.zaxxer.hikari.util.ConcurrentBag.IBagMa
boolean compareAndSetState(int expectedState, int newState);
}
/**
* This interface is implemented by a listener to the bag. The listener
* will be informed of when the bag has become empty. The usual course
* of action by the listener in this case is to attempt to add an item
* to the bag.
*/
public interface IBagStateListener
{
void bagIsEmpty();
@ -180,7 +186,7 @@ public class ConcurrentBag<T extends com.zaxxer.hikari.util.ConcurrentBag.IBagMa
/**
* Remove a value from the bag. This method should only be called
* with objects obtained by borrow() or reserve().
* with objects obtained by {@link #borrow(long, TimeUnit)} or {@link #reserve(IBagManagable)}.
* @param value the value to remove
* @throws IllegalStateException if an attempt is made to remove an object
* from the bag that was not borrowed or reserved first
@ -200,7 +206,8 @@ public class ConcurrentBag<T extends com.zaxxer.hikari.util.ConcurrentBag.IBagMa
/**
* This method provides a "snaphot" in time of the IBagManagable
* items in the bag in the specified state. It does not "lock"
* or reserve items in any way.
* or reserve items in any way. Call {@link #reserve(IBagManagable)}
* on items in list before performing any action on them.
*
* @param state one of STATE_NOT_IN_USE or STATE_IN_USE
* @return a possibly empty list of objects having the state specified
@ -221,11 +228,29 @@ public class ConcurrentBag<T extends com.zaxxer.hikari.util.ConcurrentBag.IBagMa
return list;
}
/**
* The method is used to make an item in the bag "unavailable" for
* borrowing. It is primarily used when wanting to operate on items
* returned by the {@link #values(int)} method. Items that are
* reserved can be removed from the bag via {@link #remove(IBagManagable)}
* without the need to unreserve them. Items that are not removed
* from the bag can be make available for borrowing again by calling
* the {@link #unreserve(IBagManagable) method.
*
* @param value the item to reserve
* @return true if the item was able to be reserved, false otherwise
*/
public boolean reserve(T value)
{
return value.compareAndSetState(STATE_NOT_IN_USE, STATE_RESERVED);
}
/**
* This method is used to make an item reserved via {@link #reserve(IBagManagable)}
* available again for borrowing.
*
* @param value the item to unreserve
*/
public void unreserve(T value)
{
final long checkInTime = System.nanoTime();
@ -237,11 +262,23 @@ public class ConcurrentBag<T extends com.zaxxer.hikari.util.ConcurrentBag.IBagMa
synchronizer.releaseShared(checkInTime);
}
/**
* Add a listener to the bag. There can only be one. If this method is
* called a second time, the original listener will be evicted.
*
* @param listener a listener to the bag
*/
public void addBagStateListener(IBagStateListener listener)
{
this.listener = listener;
}
/**
* Get the number of threads pending (waiting) for an item from the
* bag to become available.
*
* @return the number of threads waiting for items from the bag
*/
public int getPendingQueue()
{
return synchronizer.getQueueLength();

@ -1,5 +1,5 @@
/*
* Copyright (C) 2013 Brett Wooldridge
* Copyright (C) 2013, 2014 Brett Wooldridge
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -31,7 +31,7 @@ public final class FastStatementList
private int size;
/**
* Construct a FastList with a default size of 16.
* Construct a FastList with a default size of 32.
*/
public FastStatementList()
{

Loading…
Cancel
Save