Search in sources :

Example 1 with ThrowableRecordingRunnableWrapper

use of com.google.devtools.build.lib.concurrent.ThrowableRecordingRunnableWrapper in project bazel by bazelbuild.

the class FilesystemValueChecker method getDirtyActionValues.

/**
   * Return a collection of action values which have output files that are not in-sync with
   * the on-disk file value (were modified externally).
   */
Collection<SkyKey> getDirtyActionValues(Map<SkyKey, SkyValue> valuesMap, @Nullable final BatchStat batchStatter, ModifiedFileSet modifiedOutputFiles) throws InterruptedException {
    if (modifiedOutputFiles == ModifiedFileSet.NOTHING_MODIFIED) {
        LOG.info("Not checking for dirty actions since nothing was modified");
        return ImmutableList.of();
    }
    LOG.info("Accumulating dirty actions");
    final int numOutputJobs = Runtime.getRuntime().availableProcessors() * 4;
    final Set<SkyKey> actionSkyKeys = new HashSet<>();
    for (SkyKey key : valuesMap.keySet()) {
        if (ACTION_FILTER.apply(key)) {
            actionSkyKeys.add(key);
        }
    }
    final Sharder<Pair<SkyKey, ActionExecutionValue>> outputShards = new Sharder<>(numOutputJobs, actionSkyKeys.size());
    for (SkyKey key : actionSkyKeys) {
        outputShards.add(Pair.of(key, (ActionExecutionValue) valuesMap.get(key)));
    }
    LOG.info("Sharded action values for batching");
    ExecutorService executor = Executors.newFixedThreadPool(numOutputJobs, new ThreadFactoryBuilder().setNameFormat("FileSystem Output File Invalidator %d").build());
    Collection<SkyKey> dirtyKeys = Sets.newConcurrentHashSet();
    ThrowableRecordingRunnableWrapper wrapper = new ThrowableRecordingRunnableWrapper("FileSystemValueChecker#getDirtyActionValues");
    modifiedOutputFilesCounter.set(0);
    modifiedOutputFilesIntraBuildCounter.set(0);
    final ImmutableSet<PathFragment> knownModifiedOutputFiles = modifiedOutputFiles == ModifiedFileSet.EVERYTHING_MODIFIED ? null : modifiedOutputFiles.modifiedSourceFiles();
    // Initialized lazily through a supplier because it is only used to check modified
    // TreeArtifacts, which are not frequently used in builds.
    Supplier<NavigableSet<PathFragment>> sortedKnownModifiedOutputFiles = Suppliers.memoize(new Supplier<NavigableSet<PathFragment>>() {

        @Override
        public NavigableSet<PathFragment> get() {
            if (knownModifiedOutputFiles == null) {
                return null;
            } else {
                return ImmutableSortedSet.copyOf(knownModifiedOutputFiles);
            }
        }
    });
    for (List<Pair<SkyKey, ActionExecutionValue>> shard : outputShards) {
        Runnable job = (batchStatter == null) ? outputStatJob(dirtyKeys, shard, knownModifiedOutputFiles, sortedKnownModifiedOutputFiles) : batchStatJob(dirtyKeys, shard, batchStatter, knownModifiedOutputFiles, sortedKnownModifiedOutputFiles);
        executor.submit(wrapper.wrap(job));
    }
    boolean interrupted = ExecutorUtil.interruptibleShutdown(executor);
    Throwables.propagateIfPossible(wrapper.getFirstThrownError());
    LOG.info("Completed output file stat checks");
    if (interrupted) {
        throw new InterruptedException();
    }
    return dirtyKeys;
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) Sharder(com.google.devtools.build.lib.concurrent.Sharder) NavigableSet(java.util.NavigableSet) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) ExecutorService(java.util.concurrent.ExecutorService) ThreadFactoryBuilder(com.google.common.util.concurrent.ThreadFactoryBuilder) ThrowableRecordingRunnableWrapper(com.google.devtools.build.lib.concurrent.ThrowableRecordingRunnableWrapper) HashSet(java.util.HashSet) Pair(com.google.devtools.build.lib.util.Pair)

Example 2 with ThrowableRecordingRunnableWrapper

use of com.google.devtools.build.lib.concurrent.ThrowableRecordingRunnableWrapper in project bazel by bazelbuild.

the class SkyframeActionExecutor method constructActionGraphAndPathMap.

/**
   * Simultaneously construct an action graph for all the actions in Skyframe and a map from
   * {@link PathFragment}s to their respective {@link Artifact}s. We do this in a threadpool to save
   * around 1.5 seconds on a mid-sized build versus a single-threaded operation.
   */
private static Pair<ActionGraph, SortedMap<PathFragment, Artifact>> constructActionGraphAndPathMap(Iterable<ActionLookupValue> values, ConcurrentMap<ActionAnalysisMetadata, ConflictException> badActionMap) throws InterruptedException {
    MutableActionGraph actionGraph = new MapBasedActionGraph();
    ConcurrentNavigableMap<PathFragment, Artifact> artifactPathMap = new ConcurrentSkipListMap<>();
    // Action graph construction is CPU-bound.
    int numJobs = Runtime.getRuntime().availableProcessors();
    // No great reason for expecting 5000 action lookup values, but not worth counting size of
    // values.
    Sharder<ActionLookupValue> actionShards = new Sharder<>(numJobs, 5000);
    for (ActionLookupValue value : values) {
        actionShards.add(value);
    }
    ThrowableRecordingRunnableWrapper wrapper = new ThrowableRecordingRunnableWrapper("SkyframeActionExecutor#constructActionGraphAndPathMap");
    ExecutorService executor = Executors.newFixedThreadPool(numJobs, new ThreadFactoryBuilder().setNameFormat("ActionLookupValue Processor %d").build());
    for (List<ActionLookupValue> shard : actionShards) {
        executor.execute(wrapper.wrap(actionRegistration(shard, actionGraph, artifactPathMap, badActionMap)));
    }
    boolean interrupted = ExecutorUtil.interruptibleShutdown(executor);
    Throwables.propagateIfPossible(wrapper.getFirstThrownError());
    if (interrupted) {
        throw new InterruptedException();
    }
    return Pair.<ActionGraph, SortedMap<PathFragment, Artifact>>of(actionGraph, artifactPathMap);
}
Also used : Sharder(com.google.devtools.build.lib.concurrent.Sharder) ConcurrentSkipListMap(java.util.concurrent.ConcurrentSkipListMap) MutableActionGraph(com.google.devtools.build.lib.actions.MutableActionGraph) MapBasedActionGraph(com.google.devtools.build.lib.actions.MapBasedActionGraph) ActionGraph(com.google.devtools.build.lib.actions.ActionGraph) MapBasedActionGraph(com.google.devtools.build.lib.actions.MapBasedActionGraph) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) MutableActionGraph(com.google.devtools.build.lib.actions.MutableActionGraph) Artifact(com.google.devtools.build.lib.actions.Artifact) SortedMap(java.util.SortedMap) ExecutorService(java.util.concurrent.ExecutorService) ThreadFactoryBuilder(com.google.common.util.concurrent.ThreadFactoryBuilder) ThrowableRecordingRunnableWrapper(com.google.devtools.build.lib.concurrent.ThrowableRecordingRunnableWrapper)

Example 3 with ThrowableRecordingRunnableWrapper

use of com.google.devtools.build.lib.concurrent.ThrowableRecordingRunnableWrapper in project bazel by bazelbuild.

the class FilesystemValueChecker method getDirtyValues.

private BatchDirtyResult getDirtyValues(ValueFetcher fetcher, Iterable<SkyKey> keys, final SkyValueDirtinessChecker checker, final boolean checkMissingValues) throws InterruptedException {
    ExecutorService executor = Executors.newFixedThreadPool(DIRTINESS_CHECK_THREADS, new ThreadFactoryBuilder().setNameFormat("FileSystem Value Invalidator %d").build());
    final BatchDirtyResult batchResult = new BatchDirtyResult();
    ThrowableRecordingRunnableWrapper wrapper = new ThrowableRecordingRunnableWrapper("FilesystemValueChecker#getDirtyValues");
    final AtomicInteger numKeysScanned = new AtomicInteger(0);
    final AtomicInteger numKeysChecked = new AtomicInteger(0);
    ElapsedTimeReceiver elapsedTimeReceiver = new ElapsedTimeReceiver() {

        @Override
        public void accept(long elapsedTimeNanos) {
            if (elapsedTimeNanos > 0) {
                LOG.info(String.format("Spent %d ms checking %d filesystem nodes (%d scanned)", TimeUnit.MILLISECONDS.convert(elapsedTimeNanos, TimeUnit.NANOSECONDS), numKeysChecked.get(), numKeysScanned.get()));
            }
        }
    };
    try (AutoProfiler prof = AutoProfiler.create(elapsedTimeReceiver)) {
        for (final SkyKey key : keys) {
            numKeysScanned.incrementAndGet();
            if (!checker.applies(key)) {
                continue;
            }
            final SkyValue value = fetcher.get(key);
            if (!checkMissingValues && value == null) {
                continue;
            }
            executor.execute(wrapper.wrap(new Runnable() {

                @Override
                public void run() {
                    numKeysChecked.incrementAndGet();
                    DirtyResult result = checker.check(key, value, tsgm);
                    if (result.isDirty()) {
                        batchResult.add(key, value, result.getNewValue());
                    }
                }
            }));
        }
        boolean interrupted = ExecutorUtil.interruptibleShutdown(executor);
        Throwables.propagateIfPossible(wrapper.getFirstThrownError());
        if (interrupted) {
            throw new InterruptedException();
        }
    }
    return batchResult;
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) AutoProfiler(com.google.devtools.build.lib.profiler.AutoProfiler) DirtyResult(com.google.devtools.build.lib.skyframe.SkyValueDirtinessChecker.DirtyResult) ElapsedTimeReceiver(com.google.devtools.build.lib.profiler.AutoProfiler.ElapsedTimeReceiver) SkyValue(com.google.devtools.build.skyframe.SkyValue) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ExecutorService(java.util.concurrent.ExecutorService) ThreadFactoryBuilder(com.google.common.util.concurrent.ThreadFactoryBuilder) ThrowableRecordingRunnableWrapper(com.google.devtools.build.lib.concurrent.ThrowableRecordingRunnableWrapper)

Aggregations

ThreadFactoryBuilder (com.google.common.util.concurrent.ThreadFactoryBuilder)3 ThrowableRecordingRunnableWrapper (com.google.devtools.build.lib.concurrent.ThrowableRecordingRunnableWrapper)3 ExecutorService (java.util.concurrent.ExecutorService)3 Sharder (com.google.devtools.build.lib.concurrent.Sharder)2 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)2 SkyKey (com.google.devtools.build.skyframe.SkyKey)2 ActionGraph (com.google.devtools.build.lib.actions.ActionGraph)1 Artifact (com.google.devtools.build.lib.actions.Artifact)1 MapBasedActionGraph (com.google.devtools.build.lib.actions.MapBasedActionGraph)1 MutableActionGraph (com.google.devtools.build.lib.actions.MutableActionGraph)1 AutoProfiler (com.google.devtools.build.lib.profiler.AutoProfiler)1 ElapsedTimeReceiver (com.google.devtools.build.lib.profiler.AutoProfiler.ElapsedTimeReceiver)1 DirtyResult (com.google.devtools.build.lib.skyframe.SkyValueDirtinessChecker.DirtyResult)1 Pair (com.google.devtools.build.lib.util.Pair)1 SkyValue (com.google.devtools.build.skyframe.SkyValue)1 HashSet (java.util.HashSet)1 NavigableSet (java.util.NavigableSet)1 SortedMap (java.util.SortedMap)1 ConcurrentSkipListMap (java.util.concurrent.ConcurrentSkipListMap)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1