use of org.neo4j.causalclustering.discovery.CoreClusterMember in project neo4j by neo4j.
the class TransactionLogRecoveryIT method coreShouldStartAfterPartialTransactionWriteCrash.
@Test
public void coreShouldStartAfterPartialTransactionWriteCrash() throws Exception {
// given: a fully synced cluster with some data
dataMatchesEventually(createEmptyNodes(cluster, 10), cluster.coreMembers());
// when: shutting down a core
CoreClusterMember core = cluster.getCoreMemberById(0);
core.shutdown();
// and making sure there will be something new to pull
CoreClusterMember lastWrites = createEmptyNodes(cluster, 10);
// and writing a partial tx
writePartialTx(core.storeDir());
// then: we should still be able to start
core.start();
// and become fully synced again
dataMatchesEventually(lastWrites, singletonList(core));
}
use of org.neo4j.causalclustering.discovery.CoreClusterMember in project neo4j by neo4j.
the class CoreEdgeMetricsIT method shouldMonitorCoreEdge.
@Test
public void shouldMonitorCoreEdge() throws Exception {
// given
cluster = clusterRule.startCluster();
// when
CoreGraphDatabase coreDB = cluster.awaitLeader(5, TimeUnit.SECONDS).database();
try (Transaction tx = coreDB.beginTx()) {
Node node = coreDB.createNode(label("boo"));
node.setProperty("foobar", "baz_bat");
tx.success();
}
// then
for (CoreClusterMember db : cluster.coreMembers()) {
assertAllNodesVisible(db.database());
}
for (ReadReplica db : cluster.readReplicas()) {
assertAllNodesVisible(db.database());
}
File coreMetricsDir = new File(cluster.getCoreMemberById(0).homeDir(), csvPath.getDefaultValue());
assertEventually("append index eventually accurate", () -> readLongValue(metricsCsv(coreMetricsDir, CoreMetrics.APPEND_INDEX)), greaterThan(0L), TIMEOUT, TimeUnit.SECONDS);
assertEventually("commit index eventually accurate", () -> readLongValue(metricsCsv(coreMetricsDir, CoreMetrics.COMMIT_INDEX)), greaterThan(0L), TIMEOUT, TimeUnit.SECONDS);
assertEventually("term eventually accurate", () -> readLongValue(metricsCsv(coreMetricsDir, CoreMetrics.TERM)), greaterThanOrEqualTo(0L), TIMEOUT, TimeUnit.SECONDS);
assertEventually("leader not found eventually accurate", () -> readLongValue(metricsCsv(coreMetricsDir, CoreMetrics.LEADER_NOT_FOUND)), equalTo(0L), TIMEOUT, TimeUnit.SECONDS);
assertEventually("tx pull requests received eventually accurate", () -> {
long total = 0;
for (final File homeDir : cluster.coreMembers().stream().map(CoreClusterMember::homeDir).collect(Collectors.toList())) {
File metricsDir = new File(homeDir, "metrics");
total += readLongValue(metricsCsv(metricsDir, CatchUpMetrics.TX_PULL_REQUESTS_RECEIVED));
}
return total;
}, greaterThan(0L), TIMEOUT, TimeUnit.SECONDS);
assertEventually("tx retries eventually accurate", () -> readLongValue(metricsCsv(coreMetricsDir, CoreMetrics.TX_RETRIES)), equalTo(0L), TIMEOUT, TimeUnit.SECONDS);
assertEventually("is leader eventually accurate", () -> readLongValue(metricsCsv(coreMetricsDir, CoreMetrics.IS_LEADER)), greaterThanOrEqualTo(0L), TIMEOUT, TimeUnit.SECONDS);
File readReplicaMetricsDir = new File(cluster.getReadReplicaById(0).homeDir(), "metrics");
assertEventually("pull update request registered", () -> readLongValue(metricsCsv(readReplicaMetricsDir, PULL_UPDATES)), greaterThan(0L), TIMEOUT, TimeUnit.SECONDS);
assertEventually("pull update request registered", () -> readLongValue(metricsCsv(readReplicaMetricsDir, PULL_UPDATE_HIGHEST_TX_ID_REQUESTED)), greaterThan(0L), TIMEOUT, TimeUnit.SECONDS);
assertEventually("pull update response received", () -> readLongValue(metricsCsv(readReplicaMetricsDir, PULL_UPDATE_HIGHEST_TX_ID_RECEIVED)), greaterThan(0L), TIMEOUT, TimeUnit.SECONDS);
assertEventually("dropped messages eventually accurate", () -> readLongValue(metricsCsv(coreMetricsDir, CoreMetrics.DROPPED_MESSAGES)), greaterThanOrEqualTo(0L), TIMEOUT, TimeUnit.SECONDS);
assertEventually("queue size eventually accurate", () -> readLongValue(metricsCsv(coreMetricsDir, CoreMetrics.QUEUE_SIZE)), greaterThanOrEqualTo(0L), TIMEOUT, TimeUnit.SECONDS);
}
use of org.neo4j.causalclustering.discovery.CoreClusterMember in project neo4j by neo4j.
the class BoltCausalClusteringIT method shouldPickANewServerToWriteToOnLeaderSwitch.
@Test
public void shouldPickANewServerToWriteToOnLeaderSwitch() throws Throwable {
// given
cluster = clusterRule.withNumberOfReadReplicas(0).startCluster();
CoreClusterMember leader = cluster.awaitLeader();
LeaderSwitcher leaderSwitcher = new LeaderSwitcher(cluster);
Config config = Config.build().withLogging(new JULogging(Level.OFF)).toConfig();
Set<BoltServerAddress> seenAddresses = new HashSet<>();
try (Driver driver = GraphDatabase.driver(leader.routingURI(), AuthTokens.basic("neo4j", "neo4j"), config)) {
boolean success = false;
long deadline = System.currentTimeMillis() + (30 * 1000);
while (!success) {
if (System.currentTimeMillis() > deadline) {
fail("Failed to write to the new leader in time. Addresses seen: " + seenAddresses);
}
try (Session session = driver.session(AccessMode.WRITE)) {
BoltServerAddress boltServerAddress = ((RoutingNetworkSession) session).address();
session.run("CREATE (p:Person)");
seenAddresses.add(boltServerAddress);
success = seenAddresses.size() >= 2;
} catch (Exception e) {
Thread.sleep(100);
}
/*
* Having the latch release here ensures that we've done at least one pass through the loop, which means
* we've completed a connection before the forced master switch.
*/
if (seenAddresses.size() >= 1) {
leaderSwitcher.start();
}
}
} finally {
leaderSwitcher.stop();
assertTrue(leaderSwitcher.hadLeaderSwitch());
assertThat(seenAddresses.size(), greaterThanOrEqualTo(2));
}
}
use of org.neo4j.causalclustering.discovery.CoreClusterMember in project neo4j by neo4j.
the class BoltCausalClusteringIT method bookmarksShouldWorkWithDriverPinnedToSingleServer.
// Ensure that Bookmarks work with single instances using a driver created using a bolt[not+routing] URI.
@Test
public void bookmarksShouldWorkWithDriverPinnedToSingleServer() throws Exception {
// given
cluster = clusterRule.withNumberOfReadReplicas(1).startCluster();
CoreClusterMember leader = cluster.awaitLeader();
try (Driver driver = GraphDatabase.driver(leader.directURI(), AuthTokens.basic("neo4j", "neo4j"))) {
String bookmark = inExpirableSession(driver, Driver::session, (session) -> {
try (Transaction tx = session.beginTransaction()) {
tx.run("CREATE (p:Person {name: {name} })", Values.parameters("name", "Alistair"));
tx.success();
}
return session.lastBookmark();
});
assertNotNull(bookmark);
try (Session session = driver.session();
Transaction tx = session.beginTransaction(bookmark)) {
Record record = tx.run("MATCH (n:Person) RETURN COUNT(*) AS count").next();
assertEquals(1, record.get("count").asInt());
tx.success();
}
}
}
use of org.neo4j.causalclustering.discovery.CoreClusterMember in project neo4j by neo4j.
the class BoltCausalClusteringIT method shouldUseBookmarkFromAReadSessionInAWriteSession.
@Test
public void shouldUseBookmarkFromAReadSessionInAWriteSession() throws Exception {
// given
cluster = clusterRule.withNumberOfReadReplicas(1).startCluster();
CoreClusterMember leader = cluster.awaitLeader();
try (Driver driver = GraphDatabase.driver(leader.directURI(), AuthTokens.basic("neo4j", "neo4j"))) {
inExpirableSession(driver, (d) -> d.session(AccessMode.WRITE), (session) -> {
session.run("CREATE (p:Person {name: {name} })", Values.parameters("name", "Jim"));
return null;
});
String bookmark;
try (Session session = driver.session(AccessMode.READ)) {
try (Transaction tx = session.beginTransaction()) {
tx.run("MATCH (n:Person) RETURN COUNT(*) AS count").next();
tx.success();
}
bookmark = session.lastBookmark();
}
assertNotNull(bookmark);
inExpirableSession(driver, (d) -> d.session(AccessMode.WRITE), (session) -> {
try (Transaction tx = session.beginTransaction(bookmark)) {
tx.run("CREATE (p:Person {name: {name} })", Values.parameters("name", "Alistair"));
tx.success();
}
return null;
});
try (Session session = driver.session()) {
Record record = session.run("MATCH (n:Person) RETURN COUNT(*) AS count").next();
assertEquals(2, record.get("count").asInt());
}
}
}
Aggregations