Skip to content

Commit fc1295b

Browse files
authored
Merge pull request #132 from ebean-orm/feature/poolStatus-totalWaitMicros
Add totalAcquireMicros() and totalWaitMicros() to PoolStatus
2 parents 2f3083b + 1f52231 commit fc1295b

File tree

6 files changed

+57
-54
lines changed

6 files changed

+57
-54
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ static DataSourceBuilder builder() {
8484
/**
8585
* Shutdown the pool.
8686
* <p>
87+
* This will close all the free connections, and then go into a wait loop,
88+
* waiting for the busy connections to be freed.
89+
* <p>
8790
* This is functionally the same as {@link #offline()} but generally we expect to only
8891
* shut down the pool once whereas we can expect to make many calls to offline() and
8992
* online().

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,14 @@ public interface PoolStatus {
3131
int waiting();
3232

3333
/**
34-
* Return the busy connection high water mark.
34+
* Return the busy connection highwater mark.
3535
*/
3636
int highWaterMark();
3737

3838
/**
3939
* Return the number of times threads had to wait for connections.
40+
* <p>
41+
* This occurs when the pool is full and threads are waiting for a connection.
4042
*/
4143
int waitCount();
4244

@@ -45,6 +47,18 @@ public interface PoolStatus {
4547
*/
4648
int hitCount();
4749

50+
/**
51+
* Return the total time acquiring a connection from the pool.
52+
*/
53+
long totalAcquireMicros();
54+
55+
/**
56+
* Return the total time waiting in micros for a free connection when the pool has hit maxConnections.
57+
* <p>
58+
* When the pool is full and threads are waiting for a connection, this is the total time spent waiting.
59+
*/
60+
long totalWaitMicros();
61+
4862
/**
4963
* Return the max acquire time in micros.
5064
*/

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

Lines changed: 18 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ private void reset() {
605605
}
606606

607607
/**
608-
* Create an un-pooled connection with the given username and password.
608+
* Create an unpooled connection with the given username and password.
609609
* <p>
610610
* This uses the default isolation level and autocommit mode.
611611
*/
@@ -639,13 +639,6 @@ private PooledConnection getPooledConnection() throws SQLException {
639639
return c;
640640
}
641641

642-
/**
643-
* This will close all the free connections, and then go into a wait loop,
644-
* waiting for the busy connections to be freed.
645-
* <p>
646-
* The DataSources's should be shutdown AFTER thread pools. Leaked
647-
* Connections are not waited on, as that would hang the server.
648-
*/
649642
@Override
650643
public void shutdown() {
651644
shutdownPool(true, false);
@@ -725,9 +718,6 @@ private void stopHeartBeatIfRunning() {
725718
}
726719
}
727720

728-
/**
729-
* Return the default autoCommit setting for the pool.
730-
*/
731721
@Override
732722
public boolean isAutoCommit() {
733723
return autoCommit;
@@ -785,13 +775,6 @@ public void setLogWriter(PrintWriter writer) throws SQLException {
785775
throw new SQLException("Method not supported");
786776
}
787777

788-
/**
789-
* Return the current status of the connection pool.
790-
* <p>
791-
* If you pass reset = true then the counters such as
792-
* hitCount, waitCount and highWaterMark are reset.
793-
* </p>
794-
*/
795778
@Override
796779
public PoolStatus status(boolean reset) {
797780
return queue.status(reset);
@@ -807,10 +790,12 @@ static final class Status implements PoolStatus {
807790
private final int highWaterMark;
808791
private final int waitCount;
809792
private final int hitCount;
793+
private final long totalAcquireMicros;
810794
private final long maxAcquireMicros;
795+
private final long totalWaitMicros;
811796
private final long meanAcquireNanos;
812797

813-
Status(int minSize, int maxSize, int free, int busy, int waiting, int highWaterMark, int waitCount, int hitCount, long totalAcquireNanos, long maxAcquireNanos) {
798+
Status(int minSize, int maxSize, int free, int busy, int waiting, int highWaterMark, int waitCount, int hitCount, long totalAcquireNanos, long maxAcquireNanos, long totalWaitNanos) {
814799
this.minSize = minSize;
815800
this.maxSize = maxSize;
816801
this.free = free;
@@ -819,86 +804,69 @@ static final class Status implements PoolStatus {
819804
this.highWaterMark = highWaterMark;
820805
this.waitCount = waitCount;
821806
this.hitCount = hitCount;
822-
this.meanAcquireNanos = hitCount == 0 ? 0 : totalAcquireNanos / hitCount;
807+
this.totalAcquireMicros = totalAcquireNanos / 1000;
823808
this.maxAcquireMicros = maxAcquireNanos / 1000;
809+
this.totalWaitMicros = totalWaitNanos / 1000;
810+
this.meanAcquireNanos = hitCount == 0 ? 0 : totalAcquireNanos / hitCount;
824811
}
825812

826813
@Override
827814
public String toString() {
828815
return "min[" + minSize + "] max[" + maxSize + "] free[" + free + "] busy[" + busy + "] waiting[" + waiting
829816
+ "] highWaterMark[" + highWaterMark + "] waitCount[" + waitCount + "] hitCount[" + hitCount
830-
+ "] meanAcquireNanos[" + meanAcquireNanos + "] maxAcquireMicros[" + maxAcquireMicros + "]";
817+
+ "] totalAcquireMicros[" + totalAcquireMicros + "] maxAcquireMicros[" + maxAcquireMicros + "] totalWaitMicros[" + totalWaitMicros + "]";
831818
}
832819

833-
/**
834-
* Return the min pool size.
835-
*/
836820
@Override
837821
public int minSize() {
838822
return minSize;
839823
}
840824

841-
/**
842-
* Return the max pool size.
843-
*/
844825
@Override
845826
public int maxSize() {
846827
return maxSize;
847828
}
848829

849-
/**
850-
* Return the current number of free connections in the pool.
851-
*/
852830
@Override
853831
public int free() {
854832
return free;
855833
}
856834

857-
/**
858-
* Return the current number of busy connections in the pool.
859-
*/
860835
@Override
861836
public int busy() {
862837
return busy;
863838
}
864839

865-
/**
866-
* Return the current number of threads waiting for a connection.
867-
*/
868840
@Override
869841
public int waiting() {
870842
return waiting;
871843
}
872844

873-
/**
874-
* Return the high water mark of busy connections.
875-
*/
876845
@Override
877846
public int highWaterMark() {
878847
return highWaterMark;
879848
}
880849

881-
/**
882-
* Return the total number of times a thread had to wait.
883-
*/
884850
@Override
885851
public int waitCount() {
886852
return waitCount;
887853
}
888854

889-
/**
890-
* Return the total number of times there was an attempt to get a
891-
* connection.
892-
* <p>
893-
* If the attempt to get a connection failed with a timeout or other
894-
* exception those attempts are still included in this hit count.
895-
* </p>
896-
*/
897855
@Override
898856
public int hitCount() {
899857
return hitCount;
900858
}
901859

860+
@Override
861+
public long totalAcquireMicros() {
862+
return totalAcquireMicros;
863+
}
864+
865+
@Override
866+
public long totalWaitMicros() {
867+
return totalWaitMicros;
868+
}
869+
902870
@Override
903871
public long maxAcquireMicros() {
904872
return maxAcquireMicros;

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ final class PooledConnectionQueue {
5353
private int hitCount;
5454
private long totalAcquireNanos;
5555
private long maxAcquireNanos;
56+
private long totalWaitNanos;
5657

5758
/**
5859
* The high water mark for the queue size.
@@ -82,7 +83,7 @@ final class PooledConnectionQueue {
8283

8384
private PoolStatus createStatus() {
8485
return new Status(minSize, maxSize, freeList.size(), busyList.size(), waitingThreads, highWaterMark,
85-
waitCount, hitCount, totalAcquireNanos, maxAcquireNanos);
86+
waitCount, hitCount, totalAcquireNanos, maxAcquireNanos, totalWaitNanos);
8687
}
8788

8889
@Override
@@ -105,6 +106,7 @@ PoolStatus status(boolean reset) {
105106
waitCount = 0;
106107
maxAcquireNanos = 0;
107108
totalAcquireNanos = 0;
109+
totalWaitNanos = 0;
108110
}
109111
return s;
110112
} finally {
@@ -244,6 +246,7 @@ private PooledConnection _obtainConnection() throws InterruptedException, SQLExc
244246
return _obtainConnectionWaitLoop();
245247
} finally {
246248
waitingThreads--;
249+
totalWaitNanos += (System.nanoTime() - start);
247250
}
248251
} finally {
249252
final var elapsed = System.nanoTime() - start;

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import io.ebean.datasource.DataSourceAlert;
44
import io.ebean.datasource.DataSourceBuilder;
55
import io.ebean.datasource.DataSourcePool;
6+
import io.ebean.datasource.PoolStatus;
67
import org.junit.jupiter.api.Test;
78

89
import javax.sql.DataSource;
@@ -68,6 +69,11 @@ void testPoolFullWithHeartbeat() throws Exception {
6869
assertThat(up).isEqualTo(2);
6970
assertThat(down).isEqualTo(1);
7071

72+
PoolStatus status = pool.status(true);
73+
assertThat(status.waitCount()).isGreaterThan(0);
74+
assertThat(status.totalWaitMicros()).isBetween(0L, 9_000_000L);
75+
assertThat(status.totalAcquireMicros()).isBetween(0L, 20_000_000L);
76+
assertThat(status.maxAcquireMicros()).isBetween(0L, 3_000_000L);
7177

7278
} finally {
7379
pool.shutdown();

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,18 @@ void getConnection_expect_poolGrowsAboveMin() throws SQLException {
6464

6565
con1.rollback();
6666
con1.close();
67-
assertThat(pool.status(false).busy()).isEqualTo(0);
68-
assertThat(pool.status(false).free()).isEqualTo(3);
67+
PoolStatus status = pool.status(true);
68+
assertThat(status.busy()).isEqualTo(0);
69+
assertThat(status.free()).isEqualTo(3);
6970
assertThat(pool.size()).isEqualTo(3);
71+
assertThat(status.waitCount()).isEqualTo(0);
72+
assertThat(status.totalWaitMicros()).isEqualTo(0);
73+
assertThat(status.hitCount()).isEqualTo(3);
74+
assertThat(status.maxAcquireMicros()).isBetween(0L, 900L);
75+
assertThat(status.meanAcquireNanos() / 1000).isBetween(0L, 900L);
76+
assertThat(status.highWaterMark()).isEqualTo(3);
77+
assertThat(status.minSize()).isEqualTo(2);
78+
assertThat(status.maxSize()).isEqualTo(4);
7079
}
7180

7281
@Test

0 commit comments

Comments
 (0)