Search in sources :

Example 11 with Future

use of org.apache.cassandra.utils.concurrent.Future in project cassandra by apache.

the class RepairJob method sendValidationRequest.

/**
 * Creates {@link ValidationTask} and submit them to task executor in parallel.
 *
 * @param endpoints Endpoint addresses to send validation request
 * @return Future that can get all {@link TreeResponse} from replica, if all validation succeed.
 */
private Future<List<TreeResponse>> sendValidationRequest(Collection<InetAddressAndPort> endpoints) {
    state.phase.validationSubmitted();
    String message = String.format("Requesting merkle trees for %s (to %s)", desc.columnFamily, endpoints);
    logger.info("{} {}", session.previewKind.logPrefix(desc.sessionId), message);
    Tracing.traceRepair(message);
    int nowInSec = getNowInSeconds();
    List<Future<TreeResponse>> tasks = new ArrayList<>(endpoints.size());
    for (InetAddressAndPort endpoint : endpoints) {
        ValidationTask task = newValidationTask(endpoint, nowInSec);
        tasks.add(task);
        session.trackValidationCompletion(Pair.create(desc, endpoint), task);
        taskExecutor.execute(task);
    }
    return FutureCombiner.allOf(tasks);
}
Also used : InetAddressAndPort(org.apache.cassandra.locator.InetAddressAndPort) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) AsyncFuture(org.apache.cassandra.utils.concurrent.AsyncFuture) Future(org.apache.cassandra.utils.concurrent.Future) ImmediateFuture(org.apache.cassandra.utils.concurrent.ImmediateFuture)

Example 12 with Future

use of org.apache.cassandra.utils.concurrent.Future in project cassandra by apache.

the class RepairSession method start.

/**
 * Start RepairJob on given ColumnFamilies.
 *
 * This first validates if all replica are available, and if they are,
 * creates RepairJobs and submit to run on given executor.
 *
 * @param executor Executor to run validation
 */
public void start(ExecutorPlus executor) {
    state.phase.start();
    String message;
    if (terminated)
        return;
    logger.info("{} parentSessionId = {}: new session: will sync {} on range {} for {}.{}", previewKind.logPrefix(getId()), state.parentRepairSession, repairedNodes(), state.commonRange, state.keyspace, Arrays.toString(state.cfnames));
    Tracing.traceRepair("Syncing range {}", state.commonRange);
    if (!previewKind.isPreview() && !paxosOnly) {
        SystemDistributedKeyspace.startRepairs(getId(), state.parentRepairSession, state.keyspace, state.cfnames, state.commonRange);
    }
    if (state.commonRange.endpoints.isEmpty()) {
        logger.info("{} {}", previewKind.logPrefix(getId()), message = String.format("No neighbors to repair with on range %s: session completed", state.commonRange));
        state.phase.skip(message);
        Tracing.traceRepair(message);
        trySuccess(new RepairSessionResult(state.id, state.keyspace, state.commonRange.ranges, Lists.<RepairResult>newArrayList(), state.commonRange.hasSkippedReplicas));
        if (!previewKind.isPreview()) {
            SystemDistributedKeyspace.failRepairs(getId(), state.keyspace, state.cfnames, new RuntimeException(message));
        }
        return;
    }
    // Checking all nodes are live
    for (InetAddressAndPort endpoint : state.commonRange.endpoints) {
        if (!FailureDetector.instance.isAlive(endpoint) && !state.commonRange.hasSkippedReplicas) {
            message = String.format("Cannot proceed on repair because a neighbor (%s) is dead: session failed", endpoint);
            state.phase.fail(message);
            logger.error("{} {}", previewKind.logPrefix(getId()), message);
            Exception e = new IOException(message);
            tryFailure(e);
            if (!previewKind.isPreview()) {
                SystemDistributedKeyspace.failRepairs(getId(), state.keyspace, state.cfnames, e);
            }
            return;
        }
    }
    // Create and submit RepairJob for each ColumnFamily
    state.phase.jobsSubmitted();
    List<Future<RepairResult>> jobs = new ArrayList<>(state.cfnames.length);
    for (String cfname : state.cfnames) {
        RepairJob job = new RepairJob(this, cfname);
        state.register(job.state);
        executor.execute(job);
        jobs.add(job);
    }
    // When all RepairJobs are done without error, cleanup and set the final result
    FBUtilities.allOf(jobs).addCallback(new FutureCallback<List<RepairResult>>() {

        public void onSuccess(List<RepairResult> results) {
            state.phase.success();
            // this repair session is completed
            logger.info("{} {}", previewKind.logPrefix(getId()), "Session completed successfully");
            Tracing.traceRepair("Completed sync of range {}", state.commonRange);
            trySuccess(new RepairSessionResult(state.id, state.keyspace, state.commonRange.ranges, results, state.commonRange.hasSkippedReplicas));
            taskExecutor.shutdown();
            // mark this session as terminated
            terminate();
            awaitTaskExecutorTermination();
        }

        public void onFailure(Throwable t) {
            state.phase.fail(t);
            String msg = "{} Session completed with the following error";
            if (Throwables.anyCauseMatches(t, RepairException::shouldWarn))
                logger.warn(msg + ": {}", previewKind.logPrefix(getId()), t.getMessage());
            else
                logger.error(msg, previewKind.logPrefix(getId()), t);
            Tracing.traceRepair("Session completed with the following error: {}", t);
            forceShutdown(t);
        }
    }, executor);
}
Also used : InetAddressAndPort(org.apache.cassandra.locator.InetAddressAndPort) ArrayList(java.util.ArrayList) IOException(java.io.IOException) RepairException(org.apache.cassandra.exceptions.RepairException) IOException(java.io.IOException) AsyncFuture(org.apache.cassandra.utils.concurrent.AsyncFuture) Future(org.apache.cassandra.utils.concurrent.Future) ArrayList(java.util.ArrayList) List(java.util.List)

