@@ -25,11 +25,18 @@ public final class SQLConnectionPool {
2525
2626 @ Data
2727 public static final class Options {
28+ // Max number of connections in the pool
2829 private int maxConnections = 10 ;
30+ // Max wait time for getResource in milliseconds when the pool is exhausted
31+ private long borrowObjectTimeout = 5000L ;
32+ // Block or throw an exception when the pool is exhausted
33+ private boolean blockWhenExhausted = true ;
2934 }
3035
3136 private final SQLConnectionBuilder builder ;
3237 private final int maxConnections ;
38+ private final long borrowObjectTimeout ;
39+ private final boolean blockWhenExhausted ;
3340
3441 // --***-- Pooled connection caches --***--
3542 private final Queue <SQLPooledConnection > freeConnections = new ConcurrentLinkedQueue <>();
@@ -49,6 +56,8 @@ public SQLConnectionPool(@NotNull SQLConnectionBuilder from) {
4956 public SQLConnectionPool (@ NotNull SQLConnectionBuilder from , @ NotNull Options poolOptions ) {
5057 this .builder = from ;
5158 this .maxConnections = poolOptions .maxConnections ;
59+ this .borrowObjectTimeout = poolOptions .borrowObjectTimeout ;
60+ this .blockWhenExhausted = poolOptions .blockWhenExhausted ;
5261 }
5362
5463 /**
@@ -63,18 +72,36 @@ public Resource getResource() throws SQLException {
6372 freeConnections .removeIf (SQLPooledConnection ::expired );
6473 SQLPooledConnection polled = freeConnections .poll ();
6574 if (polled == null && usedConnections .size () < maxConnections ) {
66- polled = new SQLPooledConnection (builder .build ());
67- polled .connection .connect ();
68-
69- SQLException error = polled .connection .getLastError ();
70- if (error != null ) throw error ;
75+ polled = establishObject ();
7176 } else if (polled == null ) {
72- throw new IllegalStateException ("Connection limit reached!" );
77+
78+ if (!blockWhenExhausted ) {
79+ throw new SQLException ("No connections available." );
80+ }
81+
82+ long start = System .currentTimeMillis ();
83+ while ((polled = freeConnections .poll ()) == null ) {
84+ if (System .currentTimeMillis () - start > borrowObjectTimeout ) {
85+ throw new SQLException ("Timeout while waiting for a connection." );
86+ } else if (usedConnections .size () < maxConnections ) {
87+ polled = establishObject ();
88+ break ;
89+ }
90+ }
7391 }
7492 usedConnections .add (polled );
7593 return new Resource (this , polled );
7694 }
7795
96+ private SQLPooledConnection establishObject () throws SQLException {
97+ SQLPooledConnection polled = new SQLPooledConnection (builder .build ());
98+ polled .connection .connect ();
99+
100+ SQLException error = polled .connection .getLastError ();
101+ if (error != null ) throw error ;
102+ return polled ;
103+ }
104+
78105 /**
79106 * Closes all connections in the pool and
80107 * clears the caches.
0 commit comments