Skip to content

Commit 3b6cef6

Browse files
authored
Metrics vertx_pool_queue_pending doesn't decrease after connection loss (#1530)
* Metrics vertx_pool_queue_pending doesn't decrease after connection loss Backported from #1529 See #1494 SqlConnectionPool must invoke dequeueMetric when a connection fails to be acquired Signed-off-by: Thomas Segismont <[email protected]> * Ignore OracleMetricsTest#testConnectionLost Fails on Oracle 2025-06-18T08:12:53.8427877Z [ERROR] tests.oracleclient.tck.OracleMetricsTest.testConnectionLost -- Time elapsed: 20.07 s <<< ERROR! 2025-06-18T08:12:53.8428800Z java.util.concurrent.TimeoutException: Timed out 2025-06-18T08:12:53.8429660Z at [email protected]/io.vertx.ext.unit.impl.CompletionImpl.await(CompletionImpl.java:73) 2025-06-18T08:12:53.8431163Z at io.vertx.tests.sql.client/io.vertx.tests.sqlclient.tck.MetricsTestBase.testConnectionLost(MetricsTestBase.java:232) 2025-06-18T08:12:53.8432547Z at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) 2025-06-18T08:12:53.8433884Z at java.base/java.lang.reflect.Method.invoke(Method.java:580) 2025-06-18T08:12:53.8434931Z at [email protected]/io.vertx.ext.unit.junit.VertxUnitRunner.invokeTestMethod(VertxUnitRunner.java:95) 2025-06-18T08:12:53.8436414Z at [email protected]/io.vertx.ext.unit.junit.VertxUnitRunner.lambda$invokeExplosively$0(VertxUnitRunner.java:114) 2025-06-18T08:12:53.8437841Z at [email protected]/io.vertx.ext.unit.impl.TestContextImpl.run(TestContextImpl.java:90) 2025-06-18T08:12:53.8439166Z at [email protected]/io.vertx.ext.unit.junit.VertxUnitRunner.invokeExplosively(VertxUnitRunner.java:130) 2025-06-18T08:12:53.8440505Z at [email protected]/io.vertx.ext.unit.junit.VertxUnitRunner$1.evaluate(VertxUnitRunner.java:84) 2025-06-18T08:12:53.8444504Z at [email protected]/io.vertx.ext.unit.junit.VertxUnitRunner$2.evaluate(VertxUnitRunner.java:196) 2025-06-18T08:12:53.8446923Z at [email protected]/io.vertx.ext.unit.junit.VertxUnitRunner$3.evaluate(VertxUnitRunner.java:211) 2025-06-18T08:12:53.8448011Z at [email protected]/org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) 2025-06-18T08:12:53.8449021Z at [email protected]/org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100) 2025-06-18T08:12:53.8449969Z at [email protected]/org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366) 2025-06-18T08:12:53.8451715Z at [email protected]/org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103) 2025-06-18T08:12:53.8453107Z at [email protected]/org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63) 2025-06-18T08:12:53.8453868Z at [email protected]/org.junit.runners.ParentRunner$4.run(ParentRunner.java:331) 2025-06-18T08:12:53.8454674Z at [email protected]/org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79) 2025-06-18T08:12:53.8455502Z at [email protected]/org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329) 2025-06-18T08:12:53.8456341Z at [email protected]/org.junit.runners.ParentRunner.access$100(ParentRunner.java:66) 2025-06-18T08:12:53.8457153Z at [email protected]/org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293) 2025-06-18T08:12:53.8457997Z at [email protected]/org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:54) 2025-06-18T08:12:53.8458761Z at [email protected]/org.junit.rules.RunRules.evaluate(RunRules.java:20) 2025-06-18T08:12:53.8459749Z at [email protected]/org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) 2025-06-18T08:12:53.8460722Z at [email protected]/org.junit.runners.ParentRunner.run(ParentRunner.java:413) 2025-06-18T08:12:53.8461598Z at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:316) 2025-06-18T08:12:53.8462621Z at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:240) 2025-06-18T08:12:53.8463694Z at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:214) 2025-06-18T08:12:53.8464613Z at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:155) 2025-06-18T08:12:53.8465193Z at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:385) 2025-06-18T08:12:53.8465752Z at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162) 2025-06-18T08:12:53.8466255Z at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:507) 2025-06-18T08:12:53.8466754Z at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:495) 2025-06-18T08:12:53.8467047Z 2025-06-18T08:13:13.5057371Z Jun 18, 2025 8:13:13 AM oracle.jdbc.driver.PhysicalConnection connect 2025-06-18T08:13:13.5065518Z INFO: entering args (oracle.jdbc.datasource.impl.OracleDataSource$1@6a8b05c5) 2025-06-18T08:13:13.5067705Z Jun 18, 2025 8:13:13 AM oracle.net.ns.NSProtocol connect 2025-06-18T08:13:13.5068225Z INFO: traceId=1E1826C1. 2025-06-18T08:13:13.5068725Z Jun 18, 2025 8:13:13 AM oracle.net.ns.NSProtocol establishConnection 2025-06-18T08:13:13.5069809Z INFO: Session Attributes: 2025-06-18T08:13:13.5070161Z sdu=8192, tdu=2097152 2025-06-18T08:13:13.5071040Z nt: host=localhost, port=32769, socketOptions={0=YES, 1=NO, 17=0, 18=false, 2=0, 20=true, 38=TLS, 23=40, 24=50, 40=false, 25=0} 2025-06-18T08:13:13.5071793Z socket=null 2025-06-18T08:13:13.5073880Z client profile={oracle.net.encryption_types_client=(), oracle.net.crypto_seed=, oracle.net.authentication_services=(), oracle.net.setFIPSMode=false, oracle.net.kerberos5_mutual_authentication=false, oracle.net.encryption_client=ACCEPTED, oracle.net.crypto_checksum_client=ACCEPTED, oracle.net.crypto_checksum_types_client=()} 2025-06-18T08:13:13.5076223Z onBreakReset=false, dataEOF=false, negotiatedOptions=0x0, connected=false 2025-06-18T08:13:13.5076905Z TTIINIT enabled=false, TTC cookie enabled=false 2025-06-18T08:13:13.5077253Z 2025-06-18T08:13:13.5077540Z Jun 18, 2025 8:13:13 AM oracle.net.ns.NSProtocol configureSessionAttsAno 2025-06-18T08:13:13.5078150Z INFO: traceId=1E1826C1, anoEnabled=true. 2025-06-18T08:13:13.5078754Z Jun 18, 2025 8:13:13 AM oracle.net.ns.NSProtocolNIO handleConnectPacketResponse 2025-06-18T08:13:13.5079401Z INFO: Got Refused, SessionTraceId = 1E1826C1 2025-06-18T08:13:13.5080067Z Jun 18, 2025 8:13:13 AM oracle.net.ns.NSProtocolNIO establishConnectionAfterRefusePacket 2025-06-18T08:13:13.5081022Z INFO: Outbound interrupt timer cancelled null 2025-06-18T08:13:13.5081604Z Jun 18, 2025 8:13:13 AM oracle.net.ns.NSProtocol establishConnection 2025-06-18T08:13:13.5082150Z INFO: Session Attributes: 2025-06-18T08:13:13.5082504Z sdu=8192, tdu=2097152 2025-06-18T08:13:13.5083213Z nt: host=localhost, port=32769, socketOptions={0=YES, 1=NO, 17=0, 18=false, 2=0, 20=true, 38=TLS, 23=40, 24=50, 40=false, 25=0} 2025-06-18T08:13:13.5083954Z socket=null 2025-06-18T08:13:13.5085828Z client profile={oracle.net.encryption_types_client=(), oracle.net.crypto_seed=, oracle.net.authentication_services=(), oracle.net.setFIPSMode=false, oracle.net.kerberos5_mutual_authentication=false, oracle.net.encryption_client=ACCEPTED, oracle.net.crypto_checksum_client=ACCEPTED, oracle.net.crypto_checksum_types_client=()} 2025-06-18T08:13:13.5088048Z onBreakReset=false, dataEOF=false, negotiatedOptions=0x0, connected=false 2025-06-18T08:13:13.5088717Z TTIINIT enabled=false, TTC cookie enabled=false 2025-06-18T08:13:13.5089087Z 2025-06-18T08:13:13.5089412Z Jun 18, 2025 8:13:13 AM oracle.net.ns.NSProtocolNIO handleConnectPacketResponse 2025-06-18T08:13:13.5090323Z INFO: Got Refused, SessionTraceId = 1E1826C1 2025-06-18T08:13:13.5091316Z Jun 18, 2025 8:13:13 AM oracle.net.ns.NSProtocolNIO establishConnectionAfterRefusePacket 2025-06-18T08:13:13.5092028Z INFO: Outbound interrupt timer cancelled null 2025-06-18T08:13:13.5092622Z Jun 18, 2025 8:13:13 AM oracle.jdbc.driver.PhysicalConnection connect 2025-06-18T08:13:13.5093155Z INFO: throwing 2025-06-18T08:13:13.5094410Z java.sql.SQLRecoverableException: ORA-12514: Cannot connect to database. Service invalidDatabase is not registered with the listener at host localhost port 32769. (CONNECTION_ID=mow8621wRDKG5TmVDKKOKA==) 2025-06-18T08:13:13.5095939Z https://docs.oracle.com/error-help/db/ora-12514/ 2025-06-18T08:13:13.5096950Z at [email protected]/oracle.jdbc.driver.T4CConnection.handleLogonNetException(T4CConnection.java:1615) 2025-06-18T08:13:13.5098226Z at [email protected]/oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:1137) 2025-06-18T08:13:13.5099436Z at [email protected]/oracle.jdbc.driver.PhysicalConnection.connect(PhysicalConnection.java:1178) 2025-06-18T08:13:13.5100955Z at [email protected]/oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:105) 2025-06-18T08:13:13.5102218Z at [email protected]/oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:886) 2025-06-18T08:13:13.5103600Z at [email protected]/oracle.jdbc.datasource.impl.OracleDataSource.getPhysicalConnection(OracleDataSource.java:707) 2025-06-18T08:13:13.5105399Z at [email protected]/oracle.jdbc.datasource.impl.OracleDataSource.getConnection(OracleDataSource.java:381) 2025-06-18T08:13:13.5106849Z at [email protected]/oracle.jdbc.datasource.impl.OracleDataSource.getConnectionInternal(OracleDataSource.java:2206) 2025-06-18T08:13:13.5108381Z at [email protected]/oracle.jdbc.datasource.impl.OracleDataSource$1.build(OracleDataSource.java:1915) 2025-06-18T08:13:13.5109766Z at [email protected]/oracle.jdbc.datasource.impl.OracleDataSource$1.build(OracleDataSource.java:1849) 2025-06-18T08:13:13.5111178Z at [email protected]/io.vertx.oracleclient.impl.OracleConnectionFactory.lambda$connect$0(OracleConnectionFactory.java:68) 2025-06-18T08:13:13.5112048Z at [email protected]/io.vertx.oracleclient.impl.Helper$SQLBlockingCodeHandler.call(Helper.java:306) 2025-06-18T08:13:13.5112745Z at [email protected]/io.vertx.core.impl.ExecuteBlocking$1.execute(ExecuteBlocking.java:36) 2025-06-18T08:13:13.5113324Z at [email protected]/io.vertx.core.impl.WorkerTask.run(WorkerTask.java:57) 2025-06-18T08:13:13.5113895Z at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) 2025-06-18T08:13:13.5114494Z at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) 2025-06-18T08:13:13.5115175Z at [email protected]/io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) 2025-06-18T08:13:13.5115711Z at java.base/java.lang.Thread.run(Thread.java:1583) 2025-06-18T08:13:13.5116495Z Caused by: oracle.net.ns.NetException: ORA-12514: Cannot connect to database. Service invalidDatabase is not registered with the listener at host localhost port 32769. (CONNECTION_ID=mow8621wRDKG5TmVDKKOKA==) 2025-06-18T08:13:13.5117693Z https://docs.oracle.com/error-help/db/ora-12514/ 2025-06-18T08:13:13.5119748Z at [email protected]/oracle.net.ns.NSProtocolNIO.createRefusePacketException(NSProtocolNIO.java:915) 2025-06-18T08:13:13.5121187Z at [email protected]/oracle.net.ns.NSProtocolNIO.handleConnectPacketResponse(NSProtocolNIO.java:461) 2025-06-18T08:13:13.5122401Z at [email protected]/oracle.net.ns.NSProtocolNIO.negotiateConnection(NSProtocolNIO.java:269) 2025-06-18T08:13:13.5123712Z at [email protected]/oracle.net.ns.NSProtocol.connect(NSProtocol.java:352) 2025-06-18T08:13:13.5124855Z at [email protected]/oracle.jdbc.driver.T4CConnection.connectNetworkSessionProtocol(T4CConnection.java:3411) 2025-06-18T08:13:13.5126233Z at [email protected]/oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:1016) 2025-06-18T08:13:13.5126994Z ... 16 more 2025-06-18T08:13:13.5127176Z 2025-06-18T08:13:13.5127531Z Jun 18, 2025 8:13:13 AM oracle.jdbc.diagnostics.Diagnostic dumpDiagnoseFirstFailure 2025-06-18T08:13:13.5128911Z INFO: properties={LOCALE=en, DriverVersion=23.4.0.24.05, java.library.path: =/usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib, java.class.path: =, java.version: =21.0.7}. 2025-06-18T08:13:15.6622033Z [ORACLE] 2025-06-18T08:13:15.077401+00:00 2025-06-18T08:13:15.6623347Z [ORACLE] TABLE SYS.WRP$_REPORTS: ADDED AUTOLIST FRAGMENT SYS_P422 (3) VALUES (( 1467203046, TO_DATE(' 2025-06-16 00:00:00', 'syyyy-mm-dd hh24:mi:ss', 'nls_calendar=gregorian') )) 2025-06-18T08:13:15.6625132Z [ORACLE] TABLE SYS.WRP$_REPORTS_DETAILS: ADDED AUTOLIST FRAGMENT SYS_P423 (3) VALUES (( 1467203046, TO_DATE(' 2025-06-16 00:00:00', 'syyyy-mm-dd hh24:mi:ss', 'nls_calendar=gregorian') )) 2025-06-18T08:13:15.6626932Z [ORACLE] TABLE SYS.WRP$_REPORTS_TIME_BANDS: ADDED AUTOLIST FRAGMENT SYS_P426 (3) VALUES (( 1467203046, TO_DATE(' 2025-06-16 00:00:00', 'syyyy-mm-dd hh24:mi:ss', 'nls_calendar=gregorian') )) 2025-06-18T08:13:21.8199194Z [ERROR] Errors: 2025-06-18T08:13:21.8201259Z [ERROR] OracleMetricsTest>MetricsTestBase.testConnectionLost:232 » Timeout Timed out 2025-06-18T08:13:21.8202285Z [ERROR] Tests run: 262, Failures: 0, Errors: 1, Skipped: 21 Signed-off-by: Thomas Segismont <[email protected]> * Ignore OracleMetricsTest#testQueuingXXX Fails on Oracle Signed-off-by: Thomas Segismont <[email protected]> --------- Signed-off-by: Thomas Segismont <[email protected]>
1 parent 740a4b7 commit 3b6cef6

