Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Internal restarts no longer break bolt connections
The Bolt server was not properly refreshing internal components it got access to and this caused internal restarts to try and access TransactionIdStore after it was closed, leading to errors about the neostore file being closed. Passing instead a Supplier of the same solves the issue. This is a partial backport of #9114
- Loading branch information
1 parent
9861cf1
commit 0163d19
Showing
7 changed files
with
164 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
101 changes: 101 additions & 0 deletions
101
integrationtests/src/test/java/org/neo4j/ha/BoltHAIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/* | ||
* Copyright (c) 2002-2017 "Neo Technology," | ||
* Network Engine for Objects in Lund AB [http://neotechnology.com] | ||
* | ||
* This file is part of Neo4j. | ||
* | ||
* Neo4j is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Affero General Public License as | ||
* published by the Free Software Foundation, either version 3 of the | ||
* License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU Affero General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Affero General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
package org.neo4j.ha; | ||
|
||
import org.junit.Rule; | ||
import org.junit.Test; | ||
|
||
import org.neo4j.driver.v1.AccessMode; | ||
import org.neo4j.driver.v1.AuthTokens; | ||
import org.neo4j.driver.v1.Driver; | ||
import org.neo4j.driver.v1.GraphDatabase; | ||
import org.neo4j.driver.v1.Record; | ||
import org.neo4j.driver.v1.Session; | ||
import org.neo4j.driver.v1.Transaction; | ||
import org.neo4j.kernel.ha.HighlyAvailableGraphDatabase; | ||
import org.neo4j.kernel.impl.ha.ClusterManager; | ||
import org.neo4j.test.ha.ClusterRule; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import static org.neo4j.driver.v1.Values.parameters; | ||
import static org.neo4j.kernel.impl.ha.ClusterManager.clusterOfSize; | ||
import static org.neo4j.kernel.impl.ha.ClusterManager.entireClusterSeesMemberAsNotAvailable; | ||
import static org.neo4j.kernel.impl.ha.ClusterManager.masterSeesMembers; | ||
|
||
public class BoltHAIT | ||
{ | ||
@Rule | ||
public final ClusterRule clusterRule = new ClusterRule( getClass() ).withCluster( clusterOfSize( 3 ) ); | ||
|
||
@Test | ||
public void shouldContinueServingBoltRequestsBetweenInteralRestarts() throws Throwable | ||
{ | ||
// given | ||
/* | ||
* Interestingly, it is enough to simply start a slave and then direct sessions to it. The problem seems | ||
* to arise immediately, since simply from startup to being into SLAVE at least one internal restart happens | ||
* and that seems sufficient to break the bolt server. | ||
* However, that would make the test really weird, so we'll start the cluster, make sure we can connect and | ||
* then isolate the slave, make it shutdown internally, then have it rejoin and it will switch to slave. | ||
* At the end of this process, it must still be possible to open and execute transactions against the instance. | ||
*/ | ||
ClusterManager.ManagedCluster cluster = clusterRule.startCluster(); | ||
HighlyAvailableGraphDatabase slave1 = cluster.getAnySlave(); | ||
|
||
Driver driver = GraphDatabase.driver( cluster.getBoltAddress( slave1 ), | ||
AuthTokens.basic( "neo4j", "neo4j" ) ); | ||
|
||
/* | ||
* We'll use a bookmark to enforce use of kernel internals by the bolt server, to make sure that parts that are | ||
* switched during an internal restart are actually refreshed. Technically, this is not necessary, since the | ||
* bolt server makes such use for every request. But this puts a nice bow on top of it. | ||
*/ | ||
String lastBookmark; | ||
|
||
try ( Session session = driver.session() ) | ||
{ | ||
try ( Transaction tx = session.beginTransaction() ) | ||
{ | ||
tx.run( "CREATE (person:Person {name: {name}, title: {title}})", | ||
parameters( "name", "Webber", "title", "Mr" ) ); | ||
tx.success(); | ||
} | ||
lastBookmark = session.lastBookmark(); | ||
} | ||
|
||
// when | ||
ClusterManager.RepairKit slaveFailRK = cluster.fail( slave1 ); | ||
|
||
cluster.await( entireClusterSeesMemberAsNotAvailable( slave1 ) ); | ||
slaveFailRK.repair(); | ||
cluster.await( masterSeesMembers( 3 ) ); | ||
|
||
// then | ||
try ( Session session = driver.session( AccessMode.READ ) ) | ||
{ | ||
try ( Transaction tx = session.beginTransaction( lastBookmark ) ) | ||
{ | ||
Record record = tx.run( "MATCH (n:Person) RETURN COUNT(*) AS count" ).next(); | ||
tx.success(); | ||
assertEquals( 1, record.get( "count" ).asInt() ); | ||
} | ||
} | ||
} | ||
} |