diff --git a/java/compiler/impl/src/com/intellij/compiler/cache/CompilerCacheConfigurator.java b/java/compiler/impl/src/com/intellij/compiler/cache/CompilerCacheConfigurator.java index 9471a4f453b6..5a2ab42e43d5 100644 --- a/java/compiler/impl/src/com/intellij/compiler/cache/CompilerCacheConfigurator.java +++ b/java/compiler/impl/src/com/intellij/compiler/cache/CompilerCacheConfigurator.java @@ -1,4 +1,4 @@ -// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.compiler.cache; import com.intellij.compiler.CompilerConfigurationSettings; @@ -42,6 +42,7 @@ public class CompilerCacheConfigurator { builder.setDeletionSpeed(CompilerCacheLoadingSettings.getApproximateDeletionSpeed()); builder.setForceDownload(CompilerCacheLoadingSettings.getForceUpdateValue()); builder.setDisableDownload(CompilerCacheLoadingSettings.getDisableUpdateValue()); + builder.setCleanupAsynchronously(CompilerCacheLoadingSettings.getCleanupAsynchronouslyValue()); builder.setMaxDownloadDuration(CompilerCacheLoadingSettings.getMaxDownloadDuration()); return builder.build(); } diff --git a/java/compiler/impl/src/com/intellij/compiler/cache/CompilerCacheLoadingSettings.java b/java/compiler/impl/src/com/intellij/compiler/cache/CompilerCacheLoadingSettings.java index 019fd18dfaf1..80f3bea59398 100644 --- a/java/compiler/impl/src/com/intellij/compiler/cache/CompilerCacheLoadingSettings.java +++ b/java/compiler/impl/src/com/intellij/compiler/cache/CompilerCacheLoadingSettings.java @@ -9,6 +9,7 @@ public class CompilerCacheLoadingSettings { private static final String FORCE_UPDATE = "JpsOutputLoaderManager.forceUpdate"; private static final String DISABLE_UPDATE = "JpsOutputLoaderManager.disableUpdate"; + private static final String CLEANUP_ASYNCHRONOUSLY = "JpsOutputLoaderManager.cleanupAsynchronously"; private static final String MAX_DOWNLOAD_DURATION = "JpsOutputLoaderManager.maxDownloadDuration"; private static final String APPROXIMATE_DELETION_SPEED = "JpsOutputLoaderManager.deletionBytesPerSec"; private static final String APPROXIMATE_DECOMPRESSION_SPEED = "JpsOutputLoaderManager.decompressionBytesPerSec"; @@ -35,6 +36,17 @@ public class CompilerCacheLoadingSettings { return disableUpdate; } + public static void saveCleanupAsynchronouslyValue(boolean cleanupAsynchronously) { + PropertiesComponent.getInstance().setValue(CLEANUP_ASYNCHRONOUSLY, cleanupAsynchronously); + LOG.info("Saving cleanup asynchronously value: " + cleanupAsynchronously); + } + + public static boolean getCleanupAsynchronouslyValue() { + boolean cleanupAsynchronously = PropertiesComponent.getInstance().getBoolean(CLEANUP_ASYNCHRONOUSLY, false); + LOG.info("Getting cleanup asynchronously value: " + cleanupAsynchronously); + return cleanupAsynchronously; + } + public static void saveMaxDownloadDuration(int maxDownloadDuration) { PropertiesComponent.getInstance().setValue(MAX_DOWNLOAD_DURATION, String.valueOf(maxDownloadDuration)); LOG.info("Saving max download duration: " + maxDownloadDuration); diff --git a/java/compiler/impl/src/com/intellij/compiler/cache/ui/CompilerCacheConfigurable.java b/java/compiler/impl/src/com/intellij/compiler/cache/ui/CompilerCacheConfigurable.java index 2074495a7584..f1f91752767f 100644 --- a/java/compiler/impl/src/com/intellij/compiler/cache/ui/CompilerCacheConfigurable.java +++ b/java/compiler/impl/src/com/intellij/compiler/cache/ui/CompilerCacheConfigurable.java @@ -23,11 +23,14 @@ public class CompilerCacheConfigurable implements SearchableConfigurable, Config private JBCheckBox myCbDisableCacheDownload; private JTextField myMaxDownloadDurationField; private JBLabel myMaxDownloadDurationDescription; + private JBCheckBox myCbCleanupAsynchronously; + private JBLabel myCleanupAsynchronouslyDescription; public CompilerCacheConfigurable(final Project project) { myProject = project; myForceUpdateDescription.setText("Turn off the heuristic that determines when it's faster to download cache or build locally and force downloads the nearest cache at each build"); //NON-NLS myMaxDownloadDurationDescription.setText("Set maximum applicable time of caches download. If the approximate time of work will be higher local build will be executed."); //NON-NLS + myCleanupAsynchronouslyDescription.setText("Removes old cache directories asynchronously. This option might produce garbage under 'system/plugins' and spawn long-living rsync processes."); //NON-NLS } @Override @@ -50,6 +53,7 @@ public class CompilerCacheConfigurable implements SearchableConfigurable, Config public boolean isModified() { boolean isModified = ComparingUtils.isModified(myCbForceUpdateCaches, CompilerCacheLoadingSettings.getForceUpdateValue()); isModified |= ComparingUtils.isModified(myCbDisableCacheDownload, CompilerCacheLoadingSettings.getDisableUpdateValue()); + isModified |= ComparingUtils.isModified(myCbCleanupAsynchronously, CompilerCacheLoadingSettings.getCleanupAsynchronouslyValue()); isModified |= ComparingUtils.isModified(myMaxDownloadDurationField, String.valueOf(CompilerCacheLoadingSettings.getMaxDownloadDuration())); return isModified; } @@ -59,6 +63,7 @@ public class CompilerCacheConfigurable implements SearchableConfigurable, Config try { CompilerCacheLoadingSettings.saveForceUpdateValue(myCbForceUpdateCaches.isSelected()); CompilerCacheLoadingSettings.saveDisableUpdateValue(myCbDisableCacheDownload.isSelected()); + CompilerCacheLoadingSettings.saveCleanupAsynchronouslyValue(myCbCleanupAsynchronously.isSelected()); CompilerCacheLoadingSettings.saveMaxDownloadDuration(Integer.parseInt(myMaxDownloadDurationField.getText())); } finally { @@ -72,6 +77,7 @@ public class CompilerCacheConfigurable implements SearchableConfigurable, Config public void reset() { myCbForceUpdateCaches.setSelected(CompilerCacheLoadingSettings.getForceUpdateValue()); myCbDisableCacheDownload.setSelected(CompilerCacheLoadingSettings.getDisableUpdateValue()); + myCbCleanupAsynchronously.setSelected(CompilerCacheLoadingSettings.getCleanupAsynchronouslyValue()); myMaxDownloadDurationField.setText(String.valueOf(CompilerCacheLoadingSettings.getMaxDownloadDuration())); } } diff --git a/java/compiler/impl/src/com/intellij/compiler/cache/ui/CompilerCacheOptionsPanel.form b/java/compiler/impl/src/com/intellij/compiler/cache/ui/CompilerCacheOptionsPanel.form index ab13e4a8e9b9..fa6afc18dc24 100644 --- a/java/compiler/impl/src/com/intellij/compiler/cache/ui/CompilerCacheOptionsPanel.form +++ b/java/compiler/impl/src/com/intellij/compiler/cache/ui/CompilerCacheOptionsPanel.form @@ -1,6 +1,6 @@
- + @@ -36,7 +36,7 @@ - + @@ -61,7 +61,7 @@ - + @@ -101,9 +101,27 @@ - + + + + + + + + + + + + + + + + + + + diff --git a/java/compiler/openapi/resources/messages/JavaCompilerBundle.properties b/java/compiler/openapi/resources/messages/JavaCompilerBundle.properties index 9360dafc0fbf..877fc8cf63b5 100644 --- a/java/compiler/openapi/resources/messages/JavaCompilerBundle.properties +++ b/java/compiler/openapi/resources/messages/JavaCompilerBundle.properties @@ -334,6 +334,7 @@ notification.group.compiler=Build finished compiler.cache.description=Compiler Cache compiler.cache.option.force.update=Force update caches compiler.cache.option.disable.update=Disable cache download +compiler.cache.option.cleanup.asynchronously=Cleanup aynchronously compiler.cache.option.max.download.time=Maximum duration of caches download: compiler.cache.option.max.download.time.units= mins notification.title.jps.caches.downloader=Jps caches downloader diff --git a/jps/jps-builders/gen/org/jetbrains/jps/api/CmdlineRemoteProto.java b/jps/jps-builders/gen/org/jetbrains/jps/api/CmdlineRemoteProto.java index 9a00b61af5d4..1c5c6a197bb2 100644 --- a/jps/jps-builders/gen/org/jetbrains/jps/api/CmdlineRemoteProto.java +++ b/jps/jps-builders/gen/org/jetbrains/jps/api/CmdlineRemoteProto.java @@ -1,3 +1,5 @@ +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. + // Generated by the protocol buffer compiler. DO NOT EDIT! // source: cmdline_remote_proto.proto @@ -5577,6 +5579,17 @@ public final class CmdlineRemoteProto { * @return The maxDownloadDuration. */ int getMaxDownloadDuration(); + + /** + * required bool cleanup_asynchronously = 10; + * @return Whether the cleanupAsynchronously field is set. + */ + boolean hasCleanupAsynchronously(); + /** + * required bool cleanup_asynchronously = 10; + * @return The cleanupAsynchronously. + */ + boolean getCleanupAsynchronously(); } /** * Protobuf type {@code org.jetbrains.jpsservice.Message.ControllerMessage.CacheDownloadSettings} @@ -5996,6 +6009,40 @@ public final class CmdlineRemoteProto { maxDownloadDuration_ = 0; } + public static final int CLEANUP_ASYNCHRONOUSLY_FIELD_NUMBER = 10; + private boolean cleanupAsynchronously_; + /** + * required bool cleanup_asynchronously = 10; + * @return Whether the cleanupAsynchronously field is set. + */ + @java.lang.Override + public boolean hasCleanupAsynchronously() { + return ((bitField0_ & 0x00000100) != 0); + } + /** + * required bool cleanup_asynchronously = 10; + * @return The cleanupAsynchronously. + */ + @java.lang.Override + public boolean getCleanupAsynchronously() { + return cleanupAsynchronously_; + } + /** + * required bool cleanup_asynchronously = 10; + * @param value The cleanupAsynchronously to set. + */ + private void setCleanupAsynchronously(boolean value) { + bitField0_ |= 0x00000100; + cleanupAsynchronously_ = value; + } + /** + * required bool cleanup_asynchronously = 10; + */ + private void clearCleanupAsynchronously() { + bitField0_ = (bitField0_ & ~0x00000100); + cleanupAsynchronously_ = false; + } + public static org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.CacheDownloadSettings parseFrom( java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException { @@ -6519,6 +6566,42 @@ public final class CmdlineRemoteProto { return this; } + /** + * required bool cleanup_asynchronously = 10; + * @return Whether the cleanupAsynchronously field is set. + */ + @java.lang.Override + public boolean hasCleanupAsynchronously() { + return instance.hasCleanupAsynchronously(); + } + /** + * required bool cleanup_asynchronously = 10; + * @return The cleanupAsynchronously. + */ + @java.lang.Override + public boolean getCleanupAsynchronously() { + return instance.getCleanupAsynchronously(); + } + /** + * required bool cleanup_asynchronously = 10; + * @param value The cleanupAsynchronously to set. + * @return This builder for chaining. + */ + public Builder setCleanupAsynchronously(boolean value) { + copyOnWrite(); + instance.setCleanupAsynchronously(value); + return this; + } + /** + * required bool cleanup_asynchronously = 10; + * @return This builder for chaining. + */ + public Builder clearCleanupAsynchronously() { + copyOnWrite(); + instance.clearCleanupAsynchronously(); + return this; + } + // @@protoc_insertion_point(builder_scope:org.jetbrains.jpsservice.Message.ControllerMessage.CacheDownloadSettings) } private byte memoizedIsInitialized = 2; @@ -6547,11 +6630,12 @@ public final class CmdlineRemoteProto { "forceDownload_", "disableDownload_", "maxDownloadDuration_", + "cleanupAsynchronously_", }; java.lang.String info = - "\u0001\t\u0000\u0001\u0001\t\t\u0001\u0000\b\u00012\u0002\u1508\u0000\u0003\u1504" + + "\u0001\n\u0000\u0001\u0001\n\n\u0001\u0000\t\u00012\u0002\u1508\u0000\u0003\u1504" + "\u0001\u0004\u1508\u0002\u0005\u1502\u0003\u0006\u1502\u0004\u0007\u1507\u0005\b" + - "\u1507\u0006\t\u1504\u0007"; + "\u1507\u0006\t\u1504\u0007\n\u1507\b"; return newMessageInfo(DEFAULT_INSTANCE, info, objects); } // fall through diff --git a/jps/jps-builders/proto/cmdline_remote_proto.proto b/jps/jps-builders/proto/cmdline_remote_proto.proto index f7ff0f11b27d..eab1bdf179f6 100644 --- a/jps/jps-builders/proto/cmdline_remote_proto.proto +++ b/jps/jps-builders/proto/cmdline_remote_proto.proto @@ -86,6 +86,7 @@ message Message { required bool force_download = 7; required bool disable_download = 8; required int32 max_download_duration = 9; + required bool cleanup_asynchronously = 10; } required Type type = 1; diff --git a/jps/jps-builders/src/org/jetbrains/jps/cache/JpsCachesLoaderUtil.java b/jps/jps-builders/src/org/jetbrains/jps/cache/JpsCachesLoaderUtil.java index 9ff6f516bd20..42abf3a6f53e 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cache/JpsCachesLoaderUtil.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cache/JpsCachesLoaderUtil.java @@ -1,9 +1,23 @@ +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.jps.cache; +import com.intellij.openapi.application.PathManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.concurrency.AppExecutorUtil; +import org.jetbrains.annotations.NotNull; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; import java.util.concurrent.ExecutorService; +import java.util.stream.Collectors; +import java.util.stream.Stream; import static com.intellij.execution.process.ProcessIOExecutorService.INSTANCE; @@ -20,4 +34,76 @@ public final class JpsCachesLoaderUtil { LOG.info("Executor service will be configured with " + threadsCount + " threads"); return threadsCount; } + + public static void delete(@NotNull File dir, boolean asynchronously) { + if (!asynchronously) { + FileUtil.delete(dir); + return; + } + + LOG.info("Deleting asynchronously... " + dir.getPath()); + try { + File temp = getEmptyTempDir(); + Path moved = Files.move(dir.toPath(), temp.toPath()); + EXECUTOR_SERVICE.execute(() -> delete(moved)); + } + catch (IOException e) { + LOG.warn("Unable to move directory: " + e.getMessage()); + FileUtil.delete(dir); + } + } + + public static void runCleanUpAsynchronously() { + LOG.info("Running clean-up asynchronously..."); + Path pluginTemp = Path.of(PathManager.getPluginTempPath()); + try (Stream stream = Files.list(pluginTemp)) { + List files = stream.filter(file -> file.getFileName().toString().startsWith(getPrefix())).collect(Collectors.toList()); + if (!files.isEmpty()) { + EXECUTOR_SERVICE.execute(() -> files.forEach(JpsCachesLoaderUtil::delete)); + } + } + catch (IOException e) { + LOG.warn("Unable to run clean-up task: " + e.getMessage()); + } + } + + private static void delete(@NotNull Path dir) { + if (SystemInfo.isUnix) { + File empty = getEmptyTempDir(); + if (empty.mkdir()) { + try { + // https://unix.stackexchange.com/a/79656/47504 + List command = new ArrayList<>(); + command.add("rsync"); + command.add("-a"); + command.add("--delete"); + command.add(empty.getPath() + "/"); + command.add(dir + "/"); + + ProcessBuilder builder = new ProcessBuilder(command); + Process process = builder.start(); + process.waitFor(); + int exitCode = process.exitValue(); + LOG.info("rsync exited with " + exitCode); + } + catch (IOException | InterruptedException e) { + LOG.warn("rsync failed: " + e.getMessage()); + } + finally { + FileUtil.delete(empty); + } + } + } + FileUtil.delete(dir.toFile()); + } + + private static @NotNull File getEmptyTempDir() { + File pluginTemp = new File(PathManager.getPluginTempPath()); + String prefix = getPrefix() + UUID.randomUUID(); + return FileUtil.findSequentNonexistentFile(pluginTemp, prefix, ""); + } + + private static @NotNull String getPrefix() { + return LOADER_TMP_FOLDER_NAME + "-"; + } } diff --git a/jps/jps-builders/src/org/jetbrains/jps/cache/loader/JpsCacheLoader.java b/jps/jps-builders/src/org/jetbrains/jps/cache/loader/JpsCacheLoader.java index 6975f3e407bb..94bc85aa3da2 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cache/loader/JpsCacheLoader.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cache/loader/JpsCacheLoader.java @@ -1,3 +1,4 @@ +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.jps.cache.loader; import com.intellij.openapi.diagnostic.Logger; @@ -7,6 +8,7 @@ import com.intellij.util.io.Decompressor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.builders.JpsBuildBundle; +import org.jetbrains.jps.cache.JpsCachesLoaderUtil; import org.jetbrains.jps.cache.client.JpsServerClient; import org.jetbrains.jps.cache.model.JpsLoaderContext; import org.jetbrains.jps.cache.statistics.JpsCacheLoadingSystemStats; @@ -22,12 +24,14 @@ class JpsCacheLoader implements JpsOutputLoader { private static final String FS_STATE_FILE = "fs_state.dat"; private final File myBuildCacheFolder; private final JpsServerClient myClient; + private final boolean isCleanupAsynchronously; private JpsLoaderContext myContext; private File myTmpCacheFolder; - JpsCacheLoader(@NotNull JpsServerClient client, @NotNull String myProjectPath) { + JpsCacheLoader(@NotNull JpsServerClient client, @NotNull String myProjectPath, boolean cleanupAsynchronously) { myBuildCacheFolder = Utils.getDataStorageRoot(myProjectPath); myClient = client; + isCleanupAsynchronously = cleanupAsynchronously; } @Nullable @@ -128,7 +132,7 @@ class JpsCacheLoader implements JpsOutputLoader { } // Remove old cache dir - FileUtil.delete(myBuildCacheFolder); + JpsCachesLoaderUtil.delete(myBuildCacheFolder, isCleanupAsynchronously); myTmpCacheFolder.renameTo(myBuildCacheFolder); //subTaskIndicator.finished(); LOG.debug("JPS cache downloads finished"); diff --git a/jps/jps-builders/src/org/jetbrains/jps/cache/loader/JpsOutputLoaderManager.java b/jps/jps-builders/src/org/jetbrains/jps/cache/loader/JpsOutputLoaderManager.java index 0bf42e5b3d06..d85bd3d5f090 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cache/loader/JpsOutputLoaderManager.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cache/loader/JpsOutputLoaderManager.java @@ -1,9 +1,9 @@ +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.jps.cache.loader; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.containers.ContainerUtil; import io.netty.channel.Channel; @@ -14,6 +14,7 @@ import org.jetbrains.jps.api.CmdlineRemoteProto; import org.jetbrains.jps.builders.BuildTargetType; import org.jetbrains.jps.builders.JpsBuildBundle; import org.jetbrains.jps.builders.java.JavaBuilderUtil; +import org.jetbrains.jps.cache.JpsCachesLoaderUtil; import org.jetbrains.jps.cache.client.JpsNettyClient; import org.jetbrains.jps.cache.client.JpsServerAuthUtil; import org.jetbrains.jps.cache.client.JpsServerClient; @@ -58,6 +59,7 @@ public class JpsOutputLoaderManager { private final JpsServerClient myServerClient; private boolean isCacheDownloaded; private final boolean isForceCachesDownload; + private final boolean isCleanupAsynchronously; private final String myBuildOutDir; private final String myProjectPath; private final String myCommitHash; @@ -82,6 +84,7 @@ public class JpsOutputLoaderManager { myCommitsCountBetweenCompilation = cacheDownloadSettings.getCommitsCountLatestBuild(); myMaxDownloadDuration = cacheDownloadSettings.getMaxDownloadDuration() * 60; isForceCachesDownload = cacheDownloadSettings.getForceDownload(); + isCleanupAsynchronously = cacheDownloadSettings.getCleanupAsynchronously(); JpsServerAuthUtil.setRequestHeaders(cacheDownloadSettings.getAuthHeadersMap()); JpsCacheLoadingSystemStats.setDeletionSpeed(cacheDownloadSettings.getDeletionSpeed()); JpsCacheLoadingSystemStats.setDecompressionSpeed(cacheDownloadSettings.getDecompressionSpeed()); @@ -91,6 +94,7 @@ public class JpsOutputLoaderManager { @NotNull List scopes, @NotNull Runnable beforeDownload) { if (!canRunNewLoading()) return; + if (isCleanupAsynchronously) JpsCachesLoaderUtil.runCleanUpAsynchronously(); if (isForceCachesDownload || isDownloadQuickerThanLocalBuild(buildRunner, myCommitsCountBetweenCompilation, scopes)) { LOG.info("Before download task execution..."); beforeDownload.run(); @@ -102,7 +106,7 @@ public class JpsOutputLoaderManager { if (outDir.exists()) { LOG.info("Start removing old caches before downloading"); myNettyClient.sendDescriptionStatusMessage(JpsBuildBundle.message("progress.text.removing.old.caches")); - FileUtil.delete(outDir); + JpsCachesLoaderUtil.delete(outDir, isCleanupAsynchronously); } LOG.info("Compilation output folder empty"); } @@ -328,7 +332,7 @@ public class JpsOutputLoaderManager { private List> getLoaders() { if (myJpsOutputLoadersLoaders != null) return myJpsOutputLoadersLoaders; - myJpsOutputLoadersLoaders = Arrays.asList(new JpsCacheLoader(myServerClient, myProjectPath), + myJpsOutputLoadersLoaders = Arrays.asList(new JpsCacheLoader(myServerClient, myProjectPath, isCleanupAsynchronously), new JpsCompilationOutputLoader(myServerClient, myBuildOutDir)); return myJpsOutputLoadersLoaders; } diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java index 0b39e32eb724..d60d8adfd5fe 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java @@ -168,7 +168,9 @@ final class BuildSession implements Runnable, CanceledStatus { myCacheLoadManager = null; if (ProjectStamps.PORTABLE_CACHES && myCacheDownloadSettings != null) { - LOG.info("Cache download settings: disableDownload=" + myCacheDownloadSettings.getDisableDownload() + "; forceUpdate=" + myCacheDownloadSettings.getForceDownload()); + LOG.info("Cache download settings: disableDownload=" + myCacheDownloadSettings.getDisableDownload() + + "; forceUpdate=" + myCacheDownloadSettings.getForceDownload() + + "; cleanupAsynchronously=" + myCacheDownloadSettings.getCleanupAsynchronously()); if (myCacheDownloadSettings.getDisableDownload()) { LOG.info("Cache download is disabled"); } else {