Search in sources :

Example 11 with BKTransmitException

use of org.apache.distributedlog.exceptions.BKTransmitException in project bookkeeper by apache.

the class BKLogSegmentWriter method transmit.

/**
 * Transmit the current buffer to bookkeeper.
 * Synchronised at the class. #write() and #flush()
 * are never called at the same time.
 * NOTE: This method should only throw known exceptions so that we don't accidentally
 *       add new code that throws in an inappropriate place.
 *
 * @return a transmit future for caller to wait for transmit result if we transmit successfully,
 *         null if no data to transmit
 * @throws BKTransmitException if the segment writer is already in error state
 * @throws LockingException if the segment writer lost lock before transmit
 * @throws WriteException if failed to create the envelope for the data to transmit
 * @throws InvalidEnvelopedEntryException when built an invalid enveloped entry
 */
private CompletableFuture<Integer> transmit() throws BKTransmitException, LockingException, WriteException, InvalidEnvelopedEntryException {
    EntryBuffer recordSetToTransmit;
    transmitLock.lock();
    try {
        synchronized (this) {
            checkWriteLock();
            // stream has encountered an error and cannot be written to.
            if (!transmitResultUpdater.compareAndSet(this, BKException.Code.OK, BKException.Code.OK)) {
                LOG.error("Log Segment {} Trying to write to an errored stream; Error is {}", fullyQualifiedLogSegment, BKException.getMessage(transmitResultUpdater.get(this)));
                throw new BKTransmitException("Trying to write to an errored stream;" + " Error code : (" + transmitResultUpdater.get(this) + ") " + BKException.getMessage(transmitResultUpdater.get(this)), transmitResultUpdater.get(this));
            }
            if (recordSetWriter.getNumRecords() == 0) {
                // Control flushes always have at least the control record to flush
                transmitDataMisses.inc();
                return null;
            }
            recordSetToTransmit = recordSetWriter;
            recordSetWriter = newRecordSetWriter();
            outstandingBytes = 0;
            if (recordSetToTransmit.hasUserRecords()) {
                numBytes += recordSetToTransmit.getNumBytes();
                numFlushesSinceRestart++;
            }
        }
        ByteBuf toSend;
        try {
            toSend = recordSetToTransmit.getBuffer();
            FailpointUtils.checkFailPoint(FailpointUtils.FailPointName.FP_TransmitFailGetBuffer);
        } catch (IOException e) {
            if (e instanceof InvalidEnvelopedEntryException) {
                alertStatsLogger.raise("Invalid enveloped entry for segment {} : ", fullyQualifiedLogSegment, e);
            }
            LOG.error("Exception while enveloping entries for segment: {}", new Object[] { fullyQualifiedLogSegment }, e);
            // If a write fails here, we need to set the transmit result to an error so that
            // no future writes go through and violate ordering guarantees.
            transmitResultUpdater.set(this, BKException.Code.WriteException);
            if (e instanceof InvalidEnvelopedEntryException) {
                alertStatsLogger.raise("Invalid enveloped entry for segment {} : ", fullyQualifiedLogSegment, e);
                throw (InvalidEnvelopedEntryException) e;
            } else {
                throw new WriteException(streamName, "Envelope Error");
            }
        }
        synchronized (this) {
            // update the transmit timestamp
            lastTransmitNanos = MathUtils.nowInNano();
            BKTransmitPacket packet = new BKTransmitPacket(recordSetToTransmit);
            packetPrevious = packet;
            entryWriter.asyncAddEntry(toSend, this, packet);
            if (recordSetToTransmit.hasUserRecords()) {
                transmitDataSuccesses.inc();
            } else {
                transmitControlSuccesses.inc();
            }
            lastTransmit.reset().start();
            outstandingTransmitsUpdater.incrementAndGet(this);
            controlFlushNeeded = false;
            return packet.getTransmitFuture();
        }
    } finally {
        transmitLock.unlock();
    }
}
Also used : WriteException(org.apache.distributedlog.exceptions.WriteException) BKTransmitException(org.apache.distributedlog.exceptions.BKTransmitException) MutableObject(org.apache.commons.lang3.mutable.MutableObject) IOException(java.io.IOException) ByteBuf(io.netty.buffer.ByteBuf) InvalidEnvelopedEntryException(org.apache.distributedlog.exceptions.InvalidEnvelopedEntryException)

Example 12 with BKTransmitException

use of org.apache.distributedlog.exceptions.BKTransmitException in project bookkeeper by apache.

the class BKLogSegmentEntryReader method readEntriesFromReadAheadCache.

private void readEntriesFromReadAheadCache(PendingReadRequest nextRequest) {
    while (!nextRequest.hasReadEnoughEntries()) {
        CacheEntry entry;
        boolean hitEndOfLogSegment;
        synchronized (this) {
            entry = readAheadEntries.peek();
            hitEndOfLogSegment = (null == entry) && isEndOfLogSegment();
        }
        // reach end of log segment
        if (hitEndOfLogSegment) {
            completeExceptionally(new EndOfLogSegmentException(getSegment().getZNodeName()), false);
            return;
        }
        if (null == entry) {
            return;
        }
        // entry is not complete yet.
        if (!entry.isDone()) {
            // we already reached end of the log segment
            if (isEndOfLogSegment(entry.getEntryId())) {
                completeExceptionally(new EndOfLogSegmentException(getSegment().getZNodeName()), false);
            }
            return;
        }
        if (entry.isSuccess()) {
            CacheEntry removedEntry = readAheadEntries.poll();
            try {
                if (entry != removedEntry) {
                    DLIllegalStateException ise = new DLIllegalStateException("Unexpected condition at reading from " + getSegment());
                    completeExceptionally(ise, false);
                    return;
                }
                try {
                    // the reference is retained on `entry.getEntry()`.
                    // Entry.Reader is responsible for releasing it.
                    nextRequest.addEntry(processReadEntry(entry.getEntry()));
                } catch (IOException e) {
                    completeExceptionally(e, false);
                    return;
                }
            } finally {
                removedEntry.release();
            }
        } else if (skipBrokenEntries && BKException.Code.DigestMatchException == entry.getRc()) {
            // skip this entry and move forward
            skippedBrokenEntriesCounter.inc();
            CacheEntry removedEntry = readAheadEntries.poll();
            removedEntry.release();
            continue;
        } else {
            completeExceptionally(new BKTransmitException("Encountered issue on reading entry " + entry.getEntryId() + " @ log segment " + getSegment(), entry.getRc()), false);
            return;
        }
    }
}
Also used : EndOfLogSegmentException(org.apache.distributedlog.exceptions.EndOfLogSegmentException) BKTransmitException(org.apache.distributedlog.exceptions.BKTransmitException) DLIllegalStateException(org.apache.distributedlog.exceptions.DLIllegalStateException) IOException(java.io.IOException)

Aggregations

BKTransmitException (org.apache.distributedlog.exceptions.BKTransmitException)12 IOException (java.io.IOException)6 CompletableFuture (java.util.concurrent.CompletableFuture)5 Test (org.junit.Test)5 LedgerHandle (org.apache.bookkeeper.client.LedgerHandle)4 ZKDistributedLock (org.apache.distributedlog.lock.ZKDistributedLock)4 ArrayList (java.util.ArrayList)3 WriteCancelledException (org.apache.distributedlog.exceptions.WriteCancelledException)3 WriteException (org.apache.distributedlog.exceptions.WriteException)3 InvalidEnvelopedEntryException (org.apache.distributedlog.exceptions.InvalidEnvelopedEntryException)2 LogSegmentRandomAccessEntryReader (org.apache.distributedlog.logsegment.LogSegmentRandomAccessEntryReader)2 ByteBuf (io.netty.buffer.ByteBuf)1 List (java.util.List)1 AsyncCallback (org.apache.bookkeeper.client.AsyncCallback)1 BKException (org.apache.bookkeeper.client.BKException)1 BookKeeper (org.apache.bookkeeper.client.BookKeeper)1 LedgerEntry (org.apache.bookkeeper.client.LedgerEntry)1 MutableObject (org.apache.commons.lang3.mutable.MutableObject)1 Entry (org.apache.distributedlog.Entry)1 AsyncLogWriter (org.apache.distributedlog.api.AsyncLogWriter)1