Search in sources :

Example 1 with ObjectClosedException

use of io.pravega.common.ObjectClosedException in project pravega by pravega.

the class DurableLog method doStop.

@Override
protected void doStop() {
    long traceId = LoggerHelpers.traceEnterWithContext(log, traceObjectId, "doStop");
    log.info("{}: Stopping.", this.traceObjectId);
    Services.stopAsync(this.operationProcessor, this.executor).whenCompleteAsync((r, ex) -> {
        cancelTailReads();
        this.durableDataLog.close();
        Throwable cause = this.stopException.get();
        if (cause == null && this.operationProcessor.state() == State.FAILED) {
            cause = this.operationProcessor.failureCause();
        }
        // Terminate the delayed start future now, if still active.
        this.delayedStart.completeExceptionally(cause == null ? new ObjectClosedException(this) : cause);
        if (cause == null) {
            // Normal shutdown.
            notifyStopped();
        } else {
            // Shutdown caused by some failure.
            notifyFailed(cause);
        }
        log.info("{}: Stopped.", this.traceObjectId);
        LoggerHelpers.traceLeave(log, traceObjectId, "doStop", traceId);
    }, this.executor).exceptionally(ex -> {
        notifyFailed(ex);
        return null;
    });
}
Also used : ObjectClosedException(io.pravega.common.ObjectClosedException) IllegalContainerStateException(io.pravega.segmentstore.server.IllegalContainerStateException) SneakyThrows(lombok.SneakyThrows) Retry(io.pravega.common.util.Retry) StorageMetadataCheckpointOperation(io.pravega.segmentstore.server.logs.operations.StorageMetadataCheckpointOperation) ProbeOperation(io.pravega.segmentstore.server.logs.operations.ProbeOperation) Exceptions(io.pravega.common.Exceptions) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) LogAddress(io.pravega.segmentstore.storage.LogAddress) StreamingException(io.pravega.segmentstore.contracts.StreamingException) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) UpdateableContainerMetadata(io.pravega.segmentstore.server.UpdateableContainerMetadata) SequencedItemList(io.pravega.common.util.SequencedItemList) Duration(java.time.Duration) AbstractService(com.google.common.util.concurrent.AbstractService) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) Operation(io.pravega.segmentstore.server.logs.operations.Operation) DataLogDisabledException(io.pravega.segmentstore.storage.DataLogDisabledException) LoggerHelpers(io.pravega.common.LoggerHelpers) Services(io.pravega.common.concurrent.Services) ContainerOfflineException(io.pravega.segmentstore.server.ContainerOfflineException) DurableDataLog(io.pravega.segmentstore.storage.DurableDataLog) Iterator(java.util.Iterator) TimeoutTimer(io.pravega.common.TimeoutTimer) MetadataCheckpointOperation(io.pravega.segmentstore.server.logs.operations.MetadataCheckpointOperation) Set(java.util.Set) OperationLog(io.pravega.segmentstore.server.OperationLog) CompletionException(java.util.concurrent.CompletionException) ThreadSafe(javax.annotation.concurrent.ThreadSafe) GuardedBy(javax.annotation.concurrent.GuardedBy) Timer(io.pravega.common.Timer) Collectors(java.util.stream.Collectors) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) Preconditions(com.google.common.base.Preconditions) VisibleForTesting(com.google.common.annotations.VisibleForTesting) ReadIndex(io.pravega.segmentstore.server.ReadIndex) DataCorruptionException(io.pravega.segmentstore.server.DataCorruptionException) DurableDataLogFactory(io.pravega.segmentstore.storage.DurableDataLogFactory) Collections(java.util.Collections) Futures(io.pravega.common.concurrent.Futures) ObjectClosedException(io.pravega.common.ObjectClosedException)

Example 2 with ObjectClosedException

use of io.pravega.common.ObjectClosedException in project pravega by pravega.

the class MemoryStateUpdater method addToReadIndex.

/**
 * Registers the given operation in the ReadIndex.
 *
 * @param operation The operation to register.
 */
