Skip to content

Commit 5de9312

Browse files
author
Zhen Li
authored
Merge pull request #285 from lutovich/1.1-remove-finalize
Removed finalize from NetworkSession
2 parents 45e3623 + b0ce429 commit 5de9312

16 files changed

+469
-31
lines changed

driver/src/main/java/org/neo4j/driver/internal/BaseDriver.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,15 @@ abstract class BaseDriver implements Driver
3232
private final static String DRIVER_LOG_NAME = "Driver";
3333

3434
private final SecurityPlan securityPlan;
35+
protected final SessionFactory sessionFactory;
3536
protected final Logger log;
3637

3738
private AtomicBoolean closed = new AtomicBoolean( false );
3839

39-
BaseDriver( SecurityPlan securityPlan, Logging logging )
40+
BaseDriver( SecurityPlan securityPlan, SessionFactory sessionFactory, Logging logging )
4041
{
4142
this.securityPlan = securityPlan;
43+
this.sessionFactory = sessionFactory;
4244
this.log = logging.getLog( DRIVER_LOG_NAME );
4345
}
4446

driver/src/main/java/org/neo4j/driver/internal/DirectDriver.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,18 @@ public DirectDriver(
3636
BoltServerAddress address,
3737
ConnectionPool connections,
3838
SecurityPlan securityPlan,
39+
SessionFactory sessionFactory,
3940
Logging logging )
4041
{
41-
super( securityPlan, logging );
42+
super( securityPlan, sessionFactory, logging );
4243
this.address = address;
4344
this.connections = connections;
4445
}
4546

4647
@Override
4748
protected Session newSessionWithMode( AccessMode mode )
4849
{
49-
return new NetworkSession( connections.acquire( address ) );
50+
return sessionFactory.newInstance( connections.acquire( address ) );
5051
}
5152

5253
@Override

