Skip to content

Commit 01ca4b1

Browse files
committed
Add maxAcquireMicros and meanAcquireNanos for pool status metrics
1 parent a6347bc commit 01ca4b1

File tree

4 files changed

+56
-3
lines changed

4 files changed

+56
-3
lines changed

ebean-datasource-api/src/main/java/io/ebean/datasource/PoolStatus.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,16 @@ default int getWaitCount() {
108108
default int getHitCount() {
109109
return hitCount();
110110
}
111+
112+
/**
113+
* Return the max acquire time in micros.
114+
*/
115+
long maxAcquireMicros();
116+
117+
/**
118+
* Return the mean acquire time in nanos.
119+
* <p>
120+
* This should be in the ballpark of 150 nanos.
121+
*/
122+
long meanAcquireNanos();
111123
}

ebean-datasource/src/main/java/io/ebean/datasource/pool/ConnectionPool.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -803,8 +803,10 @@ static final class Status implements PoolStatus {
803803
private final int highWaterMark;
804804
private final int waitCount;
805805
private final int hitCount;
806+
private final long maxAcquireMicros;
807+
private final long meanAcquireNanos;
806808

807-
Status(int minSize, int maxSize, int free, int busy, int waiting, int highWaterMark, int waitCount, int hitCount) {
809+
Status(int minSize, int maxSize, int free, int busy, int waiting, int highWaterMark, int waitCount, int hitCount, long totalAcquireNanos, long maxAcquireNanos) {
808810
this.minSize = minSize;
809811
this.maxSize = maxSize;
810812
this.free = free;
@@ -813,12 +815,15 @@ static final class Status implements PoolStatus {
813815
this.highWaterMark = highWaterMark;
814816
this.waitCount = waitCount;
815817
this.hitCount = hitCount;
818+
this.meanAcquireNanos = hitCount == 0 ? 0 : totalAcquireNanos / hitCount;
819+
this.maxAcquireMicros = maxAcquireNanos / 1000;
816820
}
817821

818822
@Override
819823
public String toString() {
820824
return "min[" + minSize + "] max[" + maxSize + "] free[" + free + "] busy[" + busy + "] waiting[" + waiting
821-
+ "] highWaterMark[" + highWaterMark + "] waitCount[" + waitCount + "] hitCount[" + hitCount + "]";
825+
+ "] highWaterMark[" + highWaterMark + "] waitCount[" + waitCount + "] hitCount[" + hitCount
826+
+ "] meanAcquireNanos[" + meanAcquireNanos + "] maxAcquireMicros[" + maxAcquireMicros + "]";
822827
}
823828

824829
/**
@@ -890,6 +895,15 @@ public int hitCount() {
890895
return hitCount;
891896
}
892897

898+
@Override
899+
public long maxAcquireMicros() {
900+
return maxAcquireMicros;
901+
}
902+
903+
@Override
904+
public long meanAcquireNanos() {
905+
return meanAcquireNanos;
906+
}
893907
}
894908

895909
}

ebean-datasource/src/main/java/io/ebean/datasource/pool/PooledConnectionQueue.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ final class PooledConnectionQueue {
5252
* Number of times a connection was got from this queue.
5353
*/
5454
private int hitCount;
55+
private long totalAcquireNanos;
56+
private long maxAcquireNanos;
57+
5558
/**
5659
* The high water mark for the queue size.
5760
*/
@@ -81,7 +84,8 @@ final class PooledConnectionQueue {
8184
}
8285

8386
private PoolStatus createStatus() {
84-
return new Status(minSize, maxSize, freeList.size(), busyList.size(), waitingThreads, highWaterMark, waitCount, hitCount);
87+
return new Status(minSize, maxSize, freeList.size(), busyList.size(), waitingThreads, highWaterMark,
88+
waitCount, hitCount, totalAcquireNanos, maxAcquireNanos);
8589
}
8690

8791
@Override
@@ -102,6 +106,8 @@ PoolStatus status(boolean reset) {
102106
highWaterMark = busyList.size();
103107
hitCount = 0;
104108
waitCount = 0;
109+
maxAcquireNanos = 0;
110+
totalAcquireNanos = 0;
105111
}
106112
return s;
107113
} finally {
@@ -237,6 +243,7 @@ private int registerBusyConnection(PooledConnection connection) {
237243
}
238244

239245
private PooledConnection _obtainConnection() throws InterruptedException, SQLException {
246+
var start = System.nanoTime();
240247
lock.lockInterruptibly();
241248
try {
242249
if (doingShutdown) {
@@ -272,6 +279,9 @@ private PooledConnection _obtainConnection() throws InterruptedException, SQLExc
272279
waitingThreads--;
273280
}
274281
} finally {
282+
final var elapsed = System.nanoTime() - start;
283+
totalAcquireNanos += elapsed;
284+
maxAcquireNanos = Math.max(maxAcquireNanos, elapsed);
275285
lock.unlock();
276286
}
277287
}

ebean-datasource/src/test/java/io/ebean/datasource/pool/ConnectionPoolTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.ebean.datasource.pool;
22

33
import io.ebean.datasource.DataSourceConfig;
4+
import io.ebean.datasource.PoolStatus;
45
import org.junit.jupiter.api.AfterEach;
56
import org.junit.jupiter.api.Test;
67

@@ -75,6 +76,22 @@ void getConnection_explicitUserPassword() throws SQLException {
7576

7677
Connection another = pool.getConnection("testing", "123");
7778
another.close();
79+
80+
for (int i = 0; i < 10_000; i++) {
81+
Connection another2 = pool.getConnection();
82+
another2.close();
83+
}
84+
PoolStatus status0 = pool.status(true);
85+
86+
for (int i = 0; i < 10_000; i++) {
87+
Connection another2 = pool.getConnection();
88+
another2.close();
89+
}
90+
PoolStatus status = pool.status(false);
91+
92+
assertThat(status.hitCount()).isEqualTo(10_000);
93+
assertThat(status.meanAcquireNanos()).isBetween(0L, 300L);
94+
assertThat(status.maxAcquireMicros()).isBetween(0L, 100L);
7895
}
7996

8097
@Test

0 commit comments

Comments
 (0)