private void addToReadIndex(StorageOperation operation) {
    try {
        if (operation instanceof StreamSegmentAppendOperation) {
            // Record a StreamSegmentAppendOperation. Just in case, we also support this type of operation, but we need to
            // log a warning indicating so. This means we do not optimize memory properly, and we end up storing data
            // in two different places.
            StreamSegmentAppendOperation appendOperation = (StreamSegmentAppendOperation) operation;
            this.readIndex.append(appendOperation.getStreamSegmentId(), appendOperation.getStreamSegmentOffset(), appendOperation.getData());
        } else if (operation instanceof MergeTransactionOperation) {
            // Record a MergeTransactionOperation. We call beginMerge here, and the StorageWriter will call completeMerge.
            MergeTransactionOperation mergeOperation = (MergeTransactionOperation) operation;
            this.readIndex.beginMerge(mergeOperation.getStreamSegmentId(), mergeOperation.getStreamSegmentOffset(), mergeOperation.getTransactionSegmentId());
        } else {
            assert !(operation instanceof CachedStreamSegmentAppendOperation) : "attempted to add a CachedStreamSegmentAppendOperation to the ReadIndex";
        }
    } catch (ObjectClosedException | StreamSegmentNotExistsException ex) {
        // The Segment is in the process of being deleted. We usually end up in here because a concurrent delete
        // request has updated the metadata while we were executing.
        log.warn("Not adding operation '{}' to ReadIndex because it refers to a deleted StreamSegment.", operation);
    }
}
Also used : ObjectClosedException(io.pravega.common.ObjectClosedException) CachedStreamSegmentAppendOperation(io.pravega.segmentstore.server.logs.operations.CachedStreamSegmentAppendOperation) StreamSegmentAppendOperation(io.pravega.segmentstore.server.logs.operations.StreamSegmentAppendOperation) MergeTransactionOperation(io.pravega.segmentstore.server.logs.operations.MergeTransactionOperation) StreamSegmentNotExistsException(io.pravega.segmentstore.contracts.StreamSegmentNotExistsException) CachedStreamSegmentAppendOperation(io.pravega.segmentstore.server.logs.operations.CachedStreamSegmentAppendOperation)

Example 3 with ObjectClosedException

use of io.pravega.common.ObjectClosedException in project pravega by pravega.

the class RedirectedReadResultEntryTests method testRequestContent.

/**
 * Tests the ability to retry (and switch base) when a failure occurred in requestContent().
 */
