Skip to content

Commit 522c037

Browse files
committed
perf: Add HTTP connect timeout and double-checked locking for ADBC init
- Set 10s connect timeout on the static HttpClient used for dataset refresh, preventing threads from blocking indefinitely on unreachable endpoints. - Replace synchronized initADBCIfNeeded() with double-checked locking using a volatile adbcInitialized flag. After warmup, parameterized queries skip the monitor entirely (volatile read only), eliminating contention at high concurrency.
1 parent 9aed5e0 commit 522c037

1 file changed

Lines changed: 14 additions & 4 deletions

File tree

src/main/java/ai/spice/SpiceClient.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@ public class SpiceClient implements AutoCloseable {
134134
private static final Gson GSON = new Gson();
135135

136136
// Cached HttpClient for refresh operations (thread-safe, connection pooling)
137-
private static final HttpClient HTTP_CLIENT = HttpClient.newHttpClient();
137+
private static final HttpClient HTTP_CLIENT = HttpClient.newBuilder()
138+
.connectTimeout(Duration.ofSeconds(10))
139+
.build();
138140

139141
// Pre-computed parameter field names to avoid string concatenation in hot path
140142
private static final String[] PARAM_NAMES = new String[64];
@@ -160,6 +162,7 @@ public class SpiceClient implements AutoCloseable {
160162
private Retryer<FlightStream> flightRetryer;
161163

162164
// ADBC resources for parameterized queries
165+
private volatile boolean adbcInitialized = false;
163166
private AdbcDatabase adbcDatabase;
164167
private AdbcConnection adbcConnection;
165168

@@ -504,12 +507,16 @@ public ArrowReader queryWithParams(String sql, Object... params) throws Executio
504507

505508
/**
506509
* Initializes the ADBC connection if not already initialized.
507-
* This is called lazily on the first parameterized query.
510+
* Uses double-checked locking to avoid monitor contention on the hot path.
508511
*/
509-
private synchronized void initADBCIfNeeded() throws AdbcException {
510-
if (adbcDatabase != null && adbcConnection != null) {
512+
private void initADBCIfNeeded() throws AdbcException {
513+
if (adbcInitialized) {
511514
return;
512515
}
516+
synchronized (this) {
517+
if (adbcInitialized) {
518+
return;
519+
}
513520

514521
logger.debug("Initializing ADBC connection");
515522

@@ -545,14 +552,17 @@ private synchronized void initADBCIfNeeded() throws AdbcException {
545552
FlightSqlDriver driver = new FlightSqlDriver(allocator);
546553
adbcDatabase = driver.open(options);
547554
adbcConnection = adbcDatabase.connect();
555+
adbcInitialized = true;
548556

549557
logger.debug("ADBC connection established - uri={}", uri);
558+
}
550559
}
551560

552561
/**
553562
* Closes the ADBC resources.
554563
*/
555564
private void closeADBC() {
565+
adbcInitialized = false;
556566
if (adbcConnection != null) {
557567
try {
558568
adbcConnection.close();

0 commit comments

Comments
 (0)