use of org.corfudb.runtime.exceptions.RecoveryException in project CorfuDB by CorfuDB.
the class ChainReplicationProtocol method recover.
/** Recover a failed write at the given global address,
* driving it to completion by invoking the recovery
* protocol.
*
* When this function returns the given globalAddress
* is guaranteed to contain a committed value.
*
* If there was no data previously written at the address,
* this function will throw a runtime exception. The
* recovery protocol should -only- be invoked if we
* previously were overwritten.
*
* @oaram layout The layout to use for the recovery.
* @param globalAddress The global address to drive
* the recovery protocol
*
*/
protected void recover(Layout layout, long globalAddress) {
// In chain replication, we started writing from the head,
// and propagated down to the tail. To recover, we start
// reading from the head, which should have the data
// we are trying to recover
int numUnits = layout.getSegmentLength(globalAddress);
log.debug("Recover[{}]: read chain head {}/{}", globalAddress, 1, numUnits);
ILogData ld = CFUtils.getUninterruptibly(layout.getLogUnitClient(globalAddress, 0).read(globalAddress)).getReadSet().getOrDefault(globalAddress, null);
// write was successful or not.
if (ld == null || ld.isEmpty()) {
throw new RecoveryException("Failed to read data during recovery at chain head.");
}
// now we go down the chain and write, ignoring any overwrite exception we get.
for (int i = 1; i < numUnits; i++) {
log.debug("Recover[{}]: write chain {}/{}", layout, i + 1, numUnits);
// in the chain.
try {
CFUtils.getUninterruptibly(layout.getLogUnitClient(globalAddress, i).write(ld), OverwriteException.class);
// We successfully recovered a write to this member of the chain
log.debug("Recover[{}]: recovered write at chain {}/{}", layout, i + 1, numUnits);
} catch (OverwriteException oe) {
// This member already had this data (in some cases, the write might have
// been committed to all members, so this is normal).
log.debug("Recover[{}]: overwritten at chain {}/{}", layout, i + 1, numUnits);
}
}
}
Aggregations