use of org.corfudb.runtime.exceptions.QuorumUnreachableException 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;
}
}
use of org.corfudb.runtime.exceptions.QuorumUnreachableException 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();
}
}
use of org.corfudb.runtime.exceptions.QuorumUnreachableException 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;
}
}
use of org.corfudb.runtime.exceptions.QuorumUnreachableException in project CorfuDB by CorfuDB.
the class SealServersHelper method waitForQuorum.
/**
* Wait for a quorum of responses from the completable futures.
*
* @param completableFutures An array of completableFutures of which a quorum is required.
* @throws QuorumUnreachableException Thrown if enough responses not received.
*/
public static void waitForQuorum(CompletableFuture<Boolean>[] completableFutures) throws QuorumUnreachableException {
Boolean success = false;
QuorumFuturesFactory.CompositeFuture<Boolean> quorumFuture = QuorumFuturesFactory.getQuorumFuture(Boolean::compareTo, completableFutures);
try {
success = quorumFuture.get();
} catch (ExecutionException | InterruptedException e) {
if (e.getCause() instanceof QuorumUnreachableException) {
throw (QuorumUnreachableException) e.getCause();
}
}
int reachableServers = (int) Arrays.stream(completableFutures).filter(booleanCompletableFuture -> !booleanCompletableFuture.isCompletedExceptionally()).count();
if (!success)
throw new QuorumUnreachableException(reachableServers, completableFutures.length);
}
Aggregations