use of org.apache.cassandra.service.reads.repair.ReadRepair in project cassandra by apache.
the class StorageProxy method concatAndBlockOnRepair.
public static PartitionIterator concatAndBlockOnRepair(List<PartitionIterator> iterators, List<ReadRepair<?, ?>> repairs) {
PartitionIterator concatenated = PartitionIterators.concat(iterators);
if (repairs.isEmpty())
return concatenated;
return new PartitionIterator() {
public void close() {
concatenated.close();
repairs.forEach(ReadRepair::maybeSendAdditionalWrites);
repairs.forEach(ReadRepair::awaitWrites);
}
public boolean hasNext() {
return concatenated.hasNext();
}
public RowIterator next() {
return concatenated.next();
}
};
}
use of org.apache.cassandra.service.reads.repair.ReadRepair in project cassandra by apache.
the class StorageProxy method fetchRows.
/**
* This function executes local and remote reads, and blocks for the results:
*
* 1. Get the replica locations, sorted by response time according to the snitch
* 2. Send a data request to the closest replica, and digest requests to either
* a) all the replicas, if read repair is enabled
* b) the closest R-1 replicas, where R is the number required to satisfy the ConsistencyLevel
* 3. Wait for a response from R replicas
* 4. If the digests (if any) match the data return the data
* 5. else carry out read repair by getting data from all the nodes.
*/
private static PartitionIterator fetchRows(List<SinglePartitionReadCommand> commands, ConsistencyLevel consistencyLevel, long queryStartNanoTime) throws UnavailableException, ReadFailureException, ReadTimeoutException {
int cmdCount = commands.size();
AbstractReadExecutor[] reads = new AbstractReadExecutor[cmdCount];
// for type of speculation we'll use in this read
for (int i = 0; i < cmdCount; i++) {
reads[i] = AbstractReadExecutor.getReadExecutor(commands.get(i), consistencyLevel, queryStartNanoTime);
if (canDoLocalRequest(reads[i].getContactedReplicas())) {
readMetrics.localRequests.mark();
} else {
readMetrics.remoteRequests.mark();
}
}
// read executoe, we'll only send read requests to enough replicas to satisfy the consistency level
for (int i = 0; i < cmdCount; i++) {
reads[i].executeAsync();
}
// set of replicas we sent messages to, speculatively send an additional messages to an un-contacted replica
for (int i = 0; i < cmdCount; i++) {
reads[i].maybeTryAdditionalReplicas();
}
// repair process by sending full data reads to all replicas we received responses from.
for (int i = 0; i < cmdCount; i++) {
reads[i].awaitResponses();
}
// an additional request to any remaining replicas we haven't contacted (if there are any)
for (int i = 0; i < cmdCount; i++) {
reads[i].maybeSendAdditionalDataRequests();
}
// read repair - block on full data responses
for (int i = 0; i < cmdCount; i++) {
reads[i].awaitReadRepair();
}
// if we didn't do a read repair, return the contents of the data response, if we did do a read
// repair, merge the full data reads
List<PartitionIterator> results = new ArrayList<>(cmdCount);
List<ReadRepair<?, ?>> repairs = new ArrayList<>(cmdCount);
for (int i = 0; i < cmdCount; i++) {
results.add(reads[i].getResult());
repairs.add(reads[i].getReadRepair());
}
// if we did a read repair, assemble repair mutation and block on them
return concatAndBlockOnRepair(results, repairs);
}
Aggregations