Skip to content

Close all connections on driver.close() #252

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 24, 2016

Conversation

pontusmelke
Copy link
Contributor

Connections/Sessions that were in flight, i.e. acquired from the pool, were not
closed when shutting down the driver, connections remained open until GC
happened. The expected behavior is that driver.close() closes down all
sessions it has created.

*/
public boolean offer( PooledConnection pooledConnection )
{
boolean offer = queue.offer( pooledConnection );
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it necessary to synchronize here, i.e. making the move from queue to acquiredConnections atomic? It feels like you should but I am failing to come up with a scenario where it matters, so I opted for less synchronization.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The order should be first remove from acquiredConn, then put back to queue to avid the following scenario happening:
T1: queue.offer(connA)
T2: acquire() -> get connA // connA = queue.poll, acquiredConn.Add(connA)
T1: acquiredConn.remove(connA)

NOTE: Remove first, then add back. This rule applies to acquire too

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, whenever you add into the queue/acquiredConn, you probably want to test if the pool already terminated. if it is already terminated, then drop the conn directly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ref: https://github.com/neo4j/neo4j-dotnet-driver/blob/1.1/Neo4j.Driver/Neo4j.Driver/Internal/ConnectionPool.cs
We used lock because we do not have a concurrent container before. We probably could have a lock free impl for java driver

@pontusmelke pontusmelke force-pushed the 1.1-close-conn-on-driver-close branch 3 times, most recently from 2cd6bec to d2239b8 Compare October 20, 2016 12:51
Connections/Sessions that were in flight, i.e. acquired from the pool, were not
closed when shutting down the driver, connections remained open until GC
happened. The expected behavior is that `driver.close()` closes down all
sessions it has created.
@pontusmelke pontusmelke force-pushed the 1.1-close-conn-on-driver-close branch from d2239b8 to 8cfe635 Compare October 20, 2016 13:23
*/
public boolean offer( PooledConnection pooledConnection )
{
boolean offer = queue.offer( pooledConnection );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The order should be first remove from acquiredConn, then put back to queue to avid the following scenario happening:
T1: queue.offer(connA)
T2: acquire() -> get connA // connA = queue.poll, acquiredConn.Add(connA)
T1: acquiredConn.remove(connA)

NOTE: Remove first, then add back. This rule applies to acquire too

*/
public boolean offer( PooledConnection pooledConnection )
{
boolean offer = queue.offer( pooledConnection );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, whenever you add into the queue/acquiredConn, you probably want to test if the pool already terminated. if it is already terminated, then drop the conn directly.

* Terminates all connections, both those that are currently in the queue as well
* as those that have been acquired.
*/
public void terminate()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You probably want a atomic var here at the very beginning of the method, to flag it that we've started termination. If any connection created after this, close it right now. If any connection want to add to the queue or map, drop them directly.

@@ -139,7 +139,7 @@ public synchronized void reset()
@Override
public boolean isOpen()
{
return isOpen.get();
return isOpen.get() && connection.isOpen();
Copy link
Contributor

@zhenlineo zhenlineo Oct 21, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if we should add connection.isOpen test here. Though it is handle, however this method before is just to test if session.close is ever called. If you want to change this to if this session could run more queries or something else, then make sure that other methods who calling this isOpen is not broken.

*/
public boolean offer( PooledConnection pooledConnection )
{
boolean offer = queue.offer( pooledConnection );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ref: https://github.com/neo4j/neo4j-dotnet-driver/blob/1.1/Neo4j.Driver/Neo4j.Driver/Internal/ConnectionPool.cs
We used lock because we do not have a concurrent container before. We probably could have a lock free impl for java driver

@pontusmelke pontusmelke force-pushed the 1.1-close-conn-on-driver-close branch from 22762d2 to 8faa0fd Compare October 24, 2016 09:17
@pontusmelke pontusmelke force-pushed the 1.1-close-conn-on-driver-close branch from 8faa0fd to f7c4c18 Compare October 24, 2016 09:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants