Skip to content

Commit b0ce429

Browse files
committed
Move leaked session switch to config
It was previously in system property. This commit makes it part of `Config` so we have a single place with all configuration parameters.
1 parent 5a4c9e2 commit b0ce429

File tree

7 files changed

+95
-12
lines changed

7 files changed

+95
-12
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ ConnectionPool createConnectionPool( AuthToken authToken, SecurityPlan securityP
129129

130130
private static SessionFactory createSessionFactory( Config config )
131131
{
132-
if ( LeakLoggingNetworkSessionFactory.leakLoggingEnabled() )
132+
if ( config.logLeakedSessions() )
133133
{
134134
return new LeakLoggingNetworkSessionFactory( config.logging() );
135135
}

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

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,24 +23,17 @@
2323
import org.neo4j.driver.v1.Logging;
2424
import org.neo4j.driver.v1.Session;
2525

26-
public class LeakLoggingNetworkSessionFactory implements SessionFactory
26+
class LeakLoggingNetworkSessionFactory implements SessionFactory
2727
{
28-
private static final String SYSTEM_PROPERTY_NAME = "org.neo4j.driver.logSessionLeaks";
2928
private static final String LOGGER_NAME = "sessionLeak";
3029

3130
private final Logger logger;
3231

33-
public LeakLoggingNetworkSessionFactory( Logging logging )
32+
LeakLoggingNetworkSessionFactory( Logging logging )
3433
{
3534
this.logger = logging.getLog( LOGGER_NAME );
3635
}
3736

38-
public static boolean leakLoggingEnabled()
39-
{
40-
String value = System.getProperty( SYSTEM_PROPERTY_NAME );
41-
return Boolean.parseBoolean( value );
42-
}
43-
4437
@Override
4538
public Session newInstance( Connection connection )
4639
{

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import org.neo4j.driver.internal.spi.Connection;
2222
import org.neo4j.driver.v1.Session;
2323

24-
public class NetworkSessionFactory implements SessionFactory
24+
class NetworkSessionFactory implements SessionFactory
2525
{
2626
@Override
2727
public Session newInstance( Connection connection )

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import org.neo4j.driver.internal.spi.Connection;
2222
import org.neo4j.driver.v1.Session;
2323

24-
public interface SessionFactory
24+
interface SessionFactory
2525
{
2626
Session newInstance( Connection connection );
2727
}

driver/src/main/java/org/neo4j/driver/v1/Config.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.neo4j.driver.internal.logging.JULogging;
2727
import org.neo4j.driver.internal.net.pooling.PoolSettings;
2828
import org.neo4j.driver.v1.util.Immutable;
29+
import org.neo4j.driver.v1.util.Resource;
2930

3031
import static org.neo4j.driver.v1.Config.TrustStrategy.trustAllCertificates;
3132

@@ -48,6 +49,7 @@ public class Config
4849
{
4950
/** User defined logging */
5051
private final Logging logging;
52+
private final boolean logLeakedSessions;
5153

5254
private final int maxIdleConnectionPoolSize;
5355

@@ -63,6 +65,7 @@ public class Config
6365
private Config( ConfigBuilder builder)
6466
{
6567
this.logging = builder.logging;
68+
this.logLeakedSessions = builder.logLeakedSessions;
6669

6770
this.maxIdleConnectionPoolSize = builder.maxIdleConnectionPoolSize;
6871

@@ -81,6 +84,16 @@ public Logging logging()
8184
return logging;
8285
}
8386

87+
/**
88+
* Check if leaked sessions logging is enabled.
89+
*
90+
* @return {@code true} if enabled, {@code false} otherwise.
91+
*/
92+
public boolean logLeakedSessions()
93+
{
94+
return logLeakedSessions;
95+
}
96+
8497
/**
8598
* Max number of connections per URL for this driver.
8699
* @return the max number of connections
@@ -158,6 +171,7 @@ RoutingSettings routingSettings()
158171
public static class ConfigBuilder
159172
{
160173
private Logging logging = new JULogging( Level.INFO );
174+
private boolean logLeakedSessions;
161175
private int maxIdleConnectionPoolSize = PoolSettings.DEFAULT_MAX_IDLE_CONNECTION_POOL_SIZE;
162176
private EncryptionLevel encryptionLevel = EncryptionLevel.REQUIRED;
163177
private TrustStrategy trustStrategy = trustAllCertificates();
@@ -178,6 +192,27 @@ public ConfigBuilder withLogging( Logging logging )
178192
return this;
179193
}
180194

195+
/**
196+
* Enable logging of leaked sessions.
197+
* <p>
198+
* Each {@link Session session} is associated with a network connection and thus is a
199+
* {@link Resource resource} that needs to be explicitly closed. Unclosed sessions will result in socket
200+
* leaks and could cause {@link OutOfMemoryError}s.
201+
* <p>
202+
* Session is considered to be leaked when it is finalized via {@link Object#finalize()} while not being
203+
* closed. This option turns on logging of such sessions and stacktraces of where they were created.
204+
* <p>
205+
* <b>Note:</b> this option should mostly be used in testing environments for session leak investigations.
206+
* Enabling it will add object finalization overhead.
207+
*
208+
* @return this builder
209+
*/
210+
public ConfigBuilder withLeakedSessionsLogging()
211+
{
212+
this.logLeakedSessions = true;
213+
return this;
214+
}
215+
181216
/**
182217
* The max number of sessions to keep open at once. Configure this
183218
* higher if you want more concurrent sessions, or lower if you want

driver/src/test/java/org/neo4j/driver/internal/ConfigTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727

2828
import static java.lang.System.getProperty;
2929
import static org.junit.Assert.assertEquals;
30+
import static org.junit.Assert.assertFalse;
31+
import static org.junit.Assert.assertTrue;
3032

3133
public class ConfigTest
3234
{
@@ -86,6 +88,16 @@ public void shouldIgnoreLivenessCheckTimeoutSetting() throws Throwable
8688
assertEquals( -1, config.idleTimeBeforeConnectionTest() );
8789
}
8890

91+
@Test
92+
public void shouldTurnOnLeakedSessionsLogging()
93+
{
94+
// leaked sessions logging is turned off by default
95+
assertFalse( Config.build().toConfig().logLeakedSessions() );
96+
97+
// it can be turned on using config
98+
assertTrue( Config.build().withLeakedSessionsLogging().toConfig().logLeakedSessions() );
99+
}
100+
89101
public static void deleteDefaultKnownCertFileIfExists()
90102
{
91103
if( DEFAULT_KNOWN_HOSTS.exists() )

driver/src/test/java/org/neo4j/driver/internal/DriverFactoryTest.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,28 @@ public void connectionPoolCloseExceptionIsSupressedWhenDriverCreationFails() thr
100100
verify( connectionPool ).close();
101101
}
102102

103+
@Test
104+
public void usesStandardSessionFactoryWhenNothingConfigured()
105+
{
106+
Config config = Config.defaultConfig();
107+
SessionFactoryCapturingDriverFactory factory = new SessionFactoryCapturingDriverFactory();
108+
109+
factory.newInstance( uri, dummyAuthToken(), dummyRoutingSettings(), config );
110+
111+
assertThat( factory.capturedSessionFactory, instanceOf( NetworkSessionFactory.class ) );
112+
}
113+
114+
@Test
115+
public void usesLeakLoggingSessionFactoryWhenConfigured()
116+
{
117+
Config config = Config.build().withLeakedSessionsLogging().toConfig();
118+
SessionFactoryCapturingDriverFactory factory = new SessionFactoryCapturingDriverFactory();
119+
120+
factory.newInstance( uri, dummyAuthToken(), dummyRoutingSettings(), config );
121+
122+
assertThat( factory.capturedSessionFactory, instanceOf( LeakLoggingNetworkSessionFactory.class ) );
123+
}
124+
103125
private static AuthToken dummyAuthToken()
104126
{
105127
return AuthTokens.basic( "neo4j", "neo4j" );
@@ -139,4 +161,25 @@ ConnectionPool createConnectionPool( AuthToken authToken, SecurityPlan securityP
139161
return connectionPool;
140162
}
141163
}
164+
165+
private static class SessionFactoryCapturingDriverFactory extends DriverFactory
166+
{
167+
SessionFactory capturedSessionFactory;
168+
169+
@Override
170+
DirectDriver createDirectDriver( BoltServerAddress address, ConnectionPool connectionPool, Config config,
171+
SecurityPlan securityPlan, SessionFactory sessionFactory )
172+
{
173+
capturedSessionFactory = sessionFactory;
174+
return null;
175+
}
176+
177+
@Override
178+
RoutingDriver createRoutingDriver( BoltServerAddress address, ConnectionPool connectionPool, Config config,
179+
RoutingSettings routingSettings, SecurityPlan securityPlan, SessionFactory sessionFactory )
180+
{
181+
capturedSessionFactory = sessionFactory;
182+
return null;
183+
}
184+
}
142185
}

0 commit comments

Comments
 (0)