Skip to content

Commit 2729d5b

Browse files
committed
Resolve issue where pooled connections could leak if exception occurred
during close. - close in PooledConnection calls reset and then returns the session to the pool. However, returning the session was not in a finally clause, so reset throwing an exception would leak the connection, eventually draining the pool from available sessions.
1 parent 12dfe1a commit 2729d5b

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

driver/src/main/java/org/neo4j/driver/internal/pool/PooledConnection.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,15 @@ public void close()
156156
{
157157
reset( StreamCollector.NO_OP );
158158
sync();
159-
release.accept( this );
160159
}
161160
catch (Exception ex)
162161
{
163162
dispose();
164163
}
164+
finally
165+
{
166+
release.accept( this );
167+
}
165168
}
166169

167170
@Override
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package org.neo4j.driver.internal.pool;
2+
3+
import org.junit.Test;
4+
5+
import java.util.LinkedList;
6+
7+
import org.neo4j.driver.internal.spi.Connection;
8+
import org.neo4j.driver.internal.spi.StreamCollector;
9+
import org.neo4j.driver.internal.util.Consumer;
10+
import org.neo4j.driver.v1.exceptions.DatabaseException;
11+
12+
import static org.hamcrest.CoreMatchers.equalTo;
13+
import static org.hamcrest.CoreMatchers.hasItem;
14+
import static org.hamcrest.MatcherAssert.assertThat;
15+
import static org.mockito.Matchers.any;
16+
import static org.mockito.Mockito.doThrow;
17+
import static org.mockito.Mockito.mock;
18+
19+
public class PooledConnectionTest
20+
{
21+
@Test
22+
public void shouldReturnToPoolIfExceptionDuringReset() throws Throwable
23+
{
24+
// Given
25+
final LinkedList<PooledConnection> returnedToPool = new LinkedList<>();
26+
Connection conn = mock( Connection.class );
27+
28+
doThrow( new DatabaseException( "asd", "asd" ) ).when(conn).reset( any( StreamCollector.class) );
29+
30+
PooledConnection pooledConnection = new PooledConnection( conn, new Consumer<PooledConnection>()
31+
{
32+
@Override
33+
public void accept( PooledConnection pooledConnection )
34+
{
35+
returnedToPool.add( pooledConnection );
36+
}
37+
} );
38+
39+
// When
40+
pooledConnection.close();
41+
42+
// Then
43+
assertThat( returnedToPool, hasItem(pooledConnection) );
44+
assertThat( returnedToPool.size(), equalTo( 1 ));
45+
}
46+
}

0 commit comments

Comments
 (0)