Search in sources :

Example 1 with ReadResponse

use of org.corfudb.protocols.wireprotocol.ReadResponse 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 ReadResponse

use of org.corfudb.protocols.wireprotocol.ReadResponse 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 3 with ReadResponse

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

the class LogUnitClientTest method valueCanBeAdopted.

@Test
public void valueCanBeAdopted() throws ExecutionException, InterruptedException {
    byte[] testString = "hello world".getBytes();
    client.write(0, Collections.<UUID>emptySet(), new IMetadata.DataRank(1), testString, Collections.emptyMap()).get();
    LogData r = client.read(0).get().getReadSet().get(0L);
    assertThat(r.getType()).isEqualTo(DataType.DATA);
    assertThat(r.getPayload(new CorfuRuntime())).isEqualTo(testString);
    try {
        ILogData data = createEmptyData(0, DataType.RANK_ONLY, new IMetadata.DataRank(2)).getSerialized();
        client.write(data).get();
        fail();
    } catch (Exception e) {
        // expected
        assertEquals(ValueAdoptedException.class, e.getCause().getClass());
        ValueAdoptedException ex = (ValueAdoptedException) e.getCause();
        ReadResponse read = ex.getReadResponse();
        LogData log = read.getReadSet().get(0l);
        assertThat(log.getType()).isEqualTo(DataType.DATA);
        assertThat(log.getPayload(new CorfuRuntime())).isEqualTo(testString);
        ;
    }
    r = client.read(0).get().getReadSet().get(0L);
    assertThat(r.getType()).isEqualTo(DataType.DATA);
    assertThat(r.getPayload(new CorfuRuntime())).isEqualTo(testString);
}
Also used : ILogData(org.corfudb.protocols.wireprotocol.ILogData) ILogData(org.corfudb.protocols.wireprotocol.ILogData) LogData(org.corfudb.protocols.wireprotocol.LogData) ReadResponse(org.corfudb.protocols.wireprotocol.ReadResponse) CorfuRuntime(org.corfudb.runtime.CorfuRuntime) UUID(java.util.UUID) DataCorruptionException(org.corfudb.runtime.exceptions.DataCorruptionException) OverwriteException(org.corfudb.runtime.exceptions.OverwriteException) TrimmedException(org.corfudb.runtime.exceptions.TrimmedException) DataOutrankedException(org.corfudb.runtime.exceptions.DataOutrankedException) ValueAdoptedException(org.corfudb.runtime.exceptions.ValueAdoptedException) ExecutionException(java.util.concurrent.ExecutionException) ValueAdoptedException(org.corfudb.runtime.exceptions.ValueAdoptedException) Test(org.junit.Test)

Example 4 with ReadResponse

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

the class QuorumReplicationProtocol method getAdoptedValueWithHighestRankIfPresent.

private ReadResponse getAdoptedValueWithHighestRankIfPresent(Long position, Set<Throwable> throwables) {
    ReadResponse result = null;
    IMetadata.DataRank maxRank = null;
    for (Throwable t : throwables) {
        if (t instanceof ValueAdoptedException) {
            ValueAdoptedException ve = (ValueAdoptedException) t;
            ReadResponse r = ve.getReadResponse();
            LogData ld = r.getReadSet().get(position);
            if (maxRank == null || maxRank.compareTo(ld.getRank()) < 0) {
                maxRank = ld.getRank();
                result = r;
            }
        }
    }
    return result;
}
Also used : ILogData(org.corfudb.protocols.wireprotocol.ILogData) LogData(org.corfudb.protocols.wireprotocol.LogData) IMetadata(org.corfudb.protocols.wireprotocol.IMetadata) ReadResponse(org.corfudb.protocols.wireprotocol.ReadResponse) ValueAdoptedException(org.corfudb.runtime.exceptions.ValueAdoptedException)

Example 5 with ReadResponse

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

the class StreamLogWithRankedAddressSpace method assertAppendPermittedUnsafe.

/**
     * Check whether the data can be appended to a given log address.
     * Note that it is not permitted multiple threads to access the same log address
     * concurrently through this method, this method does not lock or synchronize.
     * This method needs
     * @param address
     * @param newEntry
     * @throws DataOutrankedException if the log entry cannot be assigned to this log address as there is a data with higher rank
     * @throws ValueAdoptedException if the new message is a proposal during the two phase recovery write and there is an existing
     * data at this log address already.
     * @throw OverwriteException if the new data is with rank 0 (not from recovery write). This can happen only if there is a bug in the client implementation.
     */
default default void assertAppendPermittedUnsafe(long address, LogData newEntry) throws DataOutrankedException, ValueAdoptedException {
    LogData oldEntry = read(address);
    if (oldEntry.getType() == DataType.EMPTY) {
        return;
    }
    if (newEntry.getRank().getRank() == 0) {
        // data consistency in danger
        throw new OverwriteException();
    }
    int compare = newEntry.getRank().compareTo(oldEntry.getRank());
    if (compare < 0) {
        throw new DataOutrankedException();
    }
    if (compare > 0) {
        if (newEntry.getType() == DataType.RANK_ONLY && oldEntry.getType() != DataType.RANK_ONLY) {
            // the new data is a proposal, the other data is not, so the old value should be adopted
            ReadResponse resp = new ReadResponse();
            resp.put(address, oldEntry);
            throw new ValueAdoptedException(resp);
        } else {
            return;
        }
    }
}
Also used : LogData(org.corfudb.protocols.wireprotocol.LogData) ReadResponse(org.corfudb.protocols.wireprotocol.ReadResponse) DataOutrankedException(org.corfudb.runtime.exceptions.DataOutrankedException) OverwriteException(org.corfudb.runtime.exceptions.OverwriteException) ValueAdoptedException(org.corfudb.runtime.exceptions.ValueAdoptedException)

Aggregations

LogData (org.corfudb.protocols.wireprotocol.LogData)5 ReadResponse (org.corfudb.protocols.wireprotocol.ReadResponse)5 ILogData (org.corfudb.protocols.wireprotocol.ILogData)4 DataOutrankedException (org.corfudb.runtime.exceptions.DataOutrankedException)3 ValueAdoptedException (org.corfudb.runtime.exceptions.ValueAdoptedException)3 IMetadata (org.corfudb.protocols.wireprotocol.IMetadata)2 OverwriteException (org.corfudb.runtime.exceptions.OverwriteException)2 QuorumUnreachableException (org.corfudb.runtime.exceptions.QuorumUnreachableException)2 QuorumFuturesFactory (org.corfudb.runtime.view.QuorumFuturesFactory)2 UUID (java.util.UUID)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 ExecutionException (java.util.concurrent.ExecutionException)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 CorfuRuntime (org.corfudb.runtime.CorfuRuntime)1 DataCorruptionException (org.corfudb.runtime.exceptions.DataCorruptionException)1 HoleFillRequiredException (org.corfudb.runtime.exceptions.HoleFillRequiredException)1 LogUnitException (org.corfudb.runtime.exceptions.LogUnitException)1 TrimmedException (org.corfudb.runtime.exceptions.TrimmedException)1 Holder (org.corfudb.util.Holder)1