Skip to content

Commit b9ca302

Browse files
Flossyclaude
andcommitted
Document connection pooling recommendations (#19)
Add comprehensive documentation for connection management and pooling best practices. Changes: - DatabaseClassSource: Add connection pooling documentation - Recommend using pooled DataSource (HikariCP, Apache DBCP) - Document performance impact (200 connections vs 10 pooled) - Provide HikariCP configuration example - Explain connection overhead for production use - SftpClassSource: Document connection reuse and concurrency - Explain single connection reuse across loads - Document synchronized bottleneck for concurrent access - Provide lifecycle examples with try-with-resources - Note limitation for high-concurrency scenarios This addresses #19 by guiding users to proper connection management without adding complex pooling dependencies. Fixes #19 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent c9d1045 commit b9ca302

2 files changed

Lines changed: 64 additions & 0 deletions

File tree

src/main/java/org/flossware/jclassloader/DatabaseClassSource.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,41 @@
1111
/**
1212
* ClassSource implementation for loading classes from a JDBC database.
1313
* Class bytecode is stored in a table with columns for class name and class bytes.
14+
*
15+
* <h2>Performance: Connection Pooling</h2>
16+
* <p><b>IMPORTANT:</b> This class creates a new database connection for every class load operation.
17+
* For production use, always provide a pooled DataSource (HikariCP, Apache DBCP, etc.) to avoid
18+
* connection overhead and resource exhaustion.</p>
19+
*
20+
* <h3>Recommended Setup (HikariCP)</h3>
21+
* <pre>{@code
22+
* // Create a connection pool
23+
* HikariConfig config = new HikariConfig();
24+
* config.setJdbcUrl("jdbc:postgresql://localhost/classes");
25+
* config.setUsername("user");
26+
* config.setPassword("password");
27+
* config.setMaximumPoolSize(10);
28+
* config.setMinimumIdle(2);
29+
* config.setConnectionTimeout(30000);
30+
*
31+
* DataSource pooledDataSource = new HikariDataSource(config);
32+
*
33+
* // Pass the pooled DataSource to DatabaseClassSource
34+
* DatabaseClassSource source = new DatabaseClassSource(
35+
* pooledDataSource, // Reuses connections from pool
36+
* "class_table",
37+
* "class_name",
38+
* "class_bytes"
39+
* );
40+
* }</pre>
41+
*
42+
* <h3>Performance Impact</h3>
43+
* <ul>
44+
* <li><b>Without pooling:</b> Loading 100 classes = ~200 new connections (slow)</li>
45+
* <li><b>With pooling:</b> Loading 100 classes = reuses 10 pooled connections (fast)</li>
46+
* </ul>
47+
*
48+
* @see javax.sql.DataSource
1449
*/
1550
public class DatabaseClassSource implements ClassSource {
1651
private final DataSource dataSource;

src/main/java/org/flossware/jclassloader/SftpClassSource.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,35 @@
1919
* Supports both password and private key authentication with retry logic.
2020
* Requires the JSch library dependency.
2121
* Implements AutoCloseable for proper resource management - call close() when done.
22+
*
23+
* <h2>Connection Management</h2>
24+
* <p>This class reuses a single SFTP connection across multiple class loads for efficiency.
25+
* The connection is established on first use and maintained until close() is called.</p>
26+
*
27+
* <h3>Concurrency Limitation</h3>
28+
* <p><b>NOTE:</b> Connection establishment is synchronized, which creates a bottleneck for
29+
* concurrent access. All threads share the same SFTP channel. For high-concurrency scenarios,
30+
* consider creating multiple SftpClassSource instances or using a different protocol.</p>
31+
*
32+
* <h3>Connection Lifecycle</h3>
33+
* <pre>{@code
34+
* try (SftpClassSource source = SftpClassSource.builder()
35+
* .host("sftp.example.com")
36+
* .username("deploy")
37+
* .password("secret")
38+
* .build()) {
39+
*
40+
* // Connection established on first load
41+
* byte[] class1 = source.loadClassData("com.example.Class1");
42+
*
43+
* // Reuses existing connection (fast)
44+
* byte[] class2 = source.loadClassData("com.example.Class2");
45+
*
46+
* } // Connection closed automatically
47+
* }</pre>
48+
*
49+
* @see #close()
50+
* @see #disconnect()
2251
*/
2352
public class SftpClassSource implements ClassSource, AutoCloseable {
2453
private static final int DEFAULT_SESSION_TIMEOUT_MS = 30000;

0 commit comments

Comments
 (0)