Search in sources :

Example 1 with InterruptedRuntimeException

use of net.openhft.chronicle.core.threads.InterruptedRuntimeException in project Chronicle-Queue by OpenHFT.

the class NotCompleteTest method testInterruptOrExceptionDuringSerialisation.

@Test
public void testInterruptOrExceptionDuringSerialisation() throws InterruptedException {
    final File tmpDir = DirectoryUtils.tempDir("testInterruptedDuringSerialisation");
    try {
        DirectoryUtils.deleteDir(tmpDir);
        tmpDir.mkdirs();
        final List<String> names = Collections.synchronizedList(new ArrayList<>());
        final Person person1 = new Person(40, "Terry");
        final Person interrupter = new Person(50, Person.INTERRUPT);
        final Person thrower = new Person(80, Person.THROW);
        final Person person2 = new Person(90, "Bert");
        try (final ChronicleQueue queueReader = createQueue(tmpDir);
            final ChronicleQueue queueWriter = createQueue(tmpDir)) {
            ExcerptTailer tailer = queueReader.createTailer();
            MethodReader reader = tailer.methodReader((PersonListener) person -> names.add(person.name));
            final StringBuilder queueDumpBeforeInterruptedWrite = new StringBuilder();
            // set up
            doWrite(queueWriter, (proxy, queue) -> {
                proxy.accept(person1);
                queueDumpBeforeInterruptedWrite.append(queue.dump());
            });
            String cleanedQueueDump = cleanQueueDump(queueDumpBeforeInterruptedWrite.toString());
            // start up writer thread
            Thread writerThread = new Thread(() -> doWrite(queueWriter, (proxy, queue) -> {
                // thread is interrupted during this
                try {
                    proxy.accept(interrupter);
                    Jvm.error().on(getClass(), "Should have interrupted");
                } catch (InterruptedRuntimeException expected) {
                // expected.
                }
            }));
            writerThread.start();
            writerThread.join();
            try (final ChronicleQueue queue = createQueue(tmpDir)) {
                String dump = cleanQueueDump(queue.dump());
                assertEquals("queue should be unchanged by the interrupted write", cleanedQueueDump, dump);
            }
            // check only 1 written
            assertTrue(reader.readOne());
            assertEquals(1, names.size());
            assertEquals(person1.name, names.get(0));
            assertFalse(reader.readOne());
            // do a write that throws an exception
            doWrite(queueWriter, (proxy, queue) -> {
                try {
                    proxy.accept(thrower);
                } catch (NullPointerException npe) {
                // ignore
                }
            });
            try (final ChronicleQueue queue = createQueue(tmpDir)) {
                String dump = cleanQueueDump(queue.dump());
                assertEquals("queue should be unchanged by the failed (exception) write", cleanedQueueDump, dump);
            // System.err.println(queue.dump());
            }
            // check nothing else written
            assertFalse(reader.readOne());
            // do an empty write
            ExcerptAppender appender = queueWriter.acquireAppender();
            DocumentContext wd = appender.writingDocument();
            wd.rollbackOnClose();
            wd.close();
            // check queue unchanged
            String dump = cleanQueueDump(queueWriter.dump());
            assertEquals("queue should be unchanged by the failed (rollback) write", cleanedQueueDump, dump);
            // check nothing else written
            assertFalse(reader.readOne());
            // write another person to same queue in this thread
            doWrite(queueWriter, (proxy, queue) -> proxy.accept(person2));
            assertTrue(reader.readOne());
            assertEquals(2, names.size());
            assertEquals(person2.name, names.get(1));
            assertFalse(reader.readOne());
        }
    } finally {
        try {
            IOTools.deleteDirWithFiles(tmpDir, 2);
        } catch (Exception e) {
            if (e instanceof AccessDeniedException && OS.isWindows())
                return;
            throw e;
        }
    }
}
Also used : MethodReader(net.openhft.chronicle.bytes.MethodReader) DocumentContext(net.openhft.chronicle.wire.DocumentContext) Test(org.junit.Test) SingleChronicleQueueBuilder.binary(net.openhft.chronicle.queue.impl.single.SingleChronicleQueueBuilder.binary) Jvm(net.openhft.chronicle.core.Jvm) File(java.io.File) ArrayList(java.util.ArrayList) WireOut(net.openhft.chronicle.wire.WireOut) List(java.util.List) net.openhft.chronicle.queue(net.openhft.chronicle.queue) RequiredForClient(net.openhft.chronicle.core.annotation.RequiredForClient) IOTools(net.openhft.chronicle.core.io.IOTools) After(org.junit.After) BiConsumer(java.util.function.BiConsumer) OS(net.openhft.chronicle.core.OS) NotNull(org.jetbrains.annotations.NotNull) Assert(org.junit.Assert) Marshallable(net.openhft.chronicle.wire.Marshallable) AccessDeniedException(java.nio.file.AccessDeniedException) Collections(java.util.Collections) InterruptedRuntimeException(net.openhft.chronicle.core.threads.InterruptedRuntimeException) InterruptedRuntimeException(net.openhft.chronicle.core.threads.InterruptedRuntimeException) AccessDeniedException(java.nio.file.AccessDeniedException) AccessDeniedException(java.nio.file.AccessDeniedException) InterruptedRuntimeException(net.openhft.chronicle.core.threads.InterruptedRuntimeException) DocumentContext(net.openhft.chronicle.wire.DocumentContext) File(java.io.File) MethodReader(net.openhft.chronicle.bytes.MethodReader) Test(org.junit.Test)