Example 13 with Future

use of org.apache.cassandra.utils.concurrent.Future in project cassandra by apache.

the class CompactionManager method submitBackground.

/**
 * Call this whenever a compaction might be needed on the given columnfamily.
 * It's okay to over-call (within reason) if a call is unnecessary, it will
 * turn into a no-op in the bucketing/candidate-scan phase.
 */
public List<Future<?>> submitBackground(final ColumnFamilyStore cfs) {
    if (cfs.isAutoCompactionDisabled()) {
        logger.trace("Autocompaction is disabled");
        return Collections.emptyList();
    }
    /**
     * If a CF is currently being compacted, and there are no idle threads, submitBackground should be a no-op;
     * we can wait for the current compaction to finish and re-submit when more information is available.
     * Otherwise, we should submit at least one task to prevent starvation by busier CFs, and more if there
     * are idle threads stil. (CASSANDRA-4310)
     */
    int count = compactingCF.count(cfs);
    if (count > 0 && executor.getActiveTaskCount() >= executor.getMaximumPoolSize()) {
        logger.trace("Background compaction is still running for {}.{} ({} remaining). Skipping", cfs.keyspace.getName(), cfs.name, count);
        return Collections.emptyList();
    }
    logger.trace("Scheduling a background task check for {}.{} with {}", cfs.keyspace.getName(), cfs.name, cfs.getCompactionStrategyManager().getName());
    List<Future<?>> futures = new ArrayList<>(1);
    Future<?> fut = executor.submitIfRunning(new BackgroundCompactionCandidate(cfs), "background task");
    if (!fut.isCancelled())
        futures.add(fut);
    else
        compactingCF.remove(cfs);
    return futures;
}
Also used : Future(org.apache.cassandra.utils.concurrent.Future) ImmediateFuture(org.apache.cassandra.utils.concurrent.ImmediateFuture) RangesAtEndpoint(org.apache.cassandra.locator.RangesAtEndpoint)

Example 14 with Future

