use of org.neo4j.kernel.lifecycle.Lifespan in project neo4j by neo4j.
the class DurableStateStorageTest method shouldClearFileOnFirstUse.
@Test
public void shouldClearFileOnFirstUse() throws Throwable {
// given
EphemeralFileSystemAbstraction fsa = fileSystemRule.get();
fsa.mkdir(testDir.directory());
int rotationCount = 10;
DurableStateStorage<AtomicInteger> storage = new DurableStateStorage<>(fsa, testDir.directory(), "state", new AtomicIntegerMarshal(), rotationCount, NullLogProvider.getInstance());
int largestValueWritten = 0;
try (Lifespan lifespan = new Lifespan(storage)) {
for (; largestValueWritten < rotationCount * 2; largestValueWritten++) {
storage.persistStoreData(new AtomicInteger(largestValueWritten));
}
}
// now both files are full. We reopen, then write some more.
storage = lifeRule.add(new DurableStateStorage<>(fsa, testDir.directory(), "state", new AtomicIntegerMarshal(), rotationCount, NullLogProvider.getInstance()));
storage.persistStoreData(new AtomicInteger(largestValueWritten++));
storage.persistStoreData(new AtomicInteger(largestValueWritten++));
storage.persistStoreData(new AtomicInteger(largestValueWritten));
/*
* We have written stuff in fileA but not gotten to the end (resulting in rotation). The largestValueWritten
* should nevertheless be correct
*/
ByteBuffer forReadingBackIn = ByteBuffer.allocate(10_000);
StoreChannel lastWrittenTo = fsa.open(stateFileA(), "r");
lastWrittenTo.read(forReadingBackIn);
forReadingBackIn.flip();
AtomicInteger lastRead = null;
while (true) {
try {
lastRead = new AtomicInteger(forReadingBackIn.getInt());
} catch (BufferUnderflowException e) {
break;
}
}
// then
assertNotNull(lastRead);
assertEquals(largestValueWritten, lastRead.get());
}
use of org.neo4j.kernel.lifecycle.Lifespan in project neo4j by neo4j.
the class CountsRotationTest method shouldUnMapThePrestateFileWhenTimingOutOnRotationAndAllowForShutdownInTheFailedRotationState.
@Test
public void shouldUnMapThePrestateFileWhenTimingOutOnRotationAndAllowForShutdownInTheFailedRotationState() throws Throwable {
// Given
dbBuilder.newGraphDatabase().shutdown();
CountsTracker store = createCountsTracker(pageCache, Config.defaults().augment(Collections.singletonMap(GraphDatabaseSettings.counts_store_rotation_timeout.name(), "100ms")));
try (Lifespan lifespan = new Lifespan(store)) {
try (CountsAccessor.Updater updater = store.apply(2).get()) {
updater.incrementNodeCount(0, 1);
}
try {
// when
store.rotate(3);
fail("should have thrown");
} catch (RotationTimeoutException ex) {
// good
}
}
// and also no exceptions closing the page cache
pageCache.close();
}
use of org.neo4j.kernel.lifecycle.Lifespan in project neo4j by neo4j.
the class CountsRotationTest method shouldRotateCountsStoreWhenClosingTheDatabase.
@Test
public void shouldRotateCountsStoreWhenClosingTheDatabase() throws IOException {
// GIVEN
GraphDatabaseAPI db = (GraphDatabaseAPI) dbBuilder.newGraphDatabase();
try (Transaction tx = db.beginTx()) {
db.createNode(A);
tx.success();
}
// WHEN
db.shutdown();
// THEN
assertTrue(fs.fileExists(alphaStoreFile()));
assertTrue(fs.fileExists(betaStoreFile()));
try (Lifespan life = new Lifespan()) {
CountsTracker store = life.add(createCountsTracker(pageCache));
// a transaction for creating the label and a transaction for the node
assertEquals(BASE_TX_ID + 1 + 1, store.txId());
assertEquals(INITIAL_MINOR_VERSION, store.minorVersion());
// one for all nodes and one for the created "A" label
assertEquals(1 + 1, store.totalEntriesStored());
assertEquals(1 + 1, allRecords(store).size());
}
}
use of org.neo4j.kernel.lifecycle.Lifespan in project neo4j by neo4j.
the class CountsTrackerTest method shouldBeAbleToReadUpToDateValueWhileAnotherThreadIsPerformingRotation.
@Test
public void shouldBeAbleToReadUpToDateValueWhileAnotherThreadIsPerformingRotation() throws Exception {
// given
CountsOracle oracle = someData();
final int firstTransaction = 2, secondTransaction = 3;
try (Lifespan life = new Lifespan()) {
CountsTracker tracker = life.add(newTracker());
oracle.update(tracker, firstTransaction);
tracker.rotate(firstTransaction);
}
// when
final CountsOracle delta = new CountsOracle();
{
CountsOracle.Node n1 = delta.node(1);
// Label 4 has not been used before...
CountsOracle.Node n2 = delta.node(1, 4);
delta.relationship(n1, 1, n2);
// relationshipType 2 has not been used before...
delta.relationship(n2, 2, n1);
}
delta.update(oracle);
try (Lifespan life = new Lifespan()) {
final Barrier.Control barrier = new Barrier.Control();
CountsTracker tracker = life.add(new CountsTracker(resourceManager.logProvider(), resourceManager.fileSystem(), resourceManager.pageCache(), Config.empty(), resourceManager.testPath()) {
@Override
protected boolean include(CountsKey countsKey, ReadableBuffer value) {
barrier.reached();
return super.include(countsKey, value);
}
});
Future<Void> task = threading.execute((ThrowingFunction<CountsTracker, Void, RuntimeException>) t -> {
try {
delta.update(t, secondTransaction);
t.rotate(secondTransaction);
} catch (IOException e) {
throw new AssertionError(e);
}
return null;
}, tracker);
// then
barrier.await();
oracle.verify(tracker);
barrier.release();
task.get();
oracle.verify(tracker);
}
}
use of org.neo4j.kernel.lifecycle.Lifespan in project neo4j by neo4j.
the class CountsTrackerTest method shouldUpdateCountsOnExistingStore.
@Test
public void shouldUpdateCountsOnExistingStore() throws Exception {
// given
CountsOracle oracle = someData();
int firstTx = 2, secondTx = 3;
try (Lifespan life = new Lifespan()) {
CountsTracker tracker = life.add(newTracker());
oracle.update(tracker, firstTx);
tracker.rotate(firstTx);
oracle.verify(tracker);
// when
CountsOracle delta = new CountsOracle();
{
CountsOracle.Node n1 = delta.node(1);
// Label 4 has not been used before...
CountsOracle.Node n2 = delta.node(1, 4);
delta.relationship(n1, 1, n2);
// relationshipType 2 has not been used before...
delta.relationship(n2, 2, n1);
}
delta.update(tracker, secondTx);
delta.update(oracle);
// then
oracle.verify(tracker);
// when
tracker.rotate(secondTx);
}
// then
try (Lifespan life = new Lifespan()) {
oracle.verify(life.add(newTracker()));
}
}
Aggregations