Search in sources :

Example 36 with LifeSupport

use of org.neo4j.kernel.lifecycle.LifeSupport in project neo4j by neo4j.

the class HighAvailabilityModeSwitcher method switchToDetached.

private void switchToDetached() {
    msgLog.info("I am %s, moving to detached", instanceId);
    startModeSwitching(() -> {
        if (cancellationHandle.cancellationRequested()) {
            msgLog.info("Switch to pending cancelled on start.");
            return;
        }
        componentSwitcher.switchToSlave();
        neoStoreDataSourceSupplier.getDataSource().beforeModeSwitch();
        if (cancellationHandle.cancellationRequested()) {
            msgLog.info("Switch to pending cancelled before ha communication shutdown.");
            return;
        }
        haCommunicationLife.shutdown();
        haCommunicationLife = new LifeSupport();
    }, new CancellationHandle());
    try {
        modeSwitcherFuture.get(10, TimeUnit.SECONDS);
    } catch (Exception e) {
        msgLog.warn("Exception received while waiting for switching to detached", e);
    }
}
Also used : LifeSupport(org.neo4j.kernel.lifecycle.LifeSupport) MismatchingStoreIdException(org.neo4j.kernel.impl.store.MismatchingStoreIdException) HighAvailabilityStoreFailureException(org.neo4j.kernel.ha.store.HighAvailabilityStoreFailureException) UnableToCopyStoreFromOldMasterException(org.neo4j.kernel.ha.store.UnableToCopyStoreFromOldMasterException)

Example 37 with LifeSupport

use of org.neo4j.kernel.lifecycle.LifeSupport in project neo4j by neo4j.

the class HighAvailabilityModeSwitcher method switchToPending.

private void switchToPending(final HighAvailabilityMemberState oldState) {
    msgLog.info("I am %s, moving to pending", instanceId);
    startModeSwitching(() -> {
        if (cancellationHandle.cancellationRequested()) {
            msgLog.info("Switch to pending cancelled on start.");
            return;
        }
        componentSwitcher.switchToPending();
        neoStoreDataSourceSupplier.getDataSource().beforeModeSwitch();
        if (cancellationHandle.cancellationRequested()) {
            msgLog.info("Switch to pending cancelled before ha communication shutdown.");
            return;
        }
        haCommunicationLife.shutdown();
        haCommunicationLife = new LifeSupport();
    }, new CancellationHandle());
    try {
        modeSwitcherFuture.get(10, TimeUnit.SECONDS);
    } catch (Exception ignored) {
    }
}
Also used : LifeSupport(org.neo4j.kernel.lifecycle.LifeSupport) MismatchingStoreIdException(org.neo4j.kernel.impl.store.MismatchingStoreIdException) HighAvailabilityStoreFailureException(org.neo4j.kernel.ha.store.HighAvailabilityStoreFailureException) UnableToCopyStoreFromOldMasterException(org.neo4j.kernel.ha.store.UnableToCopyStoreFromOldMasterException)

Example 38 with LifeSupport

use of org.neo4j.kernel.lifecycle.LifeSupport in project neo4j by neo4j.

the class HighAvailabilityModeSwitcher method switchToSlave.