use of org.apache.cassandra.utils.concurrent.Future in project cassandra by apache.

the class CompactionManager method forceUserDefinedCompaction.

public void forceUserDefinedCompaction(String dataFiles) {
    String[] filenames = dataFiles.split(",");
    Multimap<ColumnFamilyStore, Descriptor> descriptors = ArrayListMultimap.create();
    for (String filename : filenames) {
        // extract keyspace and columnfamily name from filename
        Descriptor desc = Descriptor.fromFilename(filename.trim());
        if (Schema.instance.getTableMetadataRef(desc) == null) {
            logger.warn("Schema does not exist for file {}. Skipping.", filename);
            continue;
        }
        // group by keyspace/columnfamily
        ColumnFamilyStore cfs = Keyspace.open(desc.ksname).getColumnFamilyStore(desc.cfname);
        descriptors.put(cfs, cfs.getDirectories().find(new File(filename.trim()).name()));
    }
    List<Future<?>> futures = new ArrayList<>(descriptors.size());
    int nowInSec = FBUtilities.nowInSeconds();
    for (ColumnFamilyStore cfs : descriptors.keySet()) futures.add(submitUserDefined(cfs, descriptors.get(cfs), getDefaultGcBefore(cfs, nowInSec)));
    FBUtilities.waitOnFutures(futures);
}
Also used : DatabaseDescriptor(org.apache.cassandra.config.DatabaseDescriptor) Descriptor(org.apache.cassandra.io.sstable.Descriptor) Future(org.apache.cassandra.utils.concurrent.Future) ImmediateFuture(org.apache.cassandra.utils.concurrent.ImmediateFuture) File(org.apache.cassandra.io.util.File) RangesAtEndpoint(org.apache.cassandra.locator.RangesAtEndpoint)

Example 15 with Future

use of org.apache.cassandra.utils.concurrent.Future in project cassandra by apache.

the class ViewBuilder method build.

