Skip to content

Commit f7ceaa2

Browse files
committed
Create less direct drivers in CC integration test
Previously CC test infrastructure create new direct driver for every "management" operation. This became quite expensive with 1.5 because each driver needs to allocate Netty resources. Tests became quite long running. This commit introduces a lazy cache of direct drivers. Cache keeps a map from cluster member to direct driver. Less driver instances are created and tests run faster.
1 parent a99f0f8 commit f7ceaa2

File tree

5 files changed

+137
-65
lines changed

5 files changed

+137
-65
lines changed

driver/src/test/java/org/neo4j/driver/v1/integration/CausalClusteringIT.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -890,15 +890,15 @@ private void ensureNodeVisible( Cluster cluster, String name, String bookmark )
890890
{
891891
for ( ClusterMember member : cluster.members() )
892892
{
893-
int count = countNodesUsingDirectDriver( member.getBoltUri(), name, bookmark );
893+
int count = countNodesUsingDirectDriver( member, name, bookmark );
894894
assertEquals( 1, count );
895895
}
896896
}
897897

898-
private int countNodesUsingDirectDriver( URI boltUri, final String name, String bookmark )
898+
private int countNodesUsingDirectDriver( ClusterMember member, final String name, String bookmark )
899899
{
900-
try ( Driver driver = createDriver( boltUri );
901-
Session session = driver.session( bookmark ) )
900+
Driver driver = clusterRule.getCluster().getDirectDriver( member );
901+
try ( Session session = driver.session( bookmark ) )
902902
{
903903
return session.readTransaction( new TransactionWork<Integer>()
904904
{

driver/src/test/java/org/neo4j/driver/v1/util/cc/Cluster.java

Lines changed: 34 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -21,60 +21,55 @@
2121
import java.net.URI;
2222
import java.net.UnknownHostException;
2323
import java.nio.file.Path;
24-
import java.util.Collections;
2524
import java.util.HashSet;
2625
import java.util.List;
2726
import java.util.Set;
2827
import java.util.concurrent.ThreadLocalRandom;
2928
import java.util.concurrent.TimeUnit;
3029

3130
import org.neo4j.driver.internal.BoltServerAddress;
32-
import org.neo4j.driver.internal.util.DriverFactoryWithOneEventLoopThread;
3331
import org.neo4j.driver.v1.AccessMode;
34-
import org.neo4j.driver.v1.AuthTokens;
35-
import org.neo4j.driver.v1.Config;
3632
import org.neo4j.driver.v1.Driver;
3733
import org.neo4j.driver.v1.Record;
3834
import org.neo4j.driver.v1.Session;
3935
import org.neo4j.driver.v1.StatementResult;
4036
import org.neo4j.driver.v1.util.TestUtil;
4137

38+
import static java.util.Collections.emptySet;
4239
import static java.util.Collections.unmodifiableSet;
4340
import static org.junit.Assert.assertEquals;
4441
import static org.junit.Assert.assertNotNull;
45-
import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING;
4642
import static org.neo4j.driver.internal.util.Iterables.single;
47-
import static org.neo4j.driver.v1.Config.TrustStrategy.trustAllCertificates;
4843
import static org.neo4j.driver.v1.util.TestUtil.sleep;
4944

50-
public class Cluster
45+
public class Cluster implements AutoCloseable
5146
{
5247
private static final String ADMIN_USER = "neo4j";
5348
private static final int STARTUP_TIMEOUT_SECONDS = 120;
5449
private static final int ONLINE_MEMBERS_CHECK_SLEEP_MS = 500;
5550

5651
private final Path path;
57-
private final String password;
5852
private final Set<ClusterMember> members;
5953
private final Set<ClusterMember> offlineMembers;
54+
private final ClusterDrivers clusterDrivers;
6055

6156
public Cluster( Path path, String password )
6257
{
63-
this( path, password, Collections.<ClusterMember>emptySet() );
58+
this( path, emptySet(), new ClusterDrivers( ADMIN_USER, password ) );
6459
}
6560

66-
private Cluster( Path path, String password, Set<ClusterMember> members )
61+
private Cluster( Path path, Set<ClusterMember> members, ClusterDrivers clusterDrivers )
6762
{
6863
this.path = path;
69-
this.password = password;
7064
this.members = members;
7165
this.offlineMembers = new HashSet<>();
66+
this.clusterDrivers = clusterDrivers;
7267
}
7368

7469
Cluster withMembers( Set<ClusterMember> newMembers ) throws ClusterUnavailableException
7570
{
76-
waitForMembersToBeOnline( newMembers, password );
77-
return new Cluster( path, password, newMembers );
71+
waitForMembersToBeOnline( newMembers, clusterDrivers );
72+
return new Cluster( path, newMembers, clusterDrivers );
7873
}
7974

8075
public Path getPath()
@@ -85,21 +80,16 @@ public Path getPath()
8580
public void deleteData()
8681
{
8782
// execute write query to remove all nodes and retrieve bookmark
88-
String bookmark;
89-
try ( Driver driver = createDriver( leader().getBoltUri(), password ) )
90-
{
91-
bookmark = TestUtil.cleanDb( driver );
92-
assertNotNull( "Cleanup of the database did not produce a bookmark", bookmark );
93-
}
83+
Driver driverToLeader = clusterDrivers.getDriver( leader() );
84+
String bookmark = TestUtil.cleanDb( driverToLeader );
85+
assertNotNull( "Cleanup of the database did not produce a bookmark", bookmark );
9486

9587
// ensure that every cluster member is up-to-date and contains no nodes
9688
for ( ClusterMember member : members )
9789
{
98-
try ( Driver driver = createDriver( member.getBoltUri(), password ) )
99-
{
100-
long nodeCount = TestUtil.countNodes( driver, bookmark );
101-
assertEquals( "Not all nodes have been deleted. " + nodeCount + " still there somehow ", 0L, nodeCount );
102-
}
90+
Driver driver = clusterDrivers.getDriver( member );
91+
long nodeCount = TestUtil.countNodes( driver, bookmark );
92+
assertEquals( "Not all nodes have been deleted. " + nodeCount + " still there somehow ", 0L, nodeCount );
10393
}
10494
}
10595

@@ -169,6 +159,17 @@ public void kill( ClusterMember member )
169159
waitForMembersToBeOnline();
170160
}
171161

162+
public Driver getDirectDriver( ClusterMember member )
163+
{
164+
return clusterDrivers.getDriver( member );
165+
}
166+
167+
@Override
168+
public void close()
169+
{
170+
clusterDrivers.close();
171+
}
172+
172173
@Override
173174
public String toString()
174175
{
@@ -206,8 +207,8 @@ private Set<ClusterMember> membersWithRole( ClusterMemberRole role )
206207
{
207208
Set<ClusterMember> membersWithRole = new HashSet<>();
208209

209-
try ( Driver driver = createDriver( members, password );
210-
Session session = driver.session( AccessMode.READ ) )
210+
Driver driver = driverToAnyCore( members, clusterDrivers );
211+
try ( Session session = driver.session( AccessMode.READ ) )
211212
{
212213
List<Record> records = findClusterOverview( session );
213214
for ( Record record : records )
@@ -237,15 +238,15 @@ private void waitForMembersToBeOnline()
237238
{
238239
try
239240
{
240-
waitForMembersToBeOnline( members, password );
241+
waitForMembersToBeOnline( members, clusterDrivers );
241242
}
242243
catch ( ClusterUnavailableException e )
243244
{
244245
throw new RuntimeException( e );
245246
}
246247
}
247248

248-
private static void waitForMembersToBeOnline( Set<ClusterMember> members, String password )
249+
private static void waitForMembersToBeOnline( Set<ClusterMember> members, ClusterDrivers clusterDrivers )
249250
throws ClusterUnavailableException
250251
{
251252
if ( members.isEmpty() )
@@ -254,7 +255,7 @@ private static void waitForMembersToBeOnline( Set<ClusterMember> members, String
254255
}
255256

256257
Set<BoltServerAddress> expectedOnlineAddresses = extractBoltAddresses( members );
257-
Set<BoltServerAddress> actualOnlineAddresses = Collections.emptySet();
258+
Set<BoltServerAddress> actualOnlineAddresses = emptySet();
258259

259260
long deadline = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis( STARTUP_TIMEOUT_SECONDS );
260261
Throwable error = null;
@@ -264,8 +265,8 @@ private static void waitForMembersToBeOnline( Set<ClusterMember> members, String
264265
sleep( ONLINE_MEMBERS_CHECK_SLEEP_MS );
265266
assertDeadlineNotReached( deadline, expectedOnlineAddresses, actualOnlineAddresses, error );
266267

267-
try ( Driver driver = createDriver( members, password );
268-
Session session = driver.session( AccessMode.READ ) )
268+
Driver driver = driverToAnyCore( members, clusterDrivers );
269+
try ( Session session = driver.session( AccessMode.READ ) )
269270
{
270271
List<Record> records = findClusterOverview( session );
271272
actualOnlineAddresses = extractBoltAddresses( records );
@@ -286,7 +287,7 @@ private static void waitForMembersToBeOnline( Set<ClusterMember> members, String
286287
}
287288
}
288289

289-
private static Driver createDriver( Set<ClusterMember> members, String password )
290+
private static Driver driverToAnyCore( Set<ClusterMember> members, ClusterDrivers clusterDrivers )
290291
{
291292
if ( members.isEmpty() )
292293
{
@@ -295,22 +296,13 @@ private static Driver createDriver( Set<ClusterMember> members, String password
295296

296297
for ( ClusterMember member : members )
297298
{
298-
Driver driver = createDriver( member.getBoltUri(), password );
299+
Driver driver = clusterDrivers.getDriver( member );
299300
try ( Session session = driver.session( AccessMode.READ ) )
300301
{
301302
if ( isCoreMember( session ) )
302303
{
303304
return driver;
304305
}
305-
else
306-
{
307-
driver.close();
308-
}
309-
}
310-
catch ( Exception e )
311-
{
312-
driver.close();
313-
throw e;
314306
}
315307
}
316308

@@ -411,24 +403,6 @@ private static ClusterMember findByBoltAddress( BoltServerAddress boltAddress, S
411403
return null;
412404
}
413405

414-
private static Driver createDriver( URI boltUri, String password )
415-
{
416-
DriverFactoryWithOneEventLoopThread factory = new DriverFactoryWithOneEventLoopThread();
417-
return factory.newInstance( boltUri, AuthTokens.basic( ADMIN_USER, password ), driverConfig() );
418-
}
419-
420-
private static Config driverConfig()
421-
{
422-
// try to build config for a very lightweight driver
423-
return Config.build()
424-
.withLogging( DEV_NULL_LOGGING )
425-
.withTrustStrategy( trustAllCertificates() )
426-
.withEncryption()
427-
.withMaxConnectionPoolSize( 1 )
428-
.withConnectionLivenessCheckTimeout( 1, TimeUnit.HOURS )
429-
.toConfig();
430-
}
431-
432406
private static ClusterMember randomOf( Set<ClusterMember> members )
433407
{
434408
int randomIndex = ThreadLocalRandom.current().nextInt( members.size() );
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright (c) 2002-2018 "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.v1.util.cc;
20+
21+
import java.util.Map;
22+
import java.util.concurrent.ConcurrentHashMap;
23+
import java.util.concurrent.TimeUnit;
24+
25+
import org.neo4j.driver.internal.util.DriverFactoryWithOneEventLoopThread;
26+
import org.neo4j.driver.v1.AuthTokens;
27+
import org.neo4j.driver.v1.Config;
28+
import org.neo4j.driver.v1.Driver;
29+
30+
import static org.neo4j.driver.internal.logging.DevNullLogging.DEV_NULL_LOGGING;
31+
32+
public class ClusterDrivers implements AutoCloseable
33+
{
34+
private final String user;
35+
private final String password;
36+
private final Map<ClusterMember,Driver> membersWithDrivers;
37+
38+
public ClusterDrivers( String user, String password )
39+
{
40+
this.user = user;
41+
this.password = password;
42+
this.membersWithDrivers = new ConcurrentHashMap<>();
43+
}
44+
45+
public Driver getDriver( ClusterMember member )
46+
{
47+
return membersWithDrivers.computeIfAbsent( member, this::createDriver );
48+
}
49+
50+
@Override
51+
public void close()
52+
{
53+
for ( Driver driver : membersWithDrivers.values() )
54+
{
55+
driver.close();
56+
}
57+
}
58+
59+
private Driver createDriver( ClusterMember member )
60+
{
61+
DriverFactoryWithOneEventLoopThread factory = new DriverFactoryWithOneEventLoopThread();
62+
return factory.newInstance( member.getBoltUri(), AuthTokens.basic( user, password ), driverConfig() );
63+
}
64+
65+
private static Config driverConfig()
66+
{
67+
return Config.build()
68+
.withLogging( DEV_NULL_LOGGING )
69+
.withoutEncryption()
70+
.withMaxConnectionPoolSize( 1 )
71+
.withConnectionLivenessCheckTimeout( 0, TimeUnit.MILLISECONDS )
72+
.toConfig();
73+
}
74+
}

driver/src/test/java/org/neo4j/driver/v1/util/cc/ClusterMember.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.net.URI;
2222
import java.net.UnknownHostException;
2323
import java.nio.file.Path;
24+
import java.util.Objects;
2425

2526
import org.neo4j.driver.internal.BoltServerAddress;
2627

@@ -62,13 +63,35 @@ public Path getPath()
6263
return path;
6364
}
6465

66+
@Override
67+
public boolean equals( Object o )
68+
{
69+
if ( this == o )
70+
{
71+
return true;
72+
}
73+
if ( o == null || getClass() != o.getClass() )
74+
{
75+
return false;
76+
}
77+
ClusterMember that = (ClusterMember) o;
78+
return Objects.equals( boltAddress, that.boltAddress );
79+
}
80+
81+
@Override
82+
public int hashCode()
83+
{
84+
return Objects.hash( boltAddress );
85+
}
86+
6587
@Override
6688
public String toString()
6789
{
6890
return "ClusterMember{" +
6991
"boltUri=" + boltUri +
92+
", boltAddress=" + boltAddress +
7093
", path=" + path +
71-
"}";
94+
'}';
7295
}
7396

7497
private static BoltServerAddress newBoltServerAddress( URI uri )

driver/src/test/java/org/neo4j/driver/v1/util/cc/SharedCluster.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ static Cluster get()
4545
static void remove()
4646
{
4747
assertClusterExists();
48+
clusterInstance.close();
4849
clusterInstance = null;
4950
}
5051

0 commit comments

Comments
 (0)