driver/src/main/java/org/neo4j/driver/internal/DriverFactory.java

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,13 @@ public final Driver newInstance( URI uri, AuthToken authToken, RoutingSettings r
4949
BoltServerAddress address = BoltServerAddress.from( uri );
5050
SecurityPlan securityPlan = createSecurityPlan( address, config );
5151
ConnectionPool connectionPool = createConnectionPool( authToken, securityPlan, config );
52+
SessionFactory sessionFactory = createSessionFactory( config );
5253

5354
try
5455
{
55-
return createDriver( address, uri.getScheme(), connectionPool, config, routingSettings, securityPlan );
56+
return createDriver( address, uri.getScheme(), connectionPool, config, routingSettings, securityPlan,
57+
sessionFactory
58+
);
5659
}
5760
catch ( Throwable driverError )
5861
{
@@ -70,14 +73,16 @@ public final Driver newInstance( URI uri, AuthToken authToken, RoutingSettings r
7073
}
7174

7275
private Driver createDriver( BoltServerAddress address, String scheme, ConnectionPool connectionPool,
73-
Config config, RoutingSettings routingSettings, SecurityPlan securityPlan )
76+
Config config, RoutingSettings routingSettings, SecurityPlan securityPlan,
77+
SessionFactory sessionFactory )
7478
{
7579
switch ( scheme.toLowerCase() )
7680
{
7781
case "bolt":
78-
return createDirectDriver( address, connectionPool, config, securityPlan );
82+
return createDirectDriver( address, connectionPool, config, securityPlan, sessionFactory );
7983
case "bolt+routing":
80-
return createRoutingDriver( address, connectionPool, config, routingSettings, securityPlan );
84+
return createRoutingDriver( address, connectionPool, config, routingSettings, securityPlan,
85+
sessionFactory );
8186
default:
8287
throw new ClientException( format( "Unsupported URI scheme: %s", scheme ) );
8388
}
@@ -89,21 +94,21 @@ private Driver createDriver( BoltServerAddress address, String scheme, Connectio
8994
* <b>This method is package-private only for testing</b>
9095
*/
9196
DirectDriver createDirectDriver( BoltServerAddress address, ConnectionPool connectionPool, Config config,
92-
SecurityPlan securityPlan )
97+
SecurityPlan securityPlan, SessionFactory sessionFactory )
9398
{
94-
return new DirectDriver( address, connectionPool, securityPlan, config.logging() );
99+
return new DirectDriver( address, connectionPool, securityPlan, sessionFactory, config.logging() );
95100
}
96101

97102
/**
98103
* Creates new {@link RoutingDriver}.
99104
* <p>
100105
* <b>This method is package-private only for testing</b>
101106
*/
102-
RoutingDriver createRoutingDriver( BoltServerAddress address, ConnectionPool connectionPool,
103-
Config config, RoutingSettings routingSettings, SecurityPlan securityPlan )
107+
RoutingDriver createRoutingDriver( BoltServerAddress address, ConnectionPool connectionPool, Config config,
108+
RoutingSettings routingSettings, SecurityPlan securityPlan, SessionFactory sessionFactory )
104109
{
105-
return new RoutingDriver( routingSettings, address, connectionPool, securityPlan, Clock.SYSTEM,
106-
config.logging() );
110+
return new RoutingDriver( routingSettings, address, connectionPool, securityPlan, sessionFactory,
111+
Clock.SYSTEM, config.logging() );
107112
}
108113

109114
/**
@@ -122,6 +127,15 @@ ConnectionPool createConnectionPool( AuthToken authToken, SecurityPlan securityP
122127
return new SocketConnectionPool( poolSettings, connector, Clock.SYSTEM, config.logging() );
123128
}
124129

130+
private static SessionFactory createSessionFactory( Config config )
131+
{
132+
if ( config.logLeakedSessions() )
133+
{
134+
return new LeakLoggingNetworkSessionFactory( config.logging() );
135+
}
136+
return new NetworkSessionFactory();
137+
}
138+
125139
private static SecurityPlan createSecurityPlan( BoltServerAddress address, Config config )
126140
{
127141
try
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright (c) 2002-2016 "Neo Technology,"
3+
* Network Engine for Objects in Lund AB [http://neotechnology.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver.internal;
20+
21+
import org.neo4j.driver.internal.spi.Connection;
22+
import org.neo4j.driver.v1.Logger;
23+
24+
import static java.lang.System.lineSeparator;
25+
26+
class LeakLoggingNetworkSession extends NetworkSession
27+
{
28+
private final Logger log;
29+
private final String stackTrace;
30+
31+
LeakLoggingNetworkSession( Connection connection, Logger log )
32+
{
33+
super( connection );
34+
this.log = log;
35+
this.stackTrace = captureStackTrace();
36+
}
37+
38+
@Override
39+
protected void finalize() throws Throwable
40+
{
41+
logLeakIfNeeded();
42+
super.finalize();
43+
}
44+
45+
private void logLeakIfNeeded()
46+
{
47+
if ( isOpen() )
48+
{
49+
log.error( "Neo4j Session object leaked, please ensure that your application" +
50+
"calls the `close` method on Sessions before disposing of the objects.\n" +
51+
"Session was create at:\n" + stackTrace, null );
52+
}
53+
}
54+
55+
private static String captureStackTrace()
56+
{
57+
StringBuilder result = new StringBuilder();
58+
StackTraceElement[] elements = Thread.currentThread().getStackTrace();
59+
for ( StackTraceElement element : elements )
60+
{
61+
result.append( "\t" ).append( element ).append( lineSeparator() );
62+
}
63+
return result.toString();
64+
}
65+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (c) 2002-2016 "Neo Technology,"
3+
* Network Engine for Objects in Lund AB [http://neotechnology.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver.internal;
20+
21+
import org.neo4j.driver.internal.spi.Connection;
22+
import org.neo4j.driver.v1.Logger;
23+
import org.neo4j.driver.v1.Logging;
24+
import org.neo4j.driver.v1.Session;
25+
26+
class LeakLoggingNetworkSessionFactory implements SessionFactory
27+
{
28+
private static final String LOGGER_NAME = "sessionLeak";
29+
30+
private final Logger logger;
31+
32+
LeakLoggingNetworkSessionFactory( Logging logging )
33+
{
34+
this.logger = logging.getLog( LOGGER_NAME );
35+
}
36+
37+
@Override
38+
public Session newInstance( Connection connection )
39+
{
40+
return new LeakLoggingNetworkSession( connection, logger );
41+
}
42+
}

driver/src/main/java/org/neo4j/driver/internal/NetworkSession.java

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public void run()
6767
private ExplicitTransaction currentTransaction;
6868
private AtomicBoolean isOpen = new AtomicBoolean( true );
6969

70-
public NetworkSession( Connection connection )
70+
NetworkSession( Connection connection )
7171
{
7272
this.connection = connection;
7373

@@ -126,6 +126,7 @@ public static StatementResult run( Connection connection, Statement statement )
126126
return cursor;
127127
}
128128

129+
@Override
129130
public synchronized void reset()
130131
{
131132
ensureSessionIsOpen();
@@ -255,18 +256,6 @@ private void ensureConnectionIsValidBeforeOpeningTransaction()
255256
ensureConnectionIsOpen();
256257
}
257258

258-
@Override
259-
protected void finalize() throws Throwable
260-
{
261-
if ( isOpen.compareAndSet( true, false ) )
262-
{
263-
logger.error( "Neo4j Session object leaked, please ensure that your application calls the `close` " +
264-
"method on Sessions before disposing of the objects.", null );
265-
connection.close();
266-
}
267-
super.finalize();
268-
}
269-
270259
private void ensureNoUnrecoverableError()
271260
{
272261
if ( connection.hasUnrecoverableErrors() )
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright (c) 2002-2016 "Neo Technology,"
3+
* Network Engine for Objects in Lund AB [http://neotechnology.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver.internal;
20+
21+
import org.neo4j.driver.internal.spi.Connection;
22+
import org.neo4j.driver.v1.Session;
23+
24+
class NetworkSessionFactory implements SessionFactory
25+
{
26+
@Override
27+
public Session newInstance( Connection connection )
28+
{
29+
return new NetworkSession( connection );
30+
}
31+
}

driver/src/main/java/org/neo4j/driver/internal/RoutingDriver.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,19 @@ public RoutingDriver(
5151
BoltServerAddress seedAddress,
5252
ConnectionPool connections,
5353
SecurityPlan securityPlan,
54+
SessionFactory sessionFactory,
5455
Clock clock,
5556
Logging logging )
5657
{
57-
super( verifiedSecurityPlan( securityPlan ), logging );
58+
super( verifiedSecurityPlan( securityPlan ), sessionFactory, logging );
5859
this.loadBalancer = new LoadBalancer( settings, clock, log, connections, seedAddress );
5960
}
6061

6162
@Override
6263
protected Session newSessionWithMode( AccessMode mode )
6364
{
6465
Connection connection = acquireConnection( mode );
65-
NetworkSession networkSession = new NetworkSession( connection );
66+
Session networkSession = sessionFactory.newInstance( connection );
6667
return new RoutingNetworkSession( networkSession, mode, connection.boltServerAddress(), loadBalancer );
6768
}
6869

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (c) 2002-2016 "Neo Technology,"
3+
* Network Engine for Objects in Lund AB [http://neotechnology.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver.internal;
20+
21+
import org.neo4j.driver.internal.spi.Connection;
22+
import org.neo4j.driver.v1.Session;
23+
24+
interface SessionFactory
25+
{
26+
Session newInstance( Connection connection );
27+
}

0 commit comments

Comments
 (0)