in server/src/main/java/org/apache/cassandra/sidecar/tasks/PeriodicTaskExecutor.java [177:225]
public Future<Void> unschedule(PeriodicTask task)
{
PeriodicTaskKey key = new PeriodicTaskKey(task);
AtomicBoolean alreadyUnscheduled = new AtomicBoolean(false);
Long timerId = timerIds.computeIfPresent(key, (k, tid) -> {
alreadyUnscheduled.set(tid == UNSCHEDULED_STATE_TIMER_ID);
if (tid > 0)
{
// Best-effort on cancelling the timer
internalPool.cancelTimer(tid);
}
return UNSCHEDULED_STATE_TIMER_ID;
});
if (timerId == null)
{
LOGGER.debug("No such task to unschedule. task='{}'", key);
return Future.failedFuture("No such task to unschedule");
}
if (alreadyUnscheduled.get())
{
LOGGER.debug("Task is already unscheduled. task='{}'", key);
return Future.failedFuture("Task is already unscheduled");
}
LOGGER.debug("Unscheduling task. task='{}' timerId={}", key, timerId);
// The current run might have started already.
// If so, close the task once the run is completed; the task entry is removed on the next schedule.
// Otherwise, the task entry should be removed here, as there are no more schedules.
boolean removeEntry = !activeRuns.containsKey(key);
return activeRuns
.getOrDefault(key, Future.succeededFuture())
.andThen(ignored -> {
try
{
task.close();
}
catch (Throwable cause)
{
// just log any error while closing and continue
LOGGER.warn("Failed to close task during unscheduling. task='{}'", key, cause);
}
if (removeEntry)
{
timerIds.remove(key);
}
});
}