Skip to content

Commit 8639327

Browse files
committed
Make AddressSet retain resolved addresses
Routing table may override resolved router address in routing table. This leads to routing connection pool closures. This update aims to optimise this.
1 parent 9034eb9 commit 8639327

File tree

4 files changed

+53
-8
lines changed

4 files changed

+53
-8
lines changed

driver/src/main/java/org/neo4j/driver/internal/cluster/AddressSet.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,23 @@ public int size()
4040
return addresses.length;
4141
}
4242

43+
/**
44+
* Updates addresses using the provided set.
45+
* <p>
46+
* It aims to retain existing addresses by checking if they are present in the new set. To benefit from this, the provided set MUST contain specifically
47+
* {@link BoltServerAddress} instances with equal host and connection host values.
48+
*
49+
* @param newAddresses the new address set.
50+
*/
4351
public synchronized void retainAllAndAdd( Set<BoltServerAddress> newAddresses )
4452
{
4553
BoltServerAddress[] addressesArr = new BoltServerAddress[newAddresses.size()];
4654
int insertionIdx = 0;
4755
for ( BoltServerAddress address : addresses )
4856
{
49-
if ( newAddresses.remove( address ) )
57+
BoltServerAddress lookupAddress =
58+
BoltServerAddress.class.equals( address.getClass() ) ? address : new BoltServerAddress( address.host(), address.port() );
59+
if ( newAddresses.remove( lookupAddress ) )
5060
{
5161
addressesArr[insertionIdx] = address;
5262
insertionIdx++;

driver/src/main/java/org/neo4j/driver/internal/cluster/RoutingTableHandlerImpl.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ private synchronized void freshClusterCompositionFetched( ClusterCompositionLook
136136
{
137137
try
138138
{
139+
log.debug( "Fetched cluster composition for database '%s'. %s", databaseName.description(), compositionLookupResult.getClusterComposition() );
139140
routingTable.update( compositionLookupResult.getClusterComposition() );
140141
routingTableRegistry.removeAged();
141142

@@ -166,7 +167,8 @@ private synchronized void freshClusterCompositionFetched( ClusterCompositionLook
166167

167168
private synchronized void clusterCompositionLookupFailed( Throwable error )
168169
{
169-
log.error( String.format( "Failed to update routing table for database '%s'. Current routing table: %s.", databaseName.description(), routingTable ), error );
170+
log.error( String.format( "Failed to update routing table for database '%s'. Current routing table: %s.", databaseName.description(), routingTable ),
171+
error );
170172
routingTableRegistry.remove( databaseName );
171173
CompletableFuture<RoutingTable> routingTableFuture = refreshRoutingTableFuture;
172174
refreshRoutingTableFuture = null;

driver/src/test/java/org/neo4j/driver/internal/cluster/AddressSetTest.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,18 @@
2020

2121
import org.junit.jupiter.api.Test;
2222

23+
import java.net.InetAddress;
24+
import java.util.Arrays;
25+
import java.util.HashSet;
2326
import java.util.LinkedHashSet;
2427
import java.util.Set;
2528

2629
import org.neo4j.driver.internal.BoltServerAddress;
30+
import org.neo4j.driver.internal.ResolvedBoltServerAddress;
2731

2832
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
2933
import static org.junit.jupiter.api.Assertions.assertEquals;
34+
import static org.junit.jupiter.api.Assertions.assertSame;
3035

3136
class AddressSetTest
3237
{
@@ -142,6 +147,32 @@ void shouldHaveCorrectSize()
142147
assertEquals( 2, addressSet.size() );
143148
}
144149

150+
@Test
151+
void shouldRetainExistingAddresses()
152+
{
153+
AddressSet addressSet = new AddressSet();
154+
BoltServerAddress address0 = new BoltServerAddress( "node0", 7687 );
155+
BoltServerAddress address1 = new ResolvedBoltServerAddress( "node1", 7687, new InetAddress[]{InetAddress.getLoopbackAddress()} );
156+
BoltServerAddress address2 = new BoltServerAddress( "node2", 7687 );
157+
BoltServerAddress address3 = new BoltServerAddress( "node3", 7687 );
158+
BoltServerAddress address4 = new BoltServerAddress( "node4", 7687 );
159+
addressSet.retainAllAndAdd( new HashSet<>( Arrays.asList( address0, address1, address2, address3, address4 ) ) );
160+
161+
BoltServerAddress sameAddress0 = new BoltServerAddress( "node0", 7687 );
162+
BoltServerAddress sameAddress1 = new BoltServerAddress( "node1", 7687 );
163+
BoltServerAddress differentAddress2 = new BoltServerAddress( "different-node2", 7687 );
164+
BoltServerAddress sameAddress3 = new BoltServerAddress( "node3", 7687 );
165+
BoltServerAddress sameAddress4 = new BoltServerAddress( "node4", 7687 );
166+
addressSet.retainAllAndAdd( new HashSet<>( Arrays.asList( sameAddress0, sameAddress1, differentAddress2, sameAddress3, sameAddress4 ) ) );
167+
168+
assertEquals( 5, addressSet.size() );
169+
assertSame( addressSet.toArray()[0], address0 );
170+
assertSame( addressSet.toArray()[1], address1 );
171+
assertSame( addressSet.toArray()[2], address3 );
172+
assertSame( addressSet.toArray()[3], address4 );
173+
assertSame( addressSet.toArray()[4], differentAddress2 );
174+
}
175+
145176
private static Set<BoltServerAddress> addresses( String... strings )
146177
{
147178
Set<BoltServerAddress> set = new LinkedHashSet<>();

testkit-backend/src/main/java/neo4j/org/testkit/backend/messages/requests/GetRoutingTable.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import java.util.function.Function;
3333
import java.util.stream.Collectors;
3434

35-
import org.neo4j.driver.internal.BoltServerAddress;
3635
import org.neo4j.driver.internal.DatabaseName;
3736
import org.neo4j.driver.internal.DatabaseNameUtil;
3837
import org.neo4j.driver.internal.cluster.AddressSet;
@@ -43,6 +42,11 @@
4342
@Getter
4443
public class GetRoutingTable implements TestkitRequest
4544
{
45+
private static final Function<AddressSet,List<String>> ADDRESSES_TO_STRINGS =
46+
( addresses ) -> Arrays.stream( addresses.toArray() )
47+
.map( address -> String.format( "%s:%d", address.host(), address.port() ) )
48+
.collect( Collectors.toList() );
49+
4650
private GetRoutingTableBody data;
4751

4852
@Override
@@ -61,17 +65,15 @@ public TestkitResponse process( TestkitState testkitState )
6165
String.format( "There is no routing table handler for the '%s' database.", databaseName.databaseName().orElse( "null" ) ) ) );
6266

6367
org.neo4j.driver.internal.cluster.RoutingTable routingTable = routingTableHandler.routingTable();
64-
Function<AddressSet,List<String>> addressesToStrings = ( addresses ) -> Arrays.stream( addresses.toArray() )
65-
.map( BoltServerAddress::toString ).collect( Collectors.toList() );
6668

6769
return RoutingTable
6870
.builder()
6971
.data( RoutingTable.RoutingTableBody
7072
.builder()
7173
.database( databaseName.databaseName().orElse( null ) )
72-
.routers( addressesToStrings.apply( routingTable.routers() ) )
73-
.readers( addressesToStrings.apply( routingTable.readers() ) )
74-
.writers( addressesToStrings.apply( routingTable.writers() ) )
74+
.routers( ADDRESSES_TO_STRINGS.apply( routingTable.routers() ) )
75+
.readers( ADDRESSES_TO_STRINGS.apply( routingTable.readers() ) )
76+
.writers( ADDRESSES_TO_STRINGS.apply( routingTable.writers() ) )
7577
.build()
7678
).build();
7779
}

0 commit comments

Comments
 (0)