Example 2 with InterruptedRuntimeException

use of net.openhft.chronicle.core.threads.InterruptedRuntimeException in project Chronicle-Queue by OpenHFT.

the class TSQueueLock method acquireLock.

/**
 * Stores current TID and PID to table store, and any other thread trying to acquire lock will wait for
 * <code>chronicle.queue.lock.timeoutMS</code> millis (default is 30000) for the lock to be released, and if it is not
 * able to lock, *overrides the lock*.
 */
@Override
public void acquireLock() {
    throwExceptionIfClosed();
    long tid = Thread.currentThread().getId();
    if (isLockHeldByCurrentThread(tid)) {
        return;
    }
    int count = 0;
    long lockValueFromTid = getLockValueFromTid(tid);
    long value = lock.getVolatileValue();
    Pauser tlPauser = pauser.get();
    try {
        while (!lock.compareAndSwapValue(UNLOCKED, lockValueFromTid)) {
            if (count++ > 1000 && Thread.currentThread().isInterrupted())
                throw new InterruptedRuntimeException("Interrupted");
            tlPauser.pause(timeout, TimeUnit.MILLISECONDS);
            value = lock.getVolatileValue();
        }
    } catch (TimeoutException e) {
        warnAndForceUnlock("Couldn't acquire lock", value);
        acquireLock();
    } finally {
        tlPauser.reset();
    }
}
Also used : InterruptedRuntimeException(net.openhft.chronicle.core.threads.InterruptedRuntimeException) TimingPauser(net.openhft.chronicle.threads.TimingPauser) Pauser(net.openhft.chronicle.threads.Pauser) TimeoutException(java.util.concurrent.TimeoutException) UnrecoverableTimeoutException(net.openhft.chronicle.wire.UnrecoverableTimeoutException)

Example 3 with InterruptedRuntimeException

use of net.openhft.chronicle.core.threads.InterruptedRuntimeException in project Chronicle-Queue by OpenHFT.

the class TSQueueLock method waitForLock.

/**
 * checks if current thread holds lock. If not, it will wait for <code>chronicle.queue.lock.timeoutMS</code> millis for the lock to be
 * released, and if it is not after timeout, forcibly unlocks and continues.
 */
// TODO combine logic for acquireLock with this method so recovery is consistent.
@Override
public void waitForLock() {
    throwExceptionIfClosed();
    long tid = Thread.currentThread().getId();
    if (isLockHeldByCurrentThread(tid))
        return;
    long value = lock.getVolatileValue();
    Pauser tlPauser = pauser.get();
    try {
        while (value != UNLOCKED) {
            if (Thread.currentThread().isInterrupted())
                throw new InterruptedRuntimeException("Interrupted");
            tlPauser.pause(timeout, TimeUnit.MILLISECONDS);
            value = lock.getVolatileValue();
        }
    } catch (TimeoutException e) {
        warnAndForceUnlock("Queue lock is still held", value);
        // try again.
        waitForLock();
    } catch (NullPointerException ex) {
        if (!tableStore.isClosed())
            throw ex;
        throw new IllegalStateException("The table store is closed!", ex);
    } finally {
        tlPauser.reset();
    }
}
Also used : InterruptedRuntimeException(net.openhft.chronicle.core.threads.InterruptedRuntimeException) TimingPauser(net.openhft.chronicle.threads.TimingPauser) Pauser(net.openhft.chronicle.threads.Pauser) TimeoutException(java.util.concurrent.TimeoutException) UnrecoverableTimeoutException(net.openhft.chronicle.wire.UnrecoverableTimeoutException)