@Test
public void testRequestContent() {
    // More than one retry (by design, it will only retry one time; the next time it will simply throw).
    FailureReadResultEntry f1 = new FailureReadResultEntry(ReadResultEntryType.Cache, 1, 1, () -> {
        throw new ObjectClosedException(this);
    });
    RedirectedReadResultEntry e1 = new TestRedirectedReadResultEntry(f1, 0, (o, l) -> f1, executorService());
    AssertExtensions.assertThrows("requestContent did not throw when attempting to retry more than once.", () -> e1.requestContent(TIMEOUT), ex -> ex instanceof ObjectClosedException);
    // Ineligible exception.
    FailureReadResultEntry f2 = new FailureReadResultEntry(ReadResultEntryType.Cache, 1, 1, () -> {
        throw new IllegalArgumentException();
    });
    RedirectedReadResultEntry e2 = new TestRedirectedReadResultEntry(f1, 0, (o, l) -> f2, executorService());
    AssertExtensions.assertThrows("requestContent did not throw when an ineligible exception got thrown.", () -> e2.requestContent(TIMEOUT), ex -> ex instanceof IllegalArgumentException);
    // Given back another Redirect.
    RedirectedReadResultEntry e3 = new TestRedirectedReadResultEntry(f1, 0, (o, l) -> e1, executorService());
    AssertExtensions.assertThrows("requestContent did not throw when retry yielded another RedirectReadResultEntry.", () -> e3.requestContent(TIMEOUT), ex -> ex instanceof ObjectClosedException);
    // Given redirect function fails.
    RedirectedReadResultEntry e4 = new TestRedirectedReadResultEntry(f1, 0, (o, l) -> {
        throw new IntentionalException();
    }, executorService());
    AssertExtensions.assertThrows("requestContent did not throw when retry failed.", () -> e4.requestContent(TIMEOUT), ex -> ex instanceof IntentionalException);
    // One that works correctly.
    AtomicBoolean requestInvoked = new AtomicBoolean();
    FailureReadResultEntry f5 = new FailureReadResultEntry(ReadResultEntryType.Cache, 2, 1, () -> requestInvoked.set(true));
    f1.setCompletionCallback(i -> {
    // Do nothing.
    });
    RedirectedReadResultEntry e5 = new TestRedirectedReadResultEntry(f1, 1, (o, l) -> f5, executorService());
    e5.requestContent(TIMEOUT);
    Assert.assertTrue("requestTimeout was not invoked for successful redirect.", requestInvoked.get());
    Assert.assertEquals("Unexpected result from getCompletionCallback after successful redirect.", f5.getCompletionCallback(), f1.getCompletionCallback());
    Assert.assertEquals("Unexpected result from getRequestedReadLength after successful redirect.", f5.getRequestedReadLength(), e5.getRequestedReadLength());
    Assert.assertEquals("Unexpected result from getStreamSegmentOffset after successful redirect.", f5.getStreamSegmentOffset(), e5.getStreamSegmentOffset());
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ObjectClosedException(io.pravega.common.ObjectClosedException) IntentionalException(io.pravega.test.common.IntentionalException) Test(org.junit.Test)

Example 4 with ObjectClosedException

use of io.pravega.common.ObjectClosedException in project pravega by pravega.

the class BookKeeperLogTests method testAutoCloseOnBookieFailure.

/**
 * Tests the ability to auto-close upon a permanent write failure caused by BookKeeper.
 *
 * @throws Exception If one got thrown.
 */
@Test
public void testAutoCloseOnBookieFailure() throws Exception {
    try (DurableDataLog log = createDurableDataLog()) {
        log.initialize(TIMEOUT);
        try {
            // Suspend a bookie (this will trigger write errors).
            stopFirstBookie();
            // First write should fail. Either a DataLogNotAvailableException (insufficient bookies) or
            // WriteFailureException (general unable to write) should be thrown.
            AssertExtensions.assertThrows("First write did not fail with the appropriate exception.", () -> log.append(new ByteArraySegment(getWriteData()), TIMEOUT), ex -> ex instanceof RetriesExhaustedException && (ex.getCause() instanceof DataLogNotAvailableException || isLedgerClosedException(ex.getCause())) || ex instanceof ObjectClosedException || ex instanceof CancellationException);
            // Subsequent writes should be rejected since the BookKeeperLog is now closed.
            AssertExtensions.assertThrows("Second write did not fail with the appropriate exception.", () -> log.append(new ByteArraySegment(getWriteData()), TIMEOUT), ex -> ex instanceof ObjectClosedException || ex instanceof CancellationException);
        } finally {
            // Don't forget to resume the bookie.
            restartFirstBookie();
        }
    }
}
Also used : DurableDataLog(io.pravega.segmentstore.storage.DurableDataLog) DataLogNotAvailableException(io.pravega.segmentstore.storage.DataLogNotAvailableException) ByteArraySegment(io.pravega.common.util.ByteArraySegment) RetriesExhaustedException(io.pravega.common.util.RetriesExhaustedException) CancellationException(java.util.concurrent.CancellationException) ObjectClosedException(io.pravega.common.ObjectClosedException) Test(org.junit.Test)

Example 5 with ObjectClosedException

use of io.pravega.common.ObjectClosedException in project pravega by pravega.

the class DataFrameBuilderTests method testAppendWithCommitFailure.

/**
 * Tests the case when the DataLog fails to commit random frames.
 * Commit errors should affect only the LogItems that were part of it. It should cause data to be dropped
 * and affected appends failed.
 * This should be done both with large and with small LogItems. Large items span multiple frames.
 */
@Test
public void testAppendWithCommitFailure() throws Exception {
    // Fail the commit to DurableDataLog after this many writes.
    int failAt = 7;
    List<TestLogItem> records = DataFrameTestHelpers.generateLogItems(RECORD_COUNT / 2, SMALL_RECORD_MIN_SIZE, SMALL_RECORD_MAX_SIZE, 0);
    records.addAll(DataFrameTestHelpers.generateLogItems(RECORD_COUNT / 2, LARGE_RECORD_MIN_SIZE, LARGE_RECORD_MAX_SIZE, records.size()));
    @Cleanup TestDurableDataLog dataLog = TestDurableDataLog.create(CONTAINER_ID, FRAME_SIZE, executorService());
    dataLog.initialize(TIMEOUT);
    val asyncInjector = new ErrorInjector<Exception>(count -> count >= failAt, IntentionalException::new);
    dataLog.setAppendErrorInjectors(null, asyncInjector);
    AtomicInteger failCount = new AtomicInteger();
    List<DataFrameBuilder.CommitArgs> successCommits = Collections.synchronizedList(new ArrayList<>());
    // Keep a reference to the builder (once created) so we can inspect its failure cause).
    val builderRef = new AtomicReference<DataFrameBuilder>();
    val attemptCount = new AtomicInteger();
    BiConsumer<Throwable, DataFrameBuilder.CommitArgs> errorCallback = (ex, a) -> {
        attemptCount.decrementAndGet();
        // Check that we actually did want an exception to happen.
        Throwable expectedError = Exceptions.unwrap(asyncInjector.getLastCycleException());
        Assert.assertNotNull("An error happened but none was expected: " + ex, expectedError);
        Throwable actualError = Exceptions.unwrap(ex);
        if (!(ex instanceof ObjectClosedException)) {
            // First failure.
            Assert.assertEquals("Unexpected error occurred upon commit.", expectedError, actualError);
        }
        if (builderRef.get().failureCause() != null) {
            checkFailureCause(builderRef.get(), ce -> ce instanceof IntentionalException);
        }
        failCount.incrementAndGet();
    };
    val args = new DataFrameBuilder.Args(ca -> attemptCount.incrementAndGet(), successCommits::add, errorCallback, executorService());
    try (DataFrameBuilder<TestLogItem> b = new DataFrameBuilder<>(dataLog, SERIALIZER, args)) {
        builderRef.set(b);
        try {
            for (val r : records) {
                b.append(r);
            }
            b.close();
        } catch (ObjectClosedException ex) {
            await(() -> b.failureCause() != null, 20);
            // If DataFrameBuilder is closed, then we must have had an exception thrown via the callback before.
            Assert.assertNotNull("DataFrameBuilder is closed, yet failure cause is not set yet.", b.failureCause());
            checkFailureCause(b, ce -> ce instanceof IntentionalException);
        }
    }
    await(() -> successCommits.size() >= attemptCount.get(), 20);
    // Read all committed items.
    val reader = new DataFrameReader<TestLogItem>(dataLog, new TestSerializer(), CONTAINER_ID);
    val readItems = new ArrayList<TestLogItem>();
    DataFrameRecord<TestLogItem> readItem;
    while ((readItem = reader.getNext()) != null) {
        readItems.add(readItem.getItem());
    }
    val lastCommitSeqNo = successCommits.stream().mapToLong(DataFrameBuilder.CommitArgs::getLastFullySerializedSequenceNumber).max().orElse(-1);
    val expectedItems = records.stream().filter(r -> r.getSequenceNumber() <= lastCommitSeqNo).collect(Collectors.toList());
    AssertExtensions.assertListEquals("Items read back do not match expected values.", expectedItems, readItems, TestLogItem::equals);
    // Read all entries in the Log and interpret them as DataFrames, then verify the records can be reconstructed.
    val frames = dataLog.getAllEntries(ri -> DataFrame.read(ri.getPayload(), ri.getLength(), ri.getAddress()));
    // Check the correctness of the commit callback.
    AssertExtensions.assertGreaterThan("Not enough Data Frames were generated.", 1, frames.size());
    Assert.assertEquals("Unexpected number of frames generated.", successCommits.size(), frames.size());
}
Also used : ObjectClosedException(io.pravega.common.ObjectClosedException) AssertExtensions(io.pravega.test.common.AssertExtensions) Exceptions(io.pravega.common.Exceptions) TimeoutException(java.util.concurrent.TimeoutException) Cleanup(lombok.Cleanup) HashMap(java.util.HashMap) AtomicReference(java.util.concurrent.atomic.AtomicReference) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Duration(java.time.Duration) BiConsumer(java.util.function.BiConsumer) Timeout(org.junit.rules.Timeout) Callbacks(io.pravega.common.function.Callbacks) Predicate(java.util.function.Predicate) IntentionalException(io.pravega.test.common.IntentionalException) lombok.val(lombok.val) IOException(java.io.IOException) Test(org.junit.Test) TestDurableDataLog(io.pravega.segmentstore.server.TestDurableDataLog) Collectors(java.util.stream.Collectors) ErrorInjector(io.pravega.test.common.ErrorInjector) List(java.util.List) Rule(org.junit.Rule) ByteArraySegment(io.pravega.common.util.ByteArraySegment) ThreadPooledTestSuite(io.pravega.test.common.ThreadPooledTestSuite) Comparator(java.util.Comparator) Assert(org.junit.Assert) Collections(java.util.Collections) TestDurableDataLog(io.pravega.segmentstore.server.TestDurableDataLog) ArrayList(java.util.ArrayList) Cleanup(lombok.Cleanup) IntentionalException(io.pravega.test.common.IntentionalException) lombok.val(lombok.val) ErrorInjector(io.pravega.test.common.ErrorInjector) AtomicReference(java.util.concurrent.atomic.AtomicReference) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ObjectClosedException(io.pravega.common.ObjectClosedException) Test(org.junit.Test)

Aggregations

ObjectClosedException (io.pravega.common.ObjectClosedException)10 Test (org.junit.Test)7 ArrayList (java.util.ArrayList)4 Cleanup (lombok.Cleanup)4 lombok.val (lombok.val)4 ByteArraySegment (io.pravega.common.util.ByteArraySegment)3 DurableDataLog (io.pravega.segmentstore.storage.DurableDataLog)3 AssertExtensions (io.pravega.test.common.AssertExtensions)3 IntentionalException (io.pravega.test.common.IntentionalException)3 Duration (java.time.Duration)3 Collections (java.util.Collections)3 Assert (org.junit.Assert)3 Rule (org.junit.Rule)3 Timeout (org.junit.rules.Timeout)3 Exceptions (io.pravega.common.Exceptions)2 Futures (io.pravega.common.concurrent.Futures)2 TestDurableDataLog (io.pravega.segmentstore.server.TestDurableDataLog)2 Operation (io.pravega.segmentstore.server.logs.operations.Operation)2 ProbeOperation (io.pravega.segmentstore.server.logs.operations.ProbeOperation)2 StreamSegmentAppendOperation (io.pravega.segmentstore.server.logs.operations.StreamSegmentAppendOperation)2