File tree

5 files changed

+158
-14
lines changed

5 files changed

+158
-14
lines changed

vertx-mssql-client/src/test/java/io/vertx/mssqlclient/tck/MSSQLMetricsTest.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
package io.vertx.mssqlclient.tck;
1313

1414
import io.vertx.mssqlclient.MSSQLBuilder;
15+
import io.vertx.mssqlclient.MSSQLConnectOptions;
1516
import io.vertx.mssqlclient.junit.MSSQLRule;
1617
import io.vertx.sqlclient.ClientBuilder;
1718
import io.vertx.sqlclient.Pool;
19+
import io.vertx.sqlclient.SqlConnectOptions;
1820
import io.vertx.sqlclient.tck.MetricsTestBase;
1921
import org.junit.ClassRule;
2022

@@ -23,9 +25,14 @@ public class MSSQLMetricsTest extends MetricsTestBase {
2325
@ClassRule
2426
public static MSSQLRule rule = MSSQLRule.SHARED_INSTANCE;
2527

28+
@Override
29+
protected SqlConnectOptions connectOptions() {
30+
return new MSSQLConnectOptions(rule.options());
31+
}
32+
2633
@Override
2734
protected ClientBuilder<Pool> poolBuilder() {
28-
return MSSQLBuilder.pool().connectingTo(rule.options());
35+
return MSSQLBuilder.pool().connectingTo(connectOptions());
2936
}
3037

3138
@Override

vertx-oracle-client/src/test/java/io/vertx/oracleclient/test/tck/OracleMetricsTest.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313

1414
import io.vertx.ext.unit.TestContext;
1515
import io.vertx.oracleclient.OracleBuilder;
16+
import io.vertx.oracleclient.OracleConnectOptions;
1617
import io.vertx.oracleclient.test.junit.OracleRule;
1718
import io.vertx.sqlclient.ClientBuilder;
1819
import io.vertx.sqlclient.Pool;
20+
import io.vertx.sqlclient.SqlConnectOptions;
1921
import io.vertx.sqlclient.tck.MetricsTestBase;
2022
import org.junit.ClassRule;
2123
import org.junit.Ignore;
@@ -26,9 +28,14 @@ public class OracleMetricsTest extends MetricsTestBase {
2628
@ClassRule
2729
public static OracleRule rule = OracleRule.SHARED_INSTANCE;
2830

31+
@Override
32+
protected SqlConnectOptions connectOptions() {
33+
return new OracleConnectOptions(rule.options());
34+
}
35+
2936
@Override
3037
protected ClientBuilder<Pool> poolBuilder() {
31-
return OracleBuilder.pool().connectingTo(rule.options());
38+
return OracleBuilder.pool().connectingTo(connectOptions());
3239
}
3340

3441
@Override
@@ -49,4 +56,25 @@ public void testPreparedBatchQuery(TestContext ctx) {
4956
public void testPrepareAndBatchQuery(TestContext ctx) {
5057
super.testPrepareAndBatchQuery(ctx);
5158
}
59+
60+
@Test
61+
@Ignore("Implementation of the test does not work with Oracle")
62+
@Override
63+
public void testQueuing(TestContext ctx) throws Exception {
64+
super.testQueuing(ctx);
65+
}
66+
67+
@Test
68+
@Ignore("Implementation of the test does not work with Oracle")
69+
@Override
70+
public void testQueuingTimeout(TestContext ctx) throws Exception {
71+
super.testQueuingTimeout(ctx);
72+
}
73+
74+
@Test
75+
@Ignore("Implementation of the test does not work with Oracle")
76+
@Override
77+
public void testConnectionLost(TestContext ctx) throws Exception {
78+
super.testConnectionLost(ctx);
79+
}
5280
}

vertx-pg-client/src/test/java/io/vertx/pgclient/PgMetricsTest.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import io.vertx.pgclient.junit.ContainerPgRule;
1515
import io.vertx.sqlclient.ClientBuilder;
1616
import io.vertx.sqlclient.Pool;
17+
import io.vertx.sqlclient.SqlConnectOptions;
1718
import io.vertx.sqlclient.tck.MetricsTestBase;
1819
import org.junit.ClassRule;
1920

@@ -22,9 +23,14 @@ public class PgMetricsTest extends MetricsTestBase {
2223
@ClassRule
2324
public static ContainerPgRule rule = new ContainerPgRule();
2425

26+
@Override
27+
protected SqlConnectOptions connectOptions() {
28+
return new PgConnectOptions(rule.options());
29+
}
30+
2531
@Override
2632
protected ClientBuilder<Pool> poolBuilder() {
27-
return PgBuilder.pool().connectingTo(rule.options());
33+
return PgBuilder.pool().connectingTo(connectOptions());
2834
}
2935

3036
@Override

vertx-sql-client/src/main/java/io/vertx/sqlclient/impl/pool/SqlConnectionPool.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,16 @@ private Object dequeueAndBeginUse(Object metric) {
186186
return NO_METRICS;
187187
}
188188

189+
private void dequeueAndReject(Object metric) {
190+
if (metrics != null && metric != NO_METRICS) {
191+
try {
192+
metrics.rejected(metric);
193+
} catch (Exception e) {
194+
// Log
195+
}
196+
}
197+
}
198+
189199
private Object endUse(Object metric) {
190200
if (metrics != null && metric != NO_METRICS) {
191201
try {
@@ -271,6 +281,7 @@ public void onEnqueue(PoolWaiter<PooledConnection> waiter) {
271281
pool.cancel(waiter, ar -> {
272282
if (ar.succeeded()) {
273283
if (ar.result()) {
284+
dequeueAndReject(queueMetric);
274285
handler.handle(Future.failedFuture("Timeout"));
275286
}
276287
} else {

vertx-sql-client/src/test/java/io/vertx/sqlclient/tck/MetricsTestBase.java

Lines changed: 103 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
import java.util.concurrent.atomic.AtomicReference;
3737
import java.util.function.Function;
3838

39+
import static java.util.concurrent.TimeUnit.MILLISECONDS;
40+
import static java.util.concurrent.TimeUnit.SECONDS;
41+
3942
@RunWith(VertxUnitRunner.class)
4043
public abstract class MetricsTestBase {
4144

@@ -81,6 +84,8 @@ protected Pool getPool() {
8184
return pool;
8285
}
8386

87+
protected abstract SqlConnectOptions connectOptions();
88+
8489
protected abstract ClientBuilder<Pool> poolBuilder();
8590

8691
protected Pool createPool(Vertx vertx) {
@@ -122,6 +127,15 @@ public void close() {
122127

123128
@Test
124129
public void testQueuing(TestContext ctx) throws Exception {
130+
testQueuing(ctx, false);
131+
}
132+
133+
@Test
134+
public void testQueuingTimeout(TestContext ctx) throws Exception {
135+
testQueuing(ctx, true);
136+
}
137+
138+
private void testQueuing(TestContext ctx, boolean timeout) throws Exception {
125139
AtomicInteger queueSize = new AtomicInteger();
126140
AtomicInteger inUse = new AtomicInteger();
127141
List<Object> enqueueMetrics = Collections.synchronizedList(new ArrayList<>());
@@ -156,28 +170,106 @@ public void end(Object inUseMetric, boolean succeeded) {
156170
endMetrics.add(inUseMetric);
157171
}
158172
};
159-
Pool pool = createPool(vertx, new PoolOptions().setMaxSize(1).setName("the-pool"));
160-
SqlConnection conn = pool.getConnection().toCompletionStage().toCompletableFuture().get(20, TimeUnit.SECONDS);
173+
PoolOptions poolOptions = new PoolOptions().setMaxSize(1).setName("the-pool");
174+
if (timeout) {
175+
poolOptions.setConnectionTimeout(2).setConnectionTimeoutUnit(SECONDS);
176+
}
177+
Pool pool = createPool(vertx, poolOptions);
178+
SqlConnection conn = Future.await(pool.getConnection(), 20, SECONDS);
161179
int num = 16;
162180
List<Future<?>> futures = new ArrayList<>();
163181
for (int i = 0;i < num;i++) {
164-
futures.add(pool.query("SELECT * FROM immutable WHERE id=1").execute());
165-
}
166-
long now = System.currentTimeMillis();
167-
while (queueSize.get() != num) {
168-
ctx.assertTrue(System.currentTimeMillis() - now < 20_000);
169-
Thread.sleep(100);
182+
futures.add(pool.withConnection(sqlConn -> sqlConn.query("SELECT * FROM immutable WHERE id=1").execute()));
170183
}
171-
conn.close();
172-
Future.join(futures).toCompletionStage().toCompletableFuture().get(20, TimeUnit.SECONDS);
184+
awaitQueueSize(ctx, queueSize, timeout ? 0 : num);
185+
Future.await(conn.close(), 20, SECONDS);
186+
Future.await(Future.join(futures).otherwiseEmpty(), 20, SECONDS);
173187
ctx.assertEquals(0, queueSize.get());
174188
ctx.assertEquals(0, inUse.get());
175-
ctx.assertEquals(enqueueMetrics, dequeueMetrics);
189+
if (timeout) {
190+
ctx.assertTrue(enqueueMetrics.containsAll(dequeueMetrics) && dequeueMetrics.containsAll(enqueueMetrics));
191+
} else {
192+
ctx.assertEquals(enqueueMetrics, dequeueMetrics);
193+
}
176194
ctx.assertEquals(beginMetrics, endMetrics);
177195
ctx.assertEquals("sql", poolType);
178196
ctx.assertEquals("the-pool", poolName);
179197
}
180198

199+
private void awaitQueueSize(TestContext ctx, AtomicInteger queueSize, int num) throws InterruptedException {
200+
long now = System.currentTimeMillis();
201+
for (; ; ) {
202+
if (queueSize.get() != num) {
203+
if (System.currentTimeMillis() - now >= 20_000) {
204+
ctx.fail("Timeout waiting for queue size " + queueSize.get() + " to be equal to " + num);
205+
} else {
206+
MILLISECONDS.sleep(500);
207+
}
208+
} else {
209+
break;
210+
}
211+
}
212+
}
213+
214+
@Test
215+
public void testConnectionLost(TestContext ctx) throws Exception {
216+
SqlConnectOptions connectOptions = connectOptions();
217+
ProxyServer proxy = ProxyServer.create(vertx, connectOptions.getPort(), connectOptions.getHost());
218+
AtomicReference<ProxyServer.Connection> firstConnection = new AtomicReference<>();
219+
proxy.proxyHandler(proxiedConn -> {
220+
if (firstConnection.compareAndSet(null, proxiedConn)) {
221+
proxiedConn.connect();
222+
}
223+
});
224+
// Start proxy
225+
Async listenLatch = ctx.async();
226+
proxy.listen(8080, "localhost", ctx.asyncAssertSuccess(res -> listenLatch.complete()));
227+
listenLatch.awaitSuccess(20_000);
228+
229+
230+
AtomicInteger queueSize = new AtomicInteger();
231+
poolMetrics = new PoolMetrics() {
232+
@Override
233+
public Object submitted() {
234+
queueSize.incrementAndGet();
235+
return null;
236+
}
237+
238+
@Override
239+
public Object begin(Object o) {
240+
queueSize.decrementAndGet();
241+
return null;
242+
}
243+
244+
@Override
245+
public void rejected(Object o) {
246+
queueSize.decrementAndGet();
247+
}
248+
};
249+
PoolOptions poolOptions = new PoolOptions()
250+
.setConnectionTimeout(500)
251+
.setConnectionTimeoutUnit(MILLISECONDS)
252+
.setMaxSize(1)
253+
.setName("the-pool");
254+
Pool pool = poolBuilder()
255+
.with(poolOptions)
256+
.using(vertx)
257+
.connectingTo(connectOptions.setHost("localhost").setPort(8080))
258+
.build();
259+
SqlConnection conn = Future.await(pool.getConnection(), 20, SECONDS);
260+
int num = 16;
261+
Async async = ctx.async(num + 1);
262+
for (int i = 0; i < num; i++) {
263+
pool.withConnection(sqlConn -> sqlConn.query("SELECT * FROM immutable WHERE id=1").execute())
264+
.onComplete(ctx.asyncAssertFailure(t -> async.countDown()));
265+
}
266+
conn.closeHandler(v -> async.countDown());
267+
awaitQueueSize(ctx, queueSize, 16);
268+
firstConnection.get().clientSocket().close();
269+
async.await(20_000);
270+
ctx.assertEquals(0, queueSize.get());
271+
}
272+
181273
@Test
182274
public void testSimpleQuery(TestContext ctx) {
183275
Function<SqlConnection, Future<?>> fn = conn -> conn.query("SELECT * FROM immutable WHERE id=1").execute();

0 commit comments

Comments
 (0)