private synchronized void build() {
    if (isStopped) {
        logger.debug("Stopped build for view({}.{}) after covering {} keys", ksName, view.name, keysBuilt);
        return;
    }
    // Get the local ranges for which the view hasn't already been built nor it's building
    RangesAtEndpoint replicatedRanges = StorageService.instance.getLocalReplicas(ksName);
    Replicas.temporaryAssertFull(replicatedRanges);
    Set<Range<Token>> newRanges = replicatedRanges.ranges().stream().map(r -> r.subtractAll(builtRanges)).flatMap(Set::stream).map(r -> r.subtractAll(pendingRanges.keySet())).flatMap(Set::stream).collect(Collectors.toSet());
    // If there are no new nor pending ranges we should finish the build
    if (newRanges.isEmpty() && pendingRanges.isEmpty()) {
        finish();
        return;
    }
    // Split the new local ranges and add them to the pending set
    DatabaseDescriptor.getPartitioner().splitter().map(s -> s.split(newRanges, NUM_TASKS)).orElse(newRanges).forEach(r -> pendingRanges.put(r, Pair.<Token, Long>create(null, 0L)));
    // Submit a new view build task for each building range.
    // We keep record of all the submitted tasks to be able of stopping them.
    List<Future<Long>> futures = pendingRanges.entrySet().stream().map(e -> new ViewBuilderTask(baseCfs, view, e.getKey(), e.getValue().left, e.getValue().right)).peek(tasks::add).map(CompactionManager.instance::submitViewBuilder).collect(toList());
    // Add a callback to process any eventual new local range and mark the view as built, doing a delayed retry if
    // the tasks don't succeed
    Future<List<Long>> future = FutureCombiner.allOf(futures);
    future.addCallback(new FutureCallback<List<Long>>() {

        public void onSuccess(List<Long> result) {
            keysBuilt += result.stream().mapToLong(x -> x).sum();
            builtRanges.addAll(pendingRanges.keySet());
            pendingRanges.clear();
            build();
        }

        public void onFailure(Throwable t) {
            if (t instanceof CompactionInterruptedException) {
                internalStop(true);
                keysBuilt = tasks.stream().mapToLong(ViewBuilderTask::keysBuilt).sum();
                logger.info("Interrupted build for view({}.{}) after covering {} keys", ksName, view.name, keysBuilt);
            } else {
                ScheduledExecutors.nonPeriodicTasks.schedule(() -> loadStatusAndBuild(), 5, TimeUnit.MINUTES);
                logger.warn("Materialized View failed to complete, sleeping 5 minutes before restarting", t);
            }
        }
    });
    this.future = future;
}
Also used : ScheduledExecutors(org.apache.cassandra.concurrent.ScheduledExecutors) CompactionManager(org.apache.cassandra.db.compaction.CompactionManager) LoggerFactory(org.slf4j.LoggerFactory) Range(org.apache.cassandra.dht.Range) CompactionInterruptedException(org.apache.cassandra.db.compaction.CompactionInterruptedException) SystemKeyspace(org.apache.cassandra.db.SystemKeyspace) SystemDistributedKeyspace(org.apache.cassandra.schema.SystemDistributedKeyspace) Token(org.apache.cassandra.dht.Token) Replicas(org.apache.cassandra.locator.Replicas) Pair(org.apache.cassandra.utils.Pair) Map(java.util.Map) DatabaseDescriptor(org.apache.cassandra.config.DatabaseDescriptor) FutureCombiner(org.apache.cassandra.utils.concurrent.FutureCombiner) Logger(org.slf4j.Logger) FBUtilities(org.apache.cassandra.utils.FBUtilities) Set(java.util.Set) StorageService(org.apache.cassandra.service.StorageService) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) Maps(com.google.common.collect.Maps) Sets(com.google.common.collect.Sets) FutureCallback(com.google.common.util.concurrent.FutureCallback) RangesAtEndpoint(org.apache.cassandra.locator.RangesAtEndpoint) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) Collectors.toList(java.util.stream.Collectors.toList) ColumnFamilyStore(org.apache.cassandra.db.ColumnFamilyStore) Future(org.apache.cassandra.utils.concurrent.Future) ImmediateFuture(org.apache.cassandra.utils.concurrent.ImmediateFuture) RangesAtEndpoint(org.apache.cassandra.locator.RangesAtEndpoint) CompactionInterruptedException(org.apache.cassandra.db.compaction.CompactionInterruptedException) Token(org.apache.cassandra.dht.Token) Range(org.apache.cassandra.dht.Range) CompactionManager(org.apache.cassandra.db.compaction.CompactionManager) Future(org.apache.cassandra.utils.concurrent.Future) ImmediateFuture(org.apache.cassandra.utils.concurrent.ImmediateFuture) List(java.util.List) Collectors.toList(java.util.stream.Collectors.toList)

Aggregations

Future (org.apache.cassandra.utils.concurrent.Future)31 ImmediateFuture (org.apache.cassandra.utils.concurrent.ImmediateFuture)14 InetAddressAndPort (org.apache.cassandra.locator.InetAddressAndPort)12 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)8 DatabaseDescriptor (org.apache.cassandra.config.DatabaseDescriptor)8 Test (org.junit.Test)8 VisibleForTesting (com.google.common.annotations.VisibleForTesting)7 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)7 Collectors (java.util.stream.Collectors)7 Range (org.apache.cassandra.dht.Range)7 Logger (org.slf4j.Logger)7 LoggerFactory (org.slf4j.LoggerFactory)7 TimeUnit (java.util.concurrent.TimeUnit)6 ColumnFamilyStore (org.apache.cassandra.db.ColumnFamilyStore)6 CoordinatedRepairResult (org.apache.cassandra.repair.CoordinatedRepairResult)6 Schema (org.apache.cassandra.schema.Schema)6 FutureCombiner (org.apache.cassandra.utils.concurrent.FutureCombiner)6 Preconditions (com.google.common.base.Preconditions)5 IOException (java.io.IOException)5 java.util (java.util)5