private void switchToSlave() {
    /*
         * This is purely defensive and should never trigger. There was a race where the switch to slave task would
         * start after this instance was elected master and the task would constantly try to change as slave
         * for itself, never cancelling. This now should not be possible, since we cancel the task and wait for it
         * to complete, all in a single thread executor. However, this is a check worth doing because if this
         * condition slips through via some other code path it can cause trouble.
         */
    if (getServerId(availableMasterId).equals(instanceId)) {
        msgLog.error("I (" + me + ") tried to switch to slave for myself as master (" + availableMasterId + ")");
        return;
    }
    final AtomicLong wait = new AtomicLong();
    final CancellationHandle cancellationHandle = new CancellationHandle();
    startModeSwitching(new Runnable() {

        @Override
        public void run() {
            if (currentTargetState != HighAvailabilityMemberState.TO_SLAVE) {
                // Already switched - this can happen if a second master becomes available while waiting
                return;
            }
            if (cancellationHandle.cancellationRequested()) {
                msgLog.info("Switch to slave cancelled on start.");
                return;
            }
            componentSwitcher.switchToSlave();
            try {
                if (cancellationHandle.cancellationRequested()) {
                    msgLog.info("Switch to slave cancelled before ha communication started.");
                    return;
                }
                haCommunicationLife.shutdown();
                haCommunicationLife = new LifeSupport();
                // it is important for availableMasterId to be re-read on every attempt so that
                // slave switching would not result in an infinite loop with wrong/stale availableMasterId
                URI resultingSlaveHaURI = switchToSlave.switchToSlave(haCommunicationLife, me, availableMasterId, cancellationHandle);
                if (resultingSlaveHaURI == null) {
                    /*
                         * null slave uri means the task was cancelled. The task then must simply terminate and
                         * have no side effects.
                         */
                    msgLog.info("Switch to slave is effectively cancelled");
                } else {
                    slaveHaURI = resultingSlaveHaURI;
                    canAskForElections.set(true);
                }
            } catch (HighAvailabilityStoreFailureException e) {
                userLog.error("UNABLE TO START UP AS SLAVE: %s", e.getMessage());
                msgLog.error("Unable to start up as slave", e);
                clusterMemberAvailability.memberIsUnavailable(SLAVE);
                ClusterClient clusterClient = HighAvailabilityModeSwitcher.this.clusterClient;
                try {
                    // TODO I doubt this actually works
                    clusterClient.leave();
                    clusterClient.stop();
                    haCommunicationLife.shutdown();
                } catch (Throwable t) {
                    msgLog.error("Unable to stop cluster client", t);
                }
                modeSwitcherExecutor.schedule(this, 5, TimeUnit.SECONDS);
            } catch (MismatchingStoreIdException e) {
                // Try again immediately, the place that threw it have already treated the db
                // as branched and so a new attempt will have this slave copy a new store from master.
                run();
            } catch (Throwable t) {
                msgLog.error("Error while trying to switch to slave", t);
                // Try again later
                // Exponential backoff
                wait.set(1 + wait.get() * 2);
                // Wait maximum 5 minutes
                wait.set(Math.min(wait.get(), 5 * 60));
                modeSwitcherFuture = modeSwitcherExecutor.schedule(this, wait.get(), TimeUnit.SECONDS);
                msgLog.info("Attempting to switch to slave in %ds", wait.get());
            }
        }
    }, cancellationHandle);
}
Also used : AtomicLong(java.util.concurrent.atomic.AtomicLong) ClusterClient(org.neo4j.cluster.client.ClusterClient) HighAvailabilityStoreFailureException(org.neo4j.kernel.ha.store.HighAvailabilityStoreFailureException) LifeSupport(org.neo4j.kernel.lifecycle.LifeSupport) MismatchingStoreIdException(org.neo4j.kernel.impl.store.MismatchingStoreIdException) URI(java.net.URI)

Example 39 with LifeSupport

use of org.neo4j.kernel.lifecycle.LifeSupport in project neo4j by neo4j.

the class PhysicalLogFileTest method shouldOpenInFreshDirectoryAndFinallyAddHeader.

@Test
public void shouldOpenInFreshDirectoryAndFinallyAddHeader() throws Exception {
    // GIVEN
    String name = "log";
    LifeSupport life = new LifeSupport();
    FileSystemAbstraction fs = fileSystemRule.get();
    PhysicalLogFiles logFiles = new PhysicalLogFiles(directory.directory(), name, fs);
    life.add(new PhysicalLogFile(fs, logFiles, 1000, transactionIdStore::getLastCommittedTransactionId, logVersionRepository, mock(Monitor.class), new LogHeaderCache(10)));
    // WHEN
    life.start();
    life.shutdown();
    // THEN
    File file = new PhysicalLogFiles(directory.directory(), name, fs).getLogFileForVersion(1L);
    LogHeader header = readLogHeader(fs, file);
    assertEquals(1L, header.logVersion);
    assertEquals(5L, header.lastCommittedTxId);
}
Also used : FileSystemAbstraction(org.neo4j.io.fs.FileSystemAbstraction) LifeSupport(org.neo4j.kernel.lifecycle.LifeSupport) Matchers.anyString(org.mockito.Matchers.anyString) File(java.io.File) LogHeaderReader.readLogHeader(org.neo4j.kernel.impl.transaction.log.entry.LogHeaderReader.readLogHeader) LogHeader(org.neo4j.kernel.impl.transaction.log.entry.LogHeader) Test(org.junit.Test)