Example 4 with InterruptedRuntimeException

use of net.openhft.chronicle.core.threads.InterruptedRuntimeException in project Chronicle-Queue by OpenHFT.

the class TableStoreWriteLock method lock.

/**
 * Guaranteed to succeed in getting the lock (may involve timeout and recovery) or else throw.
 * <p>This is not re-entrant i.e. if you lock and try and lock again it will timeout and recover
 */
@Override
public void lock() {
    throwExceptionIfClosed();
    assert checkNotAlreadyLocked();
    long currentLockValue = 0;
    TimingPauser tlPauser = pauser.get();
    try {
        currentLockValue = lock.getVolatileValue();
        while (!lock.compareAndSwapValue(UNLOCKED, PID)) {
            if (Thread.currentThread().isInterrupted())
                throw new InterruptedRuntimeException("Interrupted for the lock file:" + path);
            tlPauser.pause(timeout, TimeUnit.MILLISECONDS);
            currentLockValue = lock.getVolatileValue();
        }
        // noinspection ConstantConditions,AssertWithSideEffects
        assert (lockedByThread = Thread.currentThread()) != null && (lockedHere = new StackTrace()) != null;
    // success
    } catch (TimeoutException e) {
        final String lockedBy = getLockedBy(currentLockValue);
        final String warningMsg = "Couldn't acquire write lock " + "after " + timeout + " ms " + "for the lock file:" + path + ". " + "Lock was held by " + lockedBy;
        if (forceUnlockOnTimeoutWhen == UnlockMode.NEVER)
            throw new UnrecoverableTimeoutException(new IllegalStateException(warningMsg + UNLOCK_MAIN_MSG));
        else if (forceUnlockOnTimeoutWhen == UnlockMode.LOCKING_PROCESS_DEAD) {
            if (forceUnlockIfProcessIsDead())
                lock();
            else
                throw new UnrecoverableTimeoutException(new IllegalStateException(warningMsg + UNLOCK_MAIN_MSG));
        } else {
            warn().on(getClass(), warningMsg + UNLOCKING_FORCIBLY_MSG);
            forceUnlock(currentLockValue);
            lock();
        }
    } finally {
        tlPauser.reset();
    }
}
Also used : UnrecoverableTimeoutException(net.openhft.chronicle.wire.UnrecoverableTimeoutException) InterruptedRuntimeException(net.openhft.chronicle.core.threads.InterruptedRuntimeException) TimingPauser(net.openhft.chronicle.threads.TimingPauser) StackTrace(net.openhft.chronicle.core.StackTrace) UnrecoverableTimeoutException(net.openhft.chronicle.wire.UnrecoverableTimeoutException) TimeoutException(java.util.concurrent.TimeoutException)

Aggregations

InterruptedRuntimeException (net.openhft.chronicle.core.threads.InterruptedRuntimeException)4 TimeoutException (java.util.concurrent.TimeoutException)3 TimingPauser (net.openhft.chronicle.threads.TimingPauser)3 UnrecoverableTimeoutException (net.openhft.chronicle.wire.UnrecoverableTimeoutException)3 Pauser (net.openhft.chronicle.threads.Pauser)2 File (java.io.File)1 AccessDeniedException (java.nio.file.AccessDeniedException)1 ArrayList (java.util.ArrayList)1 Collections (java.util.Collections)1 List (java.util.List)1 BiConsumer (java.util.function.BiConsumer)1 MethodReader (net.openhft.chronicle.bytes.MethodReader)1 Jvm (net.openhft.chronicle.core.Jvm)1 OS (net.openhft.chronicle.core.OS)1 StackTrace (net.openhft.chronicle.core.StackTrace)1 RequiredForClient (net.openhft.chronicle.core.annotation.RequiredForClient)1 IOTools (net.openhft.chronicle.core.io.IOTools)1 net.openhft.chronicle.queue (net.openhft.chronicle.queue)1 SingleChronicleQueueBuilder.binary (net.openhft.chronicle.queue.impl.single.SingleChronicleQueueBuilder.binary)1 DocumentContext (net.openhft.chronicle.wire.DocumentContext)1