Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,11 @@ void closeBusyConnections(long leakTimeMinutes) {
Log.debug("Closing busy connections using leakTimeMinutes {0}", leakTimeMinutes);
for (int i = 0; i < slots.length; i++) {
if (slots[i] != null) {
//tmp.add(slots[i]);
PooledConnection pc = slots[i];
//noinspection StatementWithEmptyBody
if (pc.lastUsedTime() > olderThanTime) {
// PooledConnection has been used recently or
// expected to be longRunning so not closing...
if (pc.startUseTime() > olderThanTime) {
// PooledConnection was checked out recently so it is in active
// use (not a leak) - leave it to be closed when returned to the pool
} else {
slots[i] = null;
--size;
Expand All @@ -107,7 +106,6 @@ void closeBusyConnections(long leakTimeMinutes) {
private void closeBusyConnection(PooledConnection pc) {
try {
Log.warn("DataSource closing busy connection? {0}", pc.fullDescription());
System.out.println("CLOSING busy connection: " + pc.fullDescription());
pc.closeConnectionFully(false);
} catch (Exception ex) {
Log.error("Error when closing potentially leaked connection " + pc.description(), ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,12 +232,12 @@ String fullDescription() {
* @param logErrors if false then don't log errors when closing
*/
void closeConnectionFully(boolean logErrors) {
if (Log.isLoggable(System.Logger.Level.TRACE)) {
Log.trace("Closing Connection[{0}] reason[{1}], pstmtStats: {2}", name, closeReason, pstmtCache.description());
}
if (pool == null) {
return; // this can happen in tests only.
}
if (Log.isLoggable(System.Logger.Level.TRACE)) {
Log.trace("Closing Connection[{0}] reason[{1}], pstmtStats: {2}", name, closeReason, pstmtCache.description());
}
pool.pstmtCacheMetrics(pstmtCache);
pool.closeConnectionFullyAsync(this, logErrors);
}
Expand Down Expand Up @@ -585,7 +585,7 @@ boolean shouldTrim(long usedSince, long createdSince) {
* <p>
* Used to detect busy connections that could be leaks.
*/
private long startUseTime() {
long startUseTime() {
return startUseTime;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class BusyConnectionBufferTest {

Expand Down Expand Up @@ -96,4 +98,29 @@ public void test_rotate() {

}

@Test
public void closeBusyConnections_onlyClosesLeaks_notActiveConnections() {
BusyConnectionBuffer b = new BusyConnectionBuffer(4, 4);

// a connection that was checked out long ago and never returned (a leak)
PooledConnection leaked = new PooledConnection("leaked");
// a connection that sat idle in the free list for a while then was just
// checked out - it is in active use, not a leak (startUseTime is recent)
PooledConnection active = new PooledConnection("active");
active.resetForUse();

b.add(leaked);
b.add(active);
assertEquals(2, b.size());

// close connections considered leaked using a 1 minute leak time
b.closeBusyConnections(1);

// the leaked connection is removed, the active connection is retained
assertEquals(1, b.size());
// active is still held in its slot, leaked is gone
assertTrue(b.remove(active));
assertFalse(b.remove(leaked));
}

}
Loading