Skip to content

Commit c888264

Browse files
committed
Pool getResource block when exhausted.
1 parent 2307a9c commit c888264

3 files changed

Lines changed: 39 additions & 10 deletions

File tree

core/src/main/java/me/zort/sqllib/SQLConnectionBuilder.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ public SQLConnectionBuilder(@Nullable SQLEndpoint endpoint) {
6666
}
6767

6868
public @NotNull SQLConnectionBuilder withParam(String key, String value) {
69-
Optional.ofNullable(endpoint).ifPresent(endpoint -> {
70-
jdbc += (jdbc.contains("?") ? "&" : "?");
71-
jdbc += key + "=" + value;
72-
});
69+
if (endpoint != null) {
70+
jdbc += (jdbc.contains("?") ? "&" : "?");
71+
jdbc += key + "=" + value;
72+
}
7373
return this;
7474
}
7575

core/src/main/java/me/zort/sqllib/SQLConnectionPool.java

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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.

core/src/main/java/me/zort/sqllib/SQLDatabaseConnection.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ public boolean connect() {
160160

161161
try {
162162
connection = connectionFactory.connect();
163+
lastError = null;
163164
} catch (SQLException e) {
164165
logSqlError(e);
165166
connection = null;
@@ -173,6 +174,7 @@ public void disconnect() {
173174
if(isConnected()) {
174175
try {
175176
connection.close();
177+
lastError = null;
176178
} catch (SQLException e) {
177179
logSqlError(e);
178180
lastError = e;

0 commit comments

Comments
 (0)