Example 40 with LifeSupport

use of org.neo4j.kernel.lifecycle.LifeSupport in project neo4j by neo4j.

the class PhysicalLogFileTest method shouldWriteSomeDataIntoTheLog.

@Test
public void shouldWriteSomeDataIntoTheLog() throws Exception {
    // GIVEN
    String name = "log";
    LifeSupport life = new LifeSupport();
    FileSystemAbstraction fs = fileSystemRule.get();
    PhysicalLogFiles logFiles = new PhysicalLogFiles(directory.directory(), name, fs);
    Monitor monitor = mock(Monitor.class);
    LogFile logFile = life.add(new PhysicalLogFile(fs, logFiles, 1000, transactionIdStore::getLastCommittedTransactionId, logVersionRepository, monitor, new LogHeaderCache(10)));
    // WHEN
    try {
        life.start();
        FlushablePositionAwareChannel writer = logFile.getWriter();
        LogPositionMarker positionMarker = new LogPositionMarker();
        writer.getCurrentPosition(positionMarker);
        int intValue = 45;
        long longValue = 4854587;
        writer.putInt(intValue);
        writer.putLong(longValue);
        writer.prepareForFlush().flush();
        // THEN
        try (ReadableClosableChannel reader = logFile.getReader(positionMarker.newPosition())) {
            assertEquals(intValue, reader.getInt());
            assertEquals(longValue, reader.getLong());
        }
    } finally {
        life.shutdown();
    }
}
Also used : FileSystemAbstraction(org.neo4j.io.fs.FileSystemAbstraction) Matchers.anyString(org.mockito.Matchers.anyString) Monitor(org.neo4j.kernel.impl.transaction.log.PhysicalLogFile.Monitor) LifeSupport(org.neo4j.kernel.lifecycle.LifeSupport) Test(org.junit.Test)

Aggregations

LifeSupport (org.neo4j.kernel.lifecycle.LifeSupport)51 Test (org.junit.Test)22 IOException (java.io.IOException)14 File (java.io.File)12 Monitors (org.neo4j.kernel.monitoring.Monitors)12 FileSystemAbstraction (org.neo4j.io.fs.FileSystemAbstraction)8 ReadableClosablePositionAwareChannel (org.neo4j.kernel.impl.transaction.log.ReadableClosablePositionAwareChannel)8 VersionAwareLogEntryReader (org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader)8 CommittedTransactionRepresentation (org.neo4j.kernel.impl.transaction.CommittedTransactionRepresentation)6 JobScheduler (org.neo4j.kernel.impl.util.JobScheduler)6 LogHeaderCache (org.neo4j.kernel.impl.transaction.log.LogHeaderCache)5 PhysicalLogFile (org.neo4j.kernel.impl.transaction.log.PhysicalLogFile)5 Monitor (org.neo4j.kernel.impl.transaction.log.PhysicalLogFile.Monitor)5 Dependencies (org.neo4j.kernel.impl.util.Dependencies)5 StorageEngine (org.neo4j.storageengine.api.StorageEngine)5 URI (java.net.URI)4 Matchers.anyString (org.mockito.Matchers.anyString)4 Config (org.neo4j.kernel.configuration.Config)4 UnableToCopyStoreFromOldMasterException (org.neo4j.kernel.ha.store.UnableToCopyStoreFromOldMasterException)4 KernelContext (org.neo4j.kernel.impl.spi.KernelContext)4