SimplePool Migration Guide
This guide helps migrate from deprecated Http2Client connection pooling methods to the new SimplePool API.
Important
The old
borrowConnection/returnConnectionmethods are deprecated for removal. Migrate toborrow()/restore()for better pool management, metrics, and health checks.
Quick Reference
| Old API (Deprecated) | New API (SimplePool) |
|---|---|
borrowConnection(uri, worker, pool, isHttp2) | borrow(uri, worker, pool, isHttp2) |
returnConnection(connection) | restore(token) |
ClientConnection | ConnectionToken |
Key Difference: Token-Based Pool Management
The SimplePool uses a token pattern instead of raw connections:
// OLD: Returns ClientConnection directly
ClientConnection conn = client.borrowConnection(uri, worker, pool, true);
try {
// use connection
} finally {
client.returnConnection(conn);
}
// NEW: Returns ConnectionToken that wraps the connection
ConnectionToken token = client.borrow(uri, worker, pool, true);
try {
ClientConnection conn = token.connection().getRawConnection();
// use connection
} finally {
client.restore(token);
}
Why tokens? Tokens track which specific borrow operation acquired a connection, enabling:
- Accurate metrics (borrow/restore counts per URI)
- Leak detection
- Proper HTTP/2 multiplexing management
Migration Patterns
Pattern 1: Simple Borrow/Return (with .get)
Before:
ClientConnection connection = null;
try {
connection = client.borrowConnection(uri, worker, pool, options).get();
// Send request
connection.sendRequest(request, callback);
} finally {
if (connection != null) {
client.returnConnection(connection);
}
}
After:
import com.networknt.client.simplepool.SimpleConnectionState;
SimpleConnectionState.ConnectionToken token = null;
try {
token = client.borrow(uri, worker, pool, options);
ClientConnection connection = token.connection().getRawConnection();
// Send request
connection.sendRequest(request, callback);
} finally {
if (token != null) {
client.restore(token);
}
}
Pattern 2: With Timeout
The new borrow() method handles timeouts internally through configuration rather than as a method parameter.
Before:
// Note: The deprecated method took a timeout parameter (e.g., 10 seconds)
ClientConnection connection = client.borrowConnection(10, uri, worker, pool, options);
After:
// Note: timeout parameter is removed in the new API
ConnectionToken token = client.borrow(uri, worker, pool, options);
ClientConnection connection = token.connection().getRawConnection();
Pattern 3: Async (IoFuture)
Before:
IoFuture<ClientConnection> future = client.borrowConnection(uri, worker, pool, options);
Migration Rule:
The async IoFuture<ClientConnection> pattern cannot be directly migrated because the new borrow() method is synchronous. These usages should be migrated to a different async pattern or kept on the old API until fully deprecated.
Pattern 4: HTTP/1.1 vs HTTP/2
// HTTP/2 (multiplexed)
ConnectionToken token = client.borrow(uri, worker, bufferPool, true);
// HTTP/1.1 (non-multiplexed)
ConnectionToken token = client.borrow(uri, worker, bufferPool, false);
New Features After Migration
After migrating to SimplePool, you gain access to:
Pool Metrics
SimplePoolMetrics metrics = client.getPoolMetrics();
if (metrics != null) {
logger.info(metrics.getSummary());
}
Pool Warm-Up
// Pre-establish connections at startup
client.warmUpPool(URI.create("https://api.example.com:443"));
Health Checks
Enable in configuration:
client:
request:
healthCheckEnabled: true
healthCheckIntervalMs: 30000
Configuration
Enable SimplePool features in client.yml:
client:
request:
# Pool sizing
connectionPoolSize: 10
connectionExpireTime: 1800000
# Metrics (default: false)
poolMetricsEnabled: true
# Warm-up (default: false)
poolWarmUpEnabled: true
poolWarmUpSize: 2
# Health checks (default: true)
healthCheckEnabled: true
healthCheckIntervalMs: 30000
Backward Compatibility
During the transition period:
- Deprecated methods internally redirect to SimplePool when possible
- Old pool (
Http2ClientConnectionPool) is still available as fallback - Both pools can coexist during migration
AI Migration Instructions
For automated migration tools and AI assistants, use these patterns:
SEARCH_PATTERN: borrowConnection call
\bclient\.borrowConnection\s*\([^)]*\)
REPLACE_PATTERN: Convert to borrow
- Change method name from
borrowConnectiontoborrow - Change return type from
ClientConnectiontoConnectionToken - Extract connection:
token.connection().getRawConnection() - Change
returnConnection(connection)torestore(token)
SEARCH_PATTERN: returnConnection call
\bclient\.returnConnection\s*\(\s*(\w+)\s*\)
REPLACE_PATTERN: Convert to restore
client.restore($1Token)
where $1Token is the corresponding token variable.
VARIABLE_RENAME
connection→tokenconn→token- Add
.connection().getRawConnection()when accessing the raw connection
IMPORT_CHANGES
Add:
import com.networknt.client.simplepool.SimpleConnectionState;
Troubleshooting
Connection Not Returned to Pool
Symptom: Pool exhaustion, connections not being reused
Cause: restore() not called in finally block
Fix: Always use try-finally:
ConnectionToken token = null;
try {
token = client.borrow(...);
// use connection
} finally {
if (token != null) client.restore(token);
}
Cannot find symbol ConnectionToken
Symptom: Compilation error stating Cannot find symbol class ConnectionToken.
Cause: Missing import for SimpleConnectionState.
Fix: Add the required import:
import com.networknt.client.simplepool.SimpleConnectionState;
getRawConnection() returns null
Symptom: NullPointerException or unexpected behavior because token.connection().getRawConnection() returns null.
Cause: The connection has not been properly established yet.
Fix: Check token.connection().isOpen() before attempting to use the raw connection:
if (token.connection().isOpen()) {
ClientConnection connection = token.connection().getRawConnection();
// use connection
}
Metrics Show Zero
Cause: Metrics not enabled
Fix: Add to configuration:
client:
request:
poolMetricsEnabled: true