Skip to content

Commit 45265b0

Browse files
committed
Modified search strategy
1 parent 3ad1846 commit 45265b0

File tree

1 file changed

+36
-31
lines changed

1 file changed

+36
-31
lines changed

ebean-datasource/src/main/java/io/ebean/datasource/pool/PooledConnectionQueue.java

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,24 @@ void returnPooledConnection(PooledConnection c, boolean forceClose) {
158158
}
159159
}
160160

161-
private PooledConnection extractFromFreeList(Object affinitiyId) {
161+
/**
162+
* Tries to extract the best matching connection from the freeList.
163+
* If there is none, it tries to create one or steal one from other affinity slot.
164+
*/
165+
private PooledConnection extractFromFreeList(Object affinitiyId, boolean create) throws SQLException {
166+
PooledConnection c = extractFromFreeList(affinitiyId);
167+
if (c == null && create) {
168+
c = createConnection();
169+
}
170+
if (c == null && buffer.isAffinitySupported()) {
171+
// TODO: This "stealing" stragegy could be optimized.
172+
// we might build a heurestic, which one would be the best candidate
173+
c = extractFromFreeList(ConnectionBuffer.GET_LAST);
174+
}
175+
return c;
176+
}
162177

178+
private PooledConnection extractFromFreeList(Object affinitiyId) {
163179
PooledConnection c = buffer.removeFree(affinitiyId);
164180
if (c == null) {
165181
return null;
@@ -182,6 +198,21 @@ private boolean staleEviction(PooledConnection c) {
182198
return pool.invalidConnection(c);
183199
}
184200

201+
202+
private PooledConnection createConnection() throws SQLException {
203+
if (totalConnections() < maxSize) {
204+
// grow the connection pool
205+
PooledConnection c = pool.createConnectionForQueue(connectionId++);
206+
int busySize = registerBusyConnection(c);
207+
if (Log.isLoggable(DEBUG)) {
208+
Log.debug("DataSource [{0}] grow; id[{1}] busy[{2}] max[{3}]", name, c.name(), busySize, maxSize);
209+
}
210+
return c;
211+
} else {
212+
return null;
213+
}
214+
}
215+
185216
private boolean stale(PooledConnection c) {
186217
return c.lastUsedTime() < System.currentTimeMillis() - validateStaleMillis;
187218
}
@@ -225,13 +256,9 @@ private PooledConnection _obtainConnection(Object affinitiyId) throws Interrupte
225256
hitCount++;
226257
// are other threads already waiting? (they get priority)
227258
if (waitingThreads == 0) {
228-
PooledConnection connection = extractFromFreeList(affinitiyId);
229-
if (connection != null) {
230-
return connection;
231-
}
232-
connection = createConnection();
233-
if (connection != null) {
234-
return connection;
259+
PooledConnection c = this.extractFromFreeList(affinitiyId, true);
260+
if (c != null) {
261+
return c;
235262
}
236263
}
237264
try {
@@ -251,20 +278,6 @@ private PooledConnection _obtainConnection(Object affinitiyId) throws Interrupte
251278
}
252279
}
253280

254-
private PooledConnection createConnection() throws SQLException {
255-
if (totalConnections() < maxSize) {
256-
// grow the connection pool
257-
PooledConnection c = pool.createConnectionForQueue(connectionId++);
258-
int busySize = registerBusyConnection(c);
259-
if (Log.isLoggable(DEBUG)) {
260-
Log.debug("DataSource [{0}] grow; id[{1}] busy[{2}] max[{3}]", name, c.name(), busySize, maxSize);
261-
}
262-
return c;
263-
} else {
264-
return null;
265-
}
266-
}
267-
268281
/**
269282
* Got into a loop waiting for connections to be returned to the pool.
270283
*/
@@ -277,13 +290,6 @@ private PooledConnection _obtainConnectionWaitLoop(Object affinitiyId) throws SQ
277290
if (conn != null) {
278291
return conn;
279292
}
280-
// we could not create new connection, so we take the last one and change the affinity id
281-
if (buffer.isAffinitySupported()) {
282-
conn = extractFromFreeList(ConnectionBuffer.GET_LAST);
283-
}
284-
if (conn != null) {
285-
return conn;
286-
}
287293
String msg = "Unsuccessfully waited [" + waitTimeoutMillis + "] millis for a connection to be returned."
288294
+ " No connections are free. You need to Increase the max connections of [" + maxSize + "]"
289295
+ " or look for a connection pool leak using datasource.xxx.capturestacktrace=true";
@@ -296,8 +302,7 @@ private PooledConnection _obtainConnectionWaitLoop(Object affinitiyId) throws SQ
296302

297303
try {
298304
nanos = notEmpty.awaitNanos(nanos);
299-
PooledConnection c = extractFromFreeList(affinitiyId);
300-
305+
PooledConnection c = this.extractFromFreeList(affinitiyId, false);
301306
if (c != null) {
302307
// successfully waited
303308
return c;

0 commit comments

Comments
 (0)