use of org.apache.cassandra.repair.KeyspaceRepairManager in project cassandra by apache.
the class LocalSessions method handlePrepareMessage.
/**
* The PrepareConsistentRequest promotes the parent repair session to a consistent incremental
* session, and isolates the data to be repaired from the rest of the table's data
*
* No response is sent to the repair coordinator until the data preparation / isolation has completed
* successfully. If the data preparation fails, a failure message is sent to the coordinator,
* cancelling the session.
*/
public void handlePrepareMessage(InetAddressAndPort from, PrepareConsistentRequest request) {
logger.trace("received {} from {}", request, from);
UUID sessionID = request.parentSession;
InetAddressAndPort coordinator = request.coordinator;
Set<InetAddressAndPort> peers = request.participants;
ActiveRepairService.ParentRepairSession parentSession;
try {
parentSession = getParentRepairSession(sessionID);
} catch (Throwable e) {
logger.error("Error retrieving ParentRepairSession for session {}, responding with failure", sessionID);
sendMessage(coordinator, Message.out(PREPARE_CONSISTENT_RSP, new PrepareConsistentResponse(sessionID, getBroadcastAddressAndPort(), false)));
return;
}
LocalSession session = createSessionUnsafe(sessionID, parentSession, peers);
putSessionUnsafe(session);
logger.info("Beginning local incremental repair session {}", session);
ExecutorService executor = executorFactory().pooled("Repair-" + sessionID, parentSession.getColumnFamilyStores().size());
KeyspaceRepairManager repairManager = parentSession.getKeyspace().getRepairManager();
RangesAtEndpoint tokenRanges = filterLocalRanges(parentSession.getKeyspace().getName(), parentSession.getRanges());
Future<List<Void>> repairPreparation = prepareSession(repairManager, sessionID, parentSession.getColumnFamilyStores(), tokenRanges, executor, () -> session.getState() != PREPARING);
repairPreparation.addCallback(new FutureCallback<List<Void>>() {
public void onSuccess(@Nullable List<Void> result) {
try {
logger.info("Prepare phase for incremental repair session {} completed", sessionID);
if (session.getState() != FAILED)
setStateAndSave(session, PREPARED);
else
logger.info("Session {} failed before anticompaction completed", sessionID);
Message<PrepareConsistentResponse> message = Message.out(PREPARE_CONSISTENT_RSP, new PrepareConsistentResponse(sessionID, getBroadcastAddressAndPort(), session.getState() != FAILED));
sendMessage(coordinator, message);
} finally {
executor.shutdown();
}
}
public void onFailure(Throwable t) {
try {
if (Throwables.anyCauseMatches(t, (throwable) -> throwable instanceof CompactionInterruptedException))
logger.info("Anticompaction interrupted for session {}: {}", sessionID, t.getMessage());
else if (Throwables.anyCauseMatches(t, (throwable) -> throwable instanceof NoSuchRepairSessionException))
logger.warn("No such repair session: {}", sessionID);
else
logger.error("Prepare phase for incremental repair session {} failed", sessionID, t);
sendMessage(coordinator, Message.out(PREPARE_CONSISTENT_RSP, new PrepareConsistentResponse(sessionID, getBroadcastAddressAndPort(), false)));
failSession(sessionID, false);
} finally {
executor.shutdown();
}
}
});
}
use of org.apache.cassandra.repair.KeyspaceRepairManager in project cassandra by apache.
the class LocalSessionTest method prepareCancellation.
/**
* If the session is cancelled mid-prepare, the isCancelled boolean supplier should start returning true
*/
@Test
public void prepareCancellation() {
UUID sessionID = registerSession();
AtomicReference<BooleanSupplier> isCancelledRef = new AtomicReference<>();
Promise<List<Void>> future = new AsyncPromise<>();
InstrumentedLocalSessions sessions = new InstrumentedLocalSessions() {
Future<List<Void>> prepareSession(KeyspaceRepairManager repairManager, UUID sessionID, Collection<ColumnFamilyStore> tables, RangesAtEndpoint ranges, ExecutorService executor, BooleanSupplier isCancelled) {
isCancelledRef.set(isCancelled);
return future;
}
};
sessions.start();
sessions.handlePrepareMessage(PARTICIPANT1, new PrepareConsistentRequest(sessionID, COORDINATOR, PARTICIPANTS));
BooleanSupplier isCancelled = isCancelledRef.get();
Assert.assertNotNull(isCancelled);
Assert.assertFalse(isCancelled.getAsBoolean());
Assert.assertTrue(sessions.sentMessages.isEmpty());
sessions.failSession(sessionID, false);
Assert.assertTrue(isCancelled.getAsBoolean());
// now that the session has failed, it send a negative response to the coordinator (even if the anti-compaction completed successfully)
future.trySuccess(null);
assertMessagesSent(sessions, COORDINATOR, new PrepareConsistentResponse(sessionID, PARTICIPANT1, false));
}
Aggregations