Search in sources :

Example 1 with ILogData

use of org.corfudb.protocols.wireprotocol.ILogData in project CorfuDB by CorfuDB.

the class QuorumReplicationProtocol method peek.

/** {@inheritDoc} */
@Override
public ILogData peek(Layout layout, long address) {
    int numUnits = layout.getSegmentLength(address);
    log.trace("Peek[{}]: quorum {}/{}", address, numUnits, numUnits);
    try {
        ReadResponse readResponse = null;
        try {
            CompletableFuture<ReadResponse>[] futures = new CompletableFuture[numUnits];
            for (int i = 0; i < numUnits; i++) {
                futures[i] = layout.getLogUnitClient(address, i).read(address);
            }
            QuorumFuturesFactory.CompositeFuture<ReadResponse> future = QuorumFuturesFactory.getQuorumFuture(new ReadResponseComparator(address), futures);
            readResponse = CFUtils.getUninterruptibly(future, QuorumUnreachableException.class);
        } catch (QuorumUnreachableException e) {
            e.printStackTrace();
            log.debug(e.getMessage(), e);
            return null;
        }
        if (readResponse != null) {
            LogData result = readResponse.getReadSet().get(address);
            if (result != null && !isEmptyType(result.getType())) {
                return result;
            }
        }
        return null;
    } catch (RuntimeException e) {
        throw e;
    }
}
Also used : ILogData(org.corfudb.protocols.wireprotocol.ILogData) LogData(org.corfudb.protocols.wireprotocol.LogData) CompletableFuture(java.util.concurrent.CompletableFuture) QuorumFuturesFactory(org.corfudb.runtime.view.QuorumFuturesFactory) ReadResponse(org.corfudb.protocols.wireprotocol.ReadResponse) QuorumUnreachableException(org.corfudb.runtime.exceptions.QuorumUnreachableException)

Example 2 with ILogData

use of org.corfudb.protocols.wireprotocol.ILogData in project CorfuDB by CorfuDB.

the class QuorumReplicationProtocol method write.

/** {@inheritDoc} */
@Override
public void write(Layout layout, ILogData data) throws OverwriteException {
    final long globalAddress = data.getGlobalAddress();
    log.debug("Write at {} " + globalAddress);
    IMetadata.DataRank rank = new IMetadata.DataRank(0);
    QuorumFuturesFactory.CompositeFuture<Boolean> future = null;
    data.setRank(rank);
    try {
        try (ILogData.SerializationHandle sh = data.getSerializedForm()) {
            future = getWriteFuture(layout, sh.getSerialized());
            CFUtils.getUninterruptibly(future, QuorumUnreachableException.class, OverwriteException.class, DataOutrankedException.class);
        }
    } catch (OverwriteException e) {
        log.error("Client implementation error, race in phase 1. Broken sequencer, data consistency in danger.");
        throw e;
    } catch (LogUnitException | QuorumUnreachableException e) {
        if (future.containsThrowableFrom(DataOutrankedException.class) || future.containsThrowableFrom(ValueAdoptedException.class)) {
            // we are competing with other client that writes the same data or fills a hole
            boolean adopted = recoveryWrite(layout, data);
            if (!adopted) {
                return;
            }
        }
        throw new OverwriteException();
    }
}
Also used : ILogData(org.corfudb.protocols.wireprotocol.ILogData) QuorumFuturesFactory(org.corfudb.runtime.view.QuorumFuturesFactory) QuorumUnreachableException(org.corfudb.runtime.exceptions.QuorumUnreachableException) IMetadata(org.corfudb.protocols.wireprotocol.IMetadata) OverwriteException(org.corfudb.runtime.exceptions.OverwriteException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) LogUnitException(org.corfudb.runtime.exceptions.LogUnitException)

Example 3 with ILogData

use of org.corfudb.protocols.wireprotocol.ILogData in project CorfuDB by CorfuDB.

the class QuorumReplicationProtocol method recoveryWrite.

private boolean recoveryWrite(Layout layout, ILogData logData) {
    long address = logData.getGlobalAddress();
    log.debug("Recovery write at {} " + address);
    Holder<ILogData> dh = new Holder<>(logData);
    AtomicBoolean otherValueAdopted = new AtomicBoolean(false);
    AtomicInteger retryCount = new AtomicInteger(0);
    if (logData.getRank() == null) {
        logData.setRank(new IMetadata.DataRank(0));
    }
    try {
        IRetry.build(ExponentialBackoffRetry.class, () -> {
            QuorumFuturesFactory.CompositeFuture<Boolean> future = null;
            try {
                log.debug("Recovery write loop for " + log);
                // increment the rank
                dh.getRef().releaseBuffer();
                dh.getRef().setRank(dh.getRef().getRank().buildHigherRank());
                // peek for existing
                if (retryCount.getAndIncrement() > 0) {
                    try {
                        return holeFillPolicy.peekUntilHoleFillRequired(address, a -> peek(layout, a));
                    } catch (HoleFillRequiredException e) {
                        log.debug(e.getMessage(), e);
                    // continuing
                    }
                }
                // phase 1
                try (ILogData.SerializationHandle ph1 = createEmptyData(dh.getRef().getGlobalAddress(), DataType.RANK_ONLY, dh.getRef().getRank())) {
                    future = getWriteFuture(layout, ph1.getSerialized());
                    CFUtils.getUninterruptibly(future, QuorumUnreachableException.class, OverwriteException.class, DataOutrankedException.class);
                } catch (LogUnitException | QuorumUnreachableException e) {
                    e.printStackTrace();
                    ReadResponse rr = getAdoptedValueWithHighestRankIfPresent(address, future.getThrowables());
                    if (rr != null) {
                        // check
                        LogData logDataExisting = rr.getReadSet().get(address);
                        logDataExisting.releaseBuffer();
                        logDataExisting.setRank(dh.getRef().getRank());
                        dh.setRef(logDataExisting.getSerializedForm().getSerialized());
                        otherValueAdopted.set(true);
                    // value adopted - continue on phase 2
                    } else {
                        throw e;
                    }
                }
                // phase 2 - only if exception is not thrown from phase 1
                future = getWriteFuture(layout, dh.getRef());
                CFUtils.getUninterruptibly(future, QuorumUnreachableException.class, OverwriteException.class, DataOutrankedException.class);
                log.trace("Write done[{}]: {}", address);
                return dh.getRef();
            } catch (QuorumUnreachableException | DataOutrankedException e) {
                e.printStackTrace();
                throw new RetryNeededException();
            } catch (RuntimeException e) {
                e.printStackTrace();
                throw e;
            }
        }).setOptions(WRITE_RETRY_SETTINGS).run();
        return otherValueAdopted.get();
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        throw new RuntimeException("interrupted", e);
    } catch (RuntimeException e) {
        throw e;
    }
}
Also used : ILogData(org.corfudb.protocols.wireprotocol.ILogData) ILogData(org.corfudb.protocols.wireprotocol.ILogData) LogData(org.corfudb.protocols.wireprotocol.LogData) QuorumFuturesFactory(org.corfudb.runtime.view.QuorumFuturesFactory) QuorumUnreachableException(org.corfudb.runtime.exceptions.QuorumUnreachableException) Holder(org.corfudb.util.Holder) HoleFillRequiredException(org.corfudb.runtime.exceptions.HoleFillRequiredException) RetryNeededException(org.corfudb.util.retry.RetryNeededException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) IMetadata(org.corfudb.protocols.wireprotocol.IMetadata) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ReadResponse(org.corfudb.protocols.wireprotocol.ReadResponse) DataOutrankedException(org.corfudb.runtime.exceptions.DataOutrankedException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) LogUnitException(org.corfudb.runtime.exceptions.LogUnitException)

Example 4 with ILogData

use of org.corfudb.protocols.wireprotocol.ILogData in project CorfuDB by CorfuDB.

the class QuorumReplicationProtocol method createEmptyData.

private ILogData.SerializationHandle createEmptyData(long position, DataType type, IMetadata.DataRank rank) {
    ILogData data = new LogData(type);
    data.setRank(rank);
    data.setGlobalAddress(position);
    return data.getSerializedForm();
}
Also used : ILogData(org.corfudb.protocols.wireprotocol.ILogData) ILogData(org.corfudb.protocols.wireprotocol.ILogData) LogData(org.corfudb.protocols.wireprotocol.LogData)

Example 5 with ILogData

use of org.corfudb.protocols.wireprotocol.ILogData in project CorfuDB by CorfuDB.

the class AbstractContextStreamView method getNextEntries.

/** Retrieve the next entries in the stream, given the context.
     *
     * This function is designed to implement a bulk read. In a bulk read,
     * one of the entries may cause the context to change - the implementation
     * should check if the entry changes the context and stop reading
     * if this occurs, returning the entry that caused contextCheckFn to return
     * true.
     *
     * The default implementation simply calls getNextEntry.
     *
     * @param context           The context to retrieve the next entry from.
     * @param maxGlobal         The maximum global address to read to.
     * @param contextCheckFn    A function which returns true if the entry changes the stream context.
     * @return
     */
protected List<ILogData> getNextEntries(T context, long maxGlobal, Function<ILogData, Boolean> contextCheckFn) {
    final List<ILogData> dataList = new ArrayList<>();
    ILogData thisData;
    while ((thisData = getNextEntry(context, maxGlobal)) != null) {
        // Add this read to the list of reads to return.
        dataList.add(thisData);
        // Update the pointer, because the underlying implementation
        // will expect it to be updated when we call getNextEntry() again.
        updatePointer(thisData);
        // If this entry changes the context, don't continue reading.
        if (contextCheckFn.apply(thisData)) {
            break;
        }
    }
    return dataList;
}
Also used : ILogData(org.corfudb.protocols.wireprotocol.ILogData)

Aggregations

ILogData (org.corfudb.protocols.wireprotocol.ILogData)27 LogData (org.corfudb.protocols.wireprotocol.LogData)9 Test (org.junit.Test)9 CorfuRuntime (org.corfudb.runtime.CorfuRuntime)8 Layout (org.corfudb.runtime.view.Layout)4 UUID (java.util.UUID)3 Nonnull (javax.annotation.Nonnull)3 SMREntry (org.corfudb.protocols.logprotocol.SMREntry)3 ReadResponse (org.corfudb.protocols.wireprotocol.ReadResponse)3 OverwriteException (org.corfudb.runtime.exceptions.OverwriteException)3 QuorumUnreachableException (org.corfudb.runtime.exceptions.QuorumUnreachableException)3 AbstractViewTest (org.corfudb.runtime.view.AbstractViewTest)3 QuorumFuturesFactory (org.corfudb.runtime.view.QuorumFuturesFactory)3 IStreamView (org.corfudb.runtime.view.stream.IStreamView)3 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 MultiObjectSMREntry (org.corfudb.protocols.logprotocol.MultiObjectSMREntry)2 MultiSMREntry (org.corfudb.protocols.logprotocol.MultiSMREntry)2 IMetadata (org.corfudb.protocols.wireprotocol.IMetadata)2 LogUnitClient (org.corfudb.runtime.clients.LogUnitClient)2 DataOutrankedException (org.corfudb.runtime.exceptions.DataOutrankedException)2