mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-02-04 23:39:07 +07:00
use fork join pool for start-up activities
GitOrigin-RevId: e1c07b7221c79274953ee1be563688f546eadd7d
This commit is contained in:
committed by
intellij-monorepo-bot
parent
ec9a504893
commit
cbd5f7be22
@@ -54,8 +54,4 @@ final class DescriptorLoadingContext implements AutoCloseable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public @NotNull DescriptorLoadingContext copy(boolean isEssential) {
|
||||
return new DescriptorLoadingContext(parentContext, isBundled, isEssential);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,6 +275,7 @@ public final class PluginDescriptorLoader {
|
||||
private static @Nullable IdeaPluginDescriptorImpl loadDescriptorFromResource(@NotNull URL resource,
|
||||
@NotNull String pathName,
|
||||
@NotNull DescriptorLoadingContext loadingContext,
|
||||
boolean isEssential,
|
||||
@NotNull PathResolver pathResolver) {
|
||||
try {
|
||||
Path file;
|
||||
@@ -302,7 +303,7 @@ public final class PluginDescriptorLoader {
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
if (loadingContext.isEssential) {
|
||||
if (isEssential) {
|
||||
ExceptionUtilRt.rethrowUnchecked(e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@@ -391,38 +392,22 @@ public final class PluginDescriptorLoader {
|
||||
Map<URL, String> urlsFromClassPath = new LinkedHashMap<>();
|
||||
URL platformPluginURL = computePlatformPluginUrlAndCollectPluginUrls(classLoader, urlsFromClassPath);
|
||||
ClassPathXmlPathResolver pathResolver = new ClassPathXmlPathResolver(classLoader);
|
||||
try (DescriptorLoadingContext loadingContext = new DescriptorLoadingContext(context, /* isBundled = */ true, /* isEssential, doesn't matter = */ true)) {
|
||||
loadDescriptorsFromClassPath(urlsFromClassPath, loadingContext, platformPluginURL, pathResolver);
|
||||
}
|
||||
loadDescriptorsFromClassPath(urlsFromClassPath, context, platformPluginURL, pathResolver);
|
||||
|
||||
ForkJoinPool.commonPool().invoke(new LoadDescriptorsFromDirAction(customPluginDir, context, false));
|
||||
|
||||
if (bundledPluginDir != null) {
|
||||
ForkJoinPool.commonPool().invoke(new LoadDescriptorsFromDirAction(bundledPluginDir, context, true));
|
||||
}
|
||||
}
|
||||
|
||||
static void loadDescriptorsFromClassPath(@NotNull Map<URL, String> urls,
|
||||
@NotNull DescriptorLoadingContext context,
|
||||
@NotNull DescriptorListLoadingContext context,
|
||||
@Nullable URL platformPluginURL,
|
||||
@NotNull PathResolver pathResolver) {
|
||||
if (urls.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (urls.size() == 1) {
|
||||
Map.Entry<URL, String> entry = urls.entrySet().iterator().next();
|
||||
IdeaPluginDescriptorImpl descriptor =
|
||||
loadDescriptorFromResource(entry.getKey(), entry.getValue(), context.copy(entry.getKey().equals(platformPluginURL)), pathResolver);
|
||||
if (descriptor != null) {
|
||||
if (!PluginManagerCore.usePluginClassLoader) {
|
||||
descriptor.setUseCoreClassLoader();
|
||||
}
|
||||
context.parentContext.result.add(descriptor, /* overrideUseIfCompatible = */ false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ForkJoinPool.commonPool().invoke(new RecursiveAction() {
|
||||
@Override
|
||||
protected void compute() {
|
||||
@@ -432,12 +417,13 @@ public final class PluginDescriptorLoader {
|
||||
@Override
|
||||
protected IdeaPluginDescriptorImpl compute() {
|
||||
URL url = entry.getKey();
|
||||
return loadDescriptorFromResource(url, entry.getValue(), context.copy(url.equals(platformPluginURL)), pathResolver);
|
||||
boolean isEssential = url.equals(platformPluginURL);
|
||||
return loadDescriptorFromResource(url, entry.getValue(), new DescriptorLoadingContext(context, true, isEssential), isEssential, pathResolver);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
PluginLoadingResult result = context.parentContext.result;
|
||||
PluginLoadingResult result = context.result;
|
||||
ForkJoinTask.invokeAll(tasks);
|
||||
for (RecursiveTask<IdeaPluginDescriptorImpl> task : tasks) {
|
||||
IdeaPluginDescriptorImpl descriptor = task.getRawResult();
|
||||
|
||||
@@ -29,7 +29,6 @@ import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ArrayUtilRt;
|
||||
import com.intellij.util.PlatformUtils;
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
import com.intellij.util.concurrency.AppExecutorUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.execution.ParametersListUtil;
|
||||
import com.intellij.util.graph.DFSTBuilder;
|
||||
@@ -48,6 +47,7 @@ import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
@@ -784,9 +784,7 @@ public final class PluginManagerCore {
|
||||
PluginDescriptorLoader.collectPluginFilesInClassPath(loader, urlsFromClassPath);
|
||||
BuildNumber buildNumber = BuildNumber.fromString("2042.42");
|
||||
DescriptorListLoadingContext context = new DescriptorListLoadingContext(0, Collections.emptySet(), new PluginLoadingResult(Collections.emptyMap(), () -> buildNumber, false));
|
||||
try (DescriptorLoadingContext loadingContext = new DescriptorLoadingContext(context, true, true)) {
|
||||
PluginDescriptorLoader.loadDescriptorsFromClassPath(urlsFromClassPath, loadingContext, null, new ClassPathXmlPathResolver(loader));
|
||||
}
|
||||
PluginDescriptorLoader.loadDescriptorsFromClassPath(urlsFromClassPath, context, null, new ClassPathXmlPathResolver(loader));
|
||||
|
||||
context.result.finishLoading();
|
||||
return context.result.getEnabledPlugins();
|
||||
@@ -807,7 +805,7 @@ public final class PluginManagerCore {
|
||||
DescriptorListLoadingContext context = PluginDescriptorLoader.loadDescriptors();
|
||||
activity.end();
|
||||
return context;
|
||||
}, AppExecutorUtil.getAppExecutorService());
|
||||
}, ForkJoinPool.commonPool());
|
||||
descriptorListFuture = future;
|
||||
return future;
|
||||
}
|
||||
@@ -817,6 +815,7 @@ public final class PluginManagerCore {
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public static @NotNull List<IdeaPluginDescriptorImpl> getEnabledPluginRawList() {
|
||||
//noinspection resource
|
||||
return getOrScheduleLoading().join().result.getEnabledPlugins();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.diagnostic.startUpPerformanceReporter
|
||||
|
||||
import com.intellij.diagnostic.ActivityImpl
|
||||
import com.intellij.diagnostic.ThreadNameManager
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap
|
||||
|
||||
private const val pooledPrefix = "ApplicationImpl pooled thread "
|
||||
|
||||
internal class IdeThreadNameManager : ThreadNameManager {
|
||||
// ConcurrencyUtil.runUnderThreadName is used in our code (to make thread dumps more clear) and changes thread name,
|
||||
// so, use first thread name that associated with thread and not subsequent one
|
||||
@@ -16,10 +18,8 @@ internal class IdeThreadNameManager : ThreadNameManager {
|
||||
return result
|
||||
}
|
||||
|
||||
val pooledPrefix = "ApplicationImpl pooled thread "
|
||||
|
||||
var name = event.threadName
|
||||
if (name.endsWith("]") && name.contains(pooledPrefix)) {
|
||||
if (name.endsWith(']') && name.contains(pooledPrefix)) {
|
||||
val lastOpen = name.lastIndexOf('[')
|
||||
if (lastOpen > 0) {
|
||||
name = name.substring(lastOpen + 1, name.length - 1)
|
||||
@@ -27,6 +27,7 @@ internal class IdeThreadNameManager : ThreadNameManager {
|
||||
}
|
||||
|
||||
result = when {
|
||||
name.startsWith("JobScheduler FJ pool ") -> name.replace("JobScheduler FJ pool ", "fj ")
|
||||
name.startsWith("AWT-EventQueue-") -> "edt"
|
||||
name.startsWith("Idea Main Thread") -> "idea main"
|
||||
name.startsWith(pooledPrefix) -> name.replace(pooledPrefix, "pooled ")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ide.ui;
|
||||
|
||||
import com.intellij.diagnostic.StartUpMeasurer;
|
||||
@@ -19,12 +19,12 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.startup.StartupActivity;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.codeStyle.WordPrefixMatcher;
|
||||
import com.intellij.util.concurrency.NonUrgentExecutor;
|
||||
import com.intellij.util.text.Matcher;
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public abstract class OptionsTopHitProvider implements OptionsSearchTopHitProvider, SearchTopHitProvider {
|
||||
@@ -163,7 +163,7 @@ public abstract class OptionsTopHitProvider implements OptionsSearchTopHitProvid
|
||||
|
||||
static final class Activity extends PreloadingActivity implements StartupActivity.DumbAware {
|
||||
Activity() {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode() ||
|
||||
if (ApplicationManager.getApplication().isUnitTestMode() ||
|
||||
ApplicationManager.getApplication().isHeadlessEnvironment()) {
|
||||
throw ExtensionNotApplicableException.INSTANCE;
|
||||
}
|
||||
@@ -171,13 +171,14 @@ public abstract class OptionsTopHitProvider implements OptionsSearchTopHitProvid
|
||||
|
||||
@Override
|
||||
public void preload(@NotNull ProgressIndicator indicator) {
|
||||
cacheAll(indicator, null); // for application
|
||||
// for application
|
||||
cacheAll(indicator, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runActivity(@NotNull Project project) {
|
||||
// for given project
|
||||
NonUrgentExecutor.getInstance().execute(() -> {
|
||||
ForkJoinPool.commonPool().execute(() -> {
|
||||
if (project.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import com.intellij.openapi.application.ex.ApplicationEx
|
||||
import com.intellij.openapi.application.impl.ApplicationImpl
|
||||
import com.intellij.openapi.components.stateStore
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.diagnostic.runAndLogException
|
||||
import com.intellij.openapi.extensions.ExtensionNotApplicableException
|
||||
import com.intellij.openapi.extensions.impl.ExtensionsAreaImpl
|
||||
import com.intellij.openapi.progress.EmptyProgressIndicator
|
||||
@@ -30,9 +29,7 @@ import com.intellij.ui.AppIcon
|
||||
import com.intellij.ui.mac.MacOSApplicationProvider
|
||||
import com.intellij.ui.mac.foundation.Foundation
|
||||
import com.intellij.ui.mac.touchbar.TouchBarsManager
|
||||
import com.intellij.util.concurrency.AppExecutorUtil
|
||||
import com.intellij.util.concurrency.NonUrgentExecutor
|
||||
import com.intellij.util.io.write
|
||||
import com.intellij.util.io.createDirectories
|
||||
import com.intellij.util.lang.ZipFilePool
|
||||
import com.intellij.util.ui.AsyncProcessIcon
|
||||
import net.miginfocom.layout.PlatformDefaults
|
||||
@@ -42,10 +39,9 @@ import java.awt.Font
|
||||
import java.awt.GraphicsEnvironment
|
||||
import java.awt.dnd.DragSource
|
||||
import java.io.IOException
|
||||
import java.nio.file.Paths
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import java.util.concurrent.CompletionStage
|
||||
import java.util.concurrent.Executor
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.util.concurrent.*
|
||||
import java.util.function.BiFunction
|
||||
import java.util.function.Function
|
||||
import kotlin.system.exitProcess
|
||||
@@ -132,18 +128,18 @@ private fun startApp(app: ApplicationImpl,
|
||||
}
|
||||
|
||||
val nonEdtExecutor = Executor {
|
||||
when {
|
||||
app.isDispatchThread -> AppExecutorUtil.getAppExecutorService().execute(it)
|
||||
else -> it.run()
|
||||
if (app.isDispatchThread) {
|
||||
ForkJoinPool.commonPool().execute(it)
|
||||
}
|
||||
else {
|
||||
it.run()
|
||||
}
|
||||
}
|
||||
|
||||
val boundedExecutor = createExecutorToPreloadServices()
|
||||
|
||||
// preload services only after icon activation
|
||||
val preloadSyncServiceFuture = registerRegistryAndInitStoreFuture
|
||||
.thenComposeAsync<Void?>(Function {
|
||||
preloadServices(it, app, activityPrefix = "", executor = boundedExecutor)
|
||||
preloadServices(it, app, activityPrefix = "")
|
||||
}, nonEdtExecutor)
|
||||
|
||||
if (!headless) {
|
||||
@@ -166,18 +162,19 @@ private fun startApp(app: ApplicationImpl,
|
||||
}
|
||||
TouchBarsManager.initialize()
|
||||
}
|
||||
}, NonUrgentExecutor.getInstance())
|
||||
}, ForkJoinPool.commonPool())
|
||||
}
|
||||
|
||||
WeakFocusStackManager.getInstance()
|
||||
|
||||
NonUrgentExecutor.getInstance().execute {
|
||||
ForkJoinPool.commonPool().execute {
|
||||
runActivity("migLayout") {
|
||||
PlatformDefaults.setLogicalPixelBase(PlatformDefaults.BASE_FONT_SIZE) // IDEA-170295
|
||||
// IDEA-170295
|
||||
PlatformDefaults.setLogicalPixelBase(PlatformDefaults.BASE_FONT_SIZE)
|
||||
}
|
||||
}
|
||||
|
||||
NonUrgentExecutor.getInstance().execute {
|
||||
ForkJoinPool.commonPool().execute {
|
||||
runActivity("icons preloading") {
|
||||
AsyncProcessIcon("")
|
||||
AnimatedIcon.Blinking(AllIcons.Ide.FatalError)
|
||||
@@ -209,13 +206,13 @@ private fun startApp(app: ApplicationImpl,
|
||||
|
||||
CompletableFuture.allOf(loadComponentInEdtFuture, preloadSyncServiceFuture)
|
||||
}
|
||||
.thenComposeAsync<Void?>(Function {
|
||||
.thenRunAsync({
|
||||
val activity = initAppActivity.startChild("app initialized callback")
|
||||
val future = callAppInitialized(app, boundedExecutor)
|
||||
val tasks = callAppInitialized(app)
|
||||
|
||||
// should be after scheduling all app initialized listeners (because this activity is not important)
|
||||
if (!Main.isLightEdit()) {
|
||||
NonUrgentExecutor.getInstance().execute {
|
||||
ForkJoinPool.commonPool().execute {
|
||||
// execute in parallel to component loading - this functionality should be used only by plugin functionality that is used after start-up
|
||||
runActivity("system properties setting") {
|
||||
SystemPropertyBean.initSystemProperties()
|
||||
@@ -223,17 +220,16 @@ private fun startApp(app: ApplicationImpl,
|
||||
}
|
||||
}
|
||||
|
||||
future.thenRun {
|
||||
activity.end()
|
||||
if (!headless) {
|
||||
addActivateAndWindowsCliListeners()
|
||||
}
|
||||
ForkJoinTask.invokeAll(tasks)
|
||||
|
||||
initAppActivity.end()
|
||||
activity.end()
|
||||
if (!headless) {
|
||||
addActivateAndWindowsCliListeners()
|
||||
}
|
||||
},
|
||||
// if `loadComponentInEdtFuture` is completed after `preloadSyncServiceFuture`, then this task will be executed in EDT, so force execution out of EDT
|
||||
nonEdtExecutor)
|
||||
|
||||
initAppActivity.end()
|
||||
}, nonEdtExecutor /* if `loadComponentInEdtFuture` is completed after `preloadSyncServiceFuture`,
|
||||
then this task will be executed in EDT, so force execution out of EDT */)
|
||||
.thenRun {
|
||||
if (starter.requiredModality == ApplicationStarter.NOT_IN_EDT) {
|
||||
starter.main(args)
|
||||
@@ -255,35 +251,25 @@ private fun startApp(app: ApplicationImpl,
|
||||
}
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
fun createExecutorToPreloadServices(): Executor {
|
||||
return AppExecutorUtil.createBoundedApplicationPoolExecutor("Preload Services", Runtime.getRuntime().availableProcessors(), false)
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
@JvmOverloads
|
||||
fun preloadServices(plugins: List<IdeaPluginDescriptorImpl>,
|
||||
container: ComponentManagerImpl,
|
||||
activityPrefix: String,
|
||||
onlyIfAwait: Boolean = false,
|
||||
executor: Executor = createExecutorToPreloadServices()): CompletableFuture<Void?> {
|
||||
val syncActivity = StartUpMeasurer.startActivity("${activityPrefix}service sync preloading")
|
||||
val asyncActivity = StartUpMeasurer.startActivity("${activityPrefix}service async preloading")
|
||||
onlyIfAwait: Boolean = false): CompletableFuture<Void?> {
|
||||
val result = container.preloadServices(plugins, activityPrefix, onlyIfAwait)
|
||||
|
||||
val result = container.preloadServices(plugins, executor, onlyIfAwait)
|
||||
|
||||
fun endActivityAndLogError(future: CompletableFuture<Void?>, activity: Activity): CompletableFuture<Void?> {
|
||||
fun logError(future: CompletableFuture<Void?>): CompletableFuture<Void?> {
|
||||
return future
|
||||
.whenComplete { _, error ->
|
||||
activity.end()
|
||||
if (error != null && error !is ProcessCanceledException) {
|
||||
StartupAbortedException.processException(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
endActivityAndLogError(result.asyncPreloadedServices, asyncActivity)
|
||||
return endActivityAndLogError(result.syncPreloadedServices, syncActivity)
|
||||
logError(result.asyncPreloadedServices)
|
||||
return logError(result.syncPreloadedServices)
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
@@ -294,7 +280,7 @@ fun registerRegistryAndInitStore(registerFuture: CompletableFuture<List<IdeaPlug
|
||||
runActivity("add registry keys") {
|
||||
RegistryKeyBean.addKeysFromPlugins()
|
||||
}
|
||||
}, AppExecutorUtil.getAppExecutorService())
|
||||
}, ForkJoinPool.commonPool())
|
||||
|
||||
// initSystemProperties or RegistryKeyBean.addKeysFromPlugins maybe not yet performed, but it doesn't affect because not used
|
||||
initConfigurationStore(app)
|
||||
@@ -360,27 +346,26 @@ private fun handleExternalCommand(args: List<String>, currentDirectory: String?)
|
||||
fun initApplication(rawArgs: List<String>, initUiTask: CompletionStage<*>) {
|
||||
val initAppActivity = MainRunner.startupStart.endAndStart(Activities.INIT_APP)
|
||||
val loadAndInitPluginFuture = CompletableFuture<List<IdeaPluginDescriptorImpl>>()
|
||||
initUiTask
|
||||
.thenRunAsync(Runnable {
|
||||
val args = processProgramArguments(rawArgs)
|
||||
EventQueue.invokeLater {
|
||||
executeInitAppInEdt(args, initAppActivity, loadAndInitPluginFuture)
|
||||
initUiTask.thenRunAsync(Runnable {
|
||||
val args = processProgramArguments(rawArgs)
|
||||
EventQueue.invokeLater {
|
||||
executeInitAppInEdt(args, initAppActivity, loadAndInitPluginFuture)
|
||||
}
|
||||
|
||||
if (!Main.isHeadless()) {
|
||||
runActivity("system fonts loading") {
|
||||
// editor and other UI components need the list of system fonts to implement font fallback
|
||||
// this list is pre-loaded here, in parallel to other activities, to speed up project opening
|
||||
// ideally, it shouldn't overlap with other font-related activities to avoid contention on JDK-internal font manager locks
|
||||
loadSystemFonts()
|
||||
}
|
||||
|
||||
if (!Main.isHeadless()) {
|
||||
runActivity("system fonts loading") {
|
||||
// editor and other UI components need the list of system fonts to implement font fallback
|
||||
// this list is pre-loaded here, in parallel to other activities, to speed up project opening
|
||||
// ideally, it shouldn't overlap with other font-related activities to avoid contention on JDK-internal font manager locks
|
||||
loadSystemFonts()
|
||||
}
|
||||
|
||||
// pre-load cursors used by drag-n-drop AWT subsystem
|
||||
runActivity("DnD setup") {
|
||||
DragSource.getDefaultDragSource()
|
||||
}
|
||||
// pre-load cursors used by drag-n-drop AWT subsystem
|
||||
runActivity("DnD setup") {
|
||||
DragSource.getDefaultDragSource()
|
||||
}
|
||||
}, AppExecutorUtil.getAppExecutorService()) // must not be executed neither in IDE main thread nor in EDT
|
||||
}
|
||||
}, ForkJoinPool.commonPool()) // must not be executed neither in IDE main thread nor in EDT
|
||||
|
||||
try {
|
||||
val activity = initAppActivity.startChild("plugin descriptor init waiting")
|
||||
@@ -464,38 +449,39 @@ private fun processProgramArguments(args: List<String>): List<String> {
|
||||
return arguments
|
||||
}
|
||||
|
||||
private fun createLocatorFile() {
|
||||
runActivity("create locator file") {
|
||||
val locatorFile = Paths.get(PathManager.getSystemPath(), ApplicationEx.LOCATOR_FILE_NAME)
|
||||
try {
|
||||
locatorFile.write(PathManager.getHomePath())
|
||||
}
|
||||
catch (e: IOException) {
|
||||
LOG.warn("can't store a location in '$locatorFile'", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
fun callAppInitialized(app: Application, executor: Executor): CompletableFuture<Void?> {
|
||||
NonUrgentExecutor.getInstance().execute {
|
||||
createLocatorFile()
|
||||
}
|
||||
|
||||
val result = mutableListOf<CompletableFuture<Void>>()
|
||||
fun callAppInitialized(app: Application): List<RecursiveAction> {
|
||||
val extensionArea = app.extensionArea as ExtensionsAreaImpl
|
||||
val extensionPoint = extensionArea.getExtensionPoint<ApplicationInitializedListener>("com.intellij.applicationInitializedListener")
|
||||
val result = ArrayList<RecursiveAction>(extensionPoint.size())
|
||||
extensionPoint.processImplementations(/* shouldBeSorted = */ false) { supplier, _ ->
|
||||
CompletableFuture.runAsync(Runnable {
|
||||
LOG.runAndLogException {
|
||||
result.add(object : RecursiveAction() {
|
||||
override fun compute() {
|
||||
try {
|
||||
supplier.get().componentsInitialized()
|
||||
}
|
||||
catch (ignore: ExtensionNotApplicableException) {
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
LOG.error(e)
|
||||
}
|
||||
}
|
||||
}, executor)
|
||||
})
|
||||
}
|
||||
extensionPoint.reset()
|
||||
return CompletableFuture.allOf(*result.toTypedArray())
|
||||
|
||||
ForkJoinPool.commonPool().execute {
|
||||
runActivity("create locator file") {
|
||||
val locatorFile = Path.of(PathManager.getSystemPath(), ApplicationEx.LOCATOR_FILE_NAME)
|
||||
try {
|
||||
locatorFile.parent?.createDirectories()
|
||||
Files.writeString(locatorFile, PathManager.getHomePath(), Charsets.UTF_8)
|
||||
}
|
||||
catch (e: IOException) {
|
||||
LOG.warn("Can't store a location in '$locatorFile'", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
@@ -13,7 +13,6 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.text.StringUtilRt;
|
||||
import com.intellij.util.ExceptionUtilRt;
|
||||
import com.intellij.util.concurrency.AppExecutorUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufOutputStream;
|
||||
@@ -38,10 +37,7 @@ import java.nio.file.attribute.PosixFileAttributeView;
|
||||
import java.nio.file.attribute.PosixFilePermission;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -195,7 +191,7 @@ public final class SocketLock {
|
||||
|
||||
activity.end();
|
||||
return server;
|
||||
}, AppExecutorUtil.getAppExecutorService());
|
||||
}, ForkJoinPool.commonPool());
|
||||
|
||||
log("exit: lock(): succeed");
|
||||
return new AbstractMap.SimpleEntry<>(ActivationStatus.NO_INSTANCE, null);
|
||||
|
||||
@@ -37,8 +37,6 @@ import com.intellij.ui.AppUIUtil;
|
||||
import com.intellij.ui.IconManager;
|
||||
import com.intellij.ui.scale.JBUIScale;
|
||||
import com.intellij.util.EnvironmentUtil;
|
||||
import com.intellij.util.concurrency.AppExecutorUtil;
|
||||
import com.intellij.util.concurrency.NonUrgentExecutor;
|
||||
import com.intellij.util.lang.ZipFilePool;
|
||||
import com.intellij.util.ui.EdtInvocationManager;
|
||||
import com.intellij.util.ui.StartupUiUtil;
|
||||
@@ -118,12 +116,12 @@ public final class StartupUtil {
|
||||
return ourShellEnvLoaded;
|
||||
}
|
||||
|
||||
private static @NotNull Future<@Nullable Object> loadEuaDocument(@NotNull ExecutorService executorService) {
|
||||
private static @Nullable Future<@Nullable Object> loadEuaDocument() {
|
||||
if (Main.isHeadless()) {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
return null;
|
||||
}
|
||||
|
||||
return executorService.submit(() -> {
|
||||
return ForkJoinPool.commonPool().submit(() -> {
|
||||
if (!ApplicationInfoImpl.getShadowInstance().isVendorJetBrains()) {
|
||||
return null;
|
||||
}
|
||||
@@ -179,9 +177,8 @@ public final class StartupUtil {
|
||||
IdeaForkJoinWorkerThreadFactory.setupForkJoinCommonPool(Main.isHeadless(args));
|
||||
|
||||
activity = activity.endAndStart("main class loading scheduling");
|
||||
ExecutorService executorService = AppExecutorUtil.getAppExecutorService();
|
||||
|
||||
Future<AppStarter> appStarterFuture = executorService.submit(() -> {
|
||||
Future<AppStarter> appStarterFuture = ForkJoinPool.commonPool().submit(() -> {
|
||||
Activity subActivity = StartUpMeasurer.startActivity("main class loading");
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<AppStarter> aClass = (Class<AppStarter>)StartupUtil.class.getClassLoader().loadClass(mainClass);
|
||||
@@ -194,11 +191,11 @@ public final class StartupUtil {
|
||||
|
||||
activity = activity.endAndStart("LaF init scheduling");
|
||||
// EndUserAgreement.Document type is not specified to avoid class loading
|
||||
Future<Object> euaDocument = loadEuaDocument(executorService);
|
||||
Future<Object> euaDocument = loadEuaDocument();
|
||||
if (Main.isHeadless()) {
|
||||
enableHeadlessAwtGuard();
|
||||
}
|
||||
CompletableFuture<?> initUiTask = scheduleInitUi(args, executorService, euaDocument)
|
||||
CompletableFuture<?> initUiTask = scheduleInitUi(args, euaDocument)
|
||||
.exceptionally(e -> {
|
||||
StartupAbortedException.processException(new StartupAbortedException("UI initialization failed", e));
|
||||
return null;
|
||||
@@ -237,7 +234,7 @@ public final class StartupUtil {
|
||||
PluginManagerCore.scheduleDescriptorLoading();
|
||||
}
|
||||
|
||||
NonUrgentExecutor.getInstance().execute(() -> {
|
||||
ForkJoinPool.commonPool().execute(() -> {
|
||||
setupSystemLibraries();
|
||||
logEssentialInfoAboutIde(log, ApplicationInfoImpl.getShadowInstance());
|
||||
loadSystemLibraries(log);
|
||||
@@ -275,10 +272,10 @@ public final class StartupUtil {
|
||||
@NotNull Logger log,
|
||||
boolean configImportNeeded,
|
||||
@NotNull Future<? extends AppStarter> appStarterFuture,
|
||||
@NotNull Future<@Nullable Object> euaDocument) throws Exception {
|
||||
@Nullable Future<@Nullable Object> euaDocument) throws Exception {
|
||||
if (!Main.isHeadless()) {
|
||||
Activity activity = StartUpMeasurer.startMainActivity("eua showing");
|
||||
Object document = euaDocument.get();
|
||||
Object document = euaDocument == null ? null : euaDocument.get();
|
||||
boolean agreementDialogWasShown = document != null && showUserAgreementAndConsentsIfNeeded(log, initUiTask, (EndUserAgreement.Document)document);
|
||||
|
||||
if (configImportNeeded) {
|
||||
@@ -341,12 +338,13 @@ public final class StartupUtil {
|
||||
AWTAutoShutdown.getInstance().notifyThreadBusy(Thread.currentThread());
|
||||
}
|
||||
|
||||
private static @NotNull CompletableFuture<?> scheduleInitUi(@NotNull String @NotNull [] args, @NotNull Executor executor, @NotNull Future<@Nullable Object> eulaDocument) {
|
||||
private static @NotNull CompletableFuture<?> scheduleInitUi(@NotNull String @NotNull [] args,
|
||||
@Nullable Future<@Nullable Object> eulaDocument) {
|
||||
// mainly call sun.util.logging.PlatformLogger.getLogger - it takes enormous time (up to 500 ms)
|
||||
// Before lockDirsAndConfigureLogger can be executed only tasks that do not require log,
|
||||
// because we don't want to complicate logging. It is OK, because lockDirsAndConfigureLogger is not so heavy-weight as UI tasks.
|
||||
CompletableFuture<Void> initUiFuture = new CompletableFuture<>();
|
||||
executor.execute(() -> {
|
||||
ForkJoinPool.commonPool().execute(() -> {
|
||||
try {
|
||||
checkHiDPISettings();
|
||||
|
||||
@@ -386,7 +384,7 @@ public final class StartupUtil {
|
||||
Activity eulaActivity = prepareSplashActivity.startChild("splash eula isAccepted");
|
||||
boolean isEulaAccepted;
|
||||
try {
|
||||
EndUserAgreement.Document document = (EndUserAgreement.Document)eulaDocument.get();
|
||||
EndUserAgreement.Document document = eulaDocument == null ? null : (EndUserAgreement.Document)eulaDocument.get();
|
||||
isEulaAccepted = document == null || document.isAccepted();
|
||||
}
|
||||
catch (InterruptedException | ExecutionException ignore) {
|
||||
@@ -411,12 +409,12 @@ public final class StartupUtil {
|
||||
|
||||
if (!Main.isHeadless()) {
|
||||
// do not wait, approach like AtomicNotNullLazyValue is used under the hood
|
||||
initUiFuture.thenRunAsync(StartupUtil::updateFrameClassAndWindowIcon, executor);
|
||||
initUiFuture.thenRunAsync(StartupUtil::updateFrameClassAndWindowIcon);
|
||||
}
|
||||
|
||||
CompletableFuture<Void> instrumentationFuture = new CompletableFuture<>();
|
||||
if (isUsingSeparateWriteThread()) {
|
||||
executor.execute(() -> {
|
||||
ForkJoinPool.commonPool().execute(() -> {
|
||||
Activity activity = StartUpMeasurer.startActivity("Write Intent Lock UI class transformer loading");
|
||||
try {
|
||||
WriteIntentLockInstrumenter.instrument();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.openapi.application;
|
||||
|
||||
import com.intellij.application.options.RegistryManager;
|
||||
import com.intellij.diagnostic.Activity;
|
||||
import com.intellij.diagnostic.ActivityCategory;
|
||||
import com.intellij.diagnostic.StartUpMeasurer;
|
||||
@@ -24,7 +23,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
final class Preloader implements ApplicationInitializedListener {
|
||||
private static final ExtensionPointName<PreloadingActivity> EP_NAME = new ExtensionPointName<>("com.intellij.preloadingActivity");
|
||||
private static final Logger LOG = Logger.getInstance(Preloader.class);
|
||||
|
||||
private static void checkHeavyProcessRunning() {
|
||||
@@ -36,15 +34,16 @@ final class Preloader implements ApplicationInitializedListener {
|
||||
@Override
|
||||
public void componentsInitialized() {
|
||||
Application app = ApplicationManager.getApplication();
|
||||
if (app.isUnitTestMode() || app.isHeadlessEnvironment() || !RegistryManager.getInstance().is("enable.activity.preloading")) {
|
||||
if (app.isUnitTestMode() || app.isHeadlessEnvironment() ||
|
||||
!Boolean.parseBoolean(System.getProperty("enable.activity.preloading", "true"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
EP_NAME.processWithPluginDescriptor(Preloader::preload);
|
||||
new ExtensionPointName<PreloadingActivity>("com.intellij.preloadingActivity").processWithPluginDescriptor(Preloader::preload);
|
||||
}
|
||||
|
||||
private static void preload(@NotNull PreloadingActivity activity, @Nullable PluginDescriptor descriptor) {
|
||||
ExecutorService executor = AppExecutorUtil.createBoundedApplicationPoolExecutor("Preloader Pool", 1);
|
||||
ExecutorService executor = AppExecutorUtil.createBoundedApplicationPoolExecutor("Preloader Pool", 1, false);
|
||||
|
||||
ProgressIndicator indicator = new ProgressIndicatorBase();
|
||||
Disposer.register(ApplicationManager.getApplication(), indicator::cancel);
|
||||
|
||||
@@ -11,7 +11,10 @@ import com.intellij.ide.*;
|
||||
import com.intellij.ide.plugins.ContainerDescriptor;
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptorImpl;
|
||||
import com.intellij.ide.plugins.PluginManagerCore;
|
||||
import com.intellij.idea.*;
|
||||
import com.intellij.idea.ApplicationLoader;
|
||||
import com.intellij.idea.Main;
|
||||
import com.intellij.idea.MutedErrorLogger;
|
||||
import com.intellij.idea.StartupUtil;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.*;
|
||||
import com.intellij.openapi.application.ex.ApplicationEx;
|
||||
@@ -41,7 +44,6 @@ import com.intellij.util.*;
|
||||
import com.intellij.util.concurrency.AppExecutorUtil;
|
||||
import com.intellij.util.concurrency.AppScheduledExecutorService;
|
||||
import com.intellij.util.containers.Stack;
|
||||
import com.intellij.util.io.storage.HeavyProcessLatch;
|
||||
import com.intellij.util.messages.Topic;
|
||||
import com.intellij.util.ui.EDT;
|
||||
import com.intellij.util.ui.EdtInvocationManager;
|
||||
@@ -348,28 +350,21 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
|
||||
List<IdeaPluginDescriptorImpl> plugins = PluginManagerCore.getLoadedPlugins(null);
|
||||
registerComponents(plugins, null);
|
||||
ApplicationLoader.initConfigurationStore(this);
|
||||
Executor executor = ApplicationLoader.createExecutorToPreloadServices();
|
||||
preloadServices(plugins, executor, false).getSyncPreloadedServices().join();
|
||||
preloadServices(plugins, "", false).getSyncPreloadedServices().join();
|
||||
loadComponents(null);
|
||||
ApplicationLoader.callAppInitialized(this, executor).join();
|
||||
ForkJoinTask.invokeAll(ApplicationLoader.callAppInitialized(this));
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public final void loadComponents(@Nullable ProgressIndicator indicator) {
|
||||
AccessToken token = HeavyProcessLatch.INSTANCE.processStarted("Loading application components"); // NON-NLS (not observable)
|
||||
try {
|
||||
if (indicator == null) {
|
||||
// no splash, no need to to use progress manager
|
||||
createComponents(null);
|
||||
}
|
||||
else {
|
||||
ProgressManager.getInstance().runProcess(() -> createComponents(indicator), indicator);
|
||||
}
|
||||
StartUpMeasurer.setCurrentState(LoadingState.COMPONENTS_LOADED);
|
||||
if (indicator == null) {
|
||||
// no splash, no need to to use progress manager
|
||||
createComponents(null);
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
else {
|
||||
ProgressManager.getInstance().runProcess(() -> createComponents(indicator), indicator);
|
||||
}
|
||||
StartUpMeasurer.setCurrentState(LoadingState.COMPONENTS_LOADED);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -170,10 +170,14 @@ open class ProjectExImpl(filePath: Path, projectName: String?) : ProjectImpl(App
|
||||
override fun init(preloadServices: Boolean, indicator: ProgressIndicator?) {
|
||||
val app = ApplicationManager.getApplication()
|
||||
|
||||
// for light project preload only services that are essential (await means "project component loading activity is completed only when all such services are completed")
|
||||
val servicePreloadingFuture = if (preloadServices) preloadServices(PluginManagerCore.getLoadedPlugins(null), container = this,
|
||||
activityPrefix = "project ",
|
||||
onlyIfAwait = isLight) else null
|
||||
// for light project preload only services that are essential
|
||||
// (await means "project component loading activity is completed only when all such services are completed")
|
||||
val servicePreloadingFuture = if (preloadServices) {
|
||||
preloadServices(PluginManagerCore.getLoadedPlugins(null), container = this, activityPrefix = "project ", onlyIfAwait = isLight)
|
||||
}
|
||||
else {
|
||||
null
|
||||
}
|
||||
createComponents(indicator)
|
||||
servicePreloadingFuture?.join()
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.openapi.util;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
@@ -13,7 +13,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
* @author gregsh
|
||||
*/
|
||||
public final class SystemPropertyBean implements PluginAware {
|
||||
private static final ExtensionPointName<SystemPropertyBean> EP_NAME = ExtensionPointName.create("com.intellij.systemProperty");
|
||||
private static final ExtensionPointName<SystemPropertyBean> EP_NAME = new ExtensionPointName<>("com.intellij.systemProperty");
|
||||
|
||||
private PluginDescriptor myPluginDescriptor;
|
||||
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
@file:Suppress("DeprecatedCallableAddReplaceWith")
|
||||
package com.intellij.serviceContainer
|
||||
|
||||
import com.intellij.diagnostic.ActivityCategory
|
||||
import com.intellij.diagnostic.LoadingState
|
||||
import com.intellij.diagnostic.PluginException
|
||||
import com.intellij.diagnostic.StartUpMeasurer
|
||||
import com.intellij.diagnostic.*
|
||||
import com.intellij.ide.plugins.*
|
||||
import com.intellij.ide.plugins.cl.PluginAwareClassLoader
|
||||
import com.intellij.idea.Main
|
||||
@@ -44,10 +41,7 @@ import java.lang.reflect.Constructor
|
||||
import java.lang.reflect.InvocationTargetException
|
||||
import java.lang.reflect.Modifier
|
||||
import java.util.*
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.ConcurrentMap
|
||||
import java.util.concurrent.Executor
|
||||
import java.util.concurrent.*
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
internal val LOG = logger<ComponentManagerImpl>()
|
||||
@@ -882,9 +876,11 @@ abstract class ComponentManagerImpl @JvmOverloads constructor(internal val paren
|
||||
val syncPreloadedServices: CompletableFuture<Void?>)
|
||||
|
||||
@ApiStatus.Internal
|
||||
fun preloadServices(plugins: List<IdeaPluginDescriptorImpl>, executor: Executor, onlyIfAwait: Boolean = false): ServicePreloadingResult {
|
||||
val asyncPreloadedServices = mutableListOf<CompletableFuture<Void>>()
|
||||
val syncPreloadedServices = mutableListOf<CompletableFuture<Void>>()
|
||||
fun preloadServices(plugins: List<IdeaPluginDescriptorImpl>,
|
||||
activityPrefix: String,
|
||||
onlyIfAwait: Boolean = false): ServicePreloadingResult {
|
||||
val asyncPreloadedServices = mutableListOf<RecursiveAction>()
|
||||
val syncPreloadedServices = mutableListOf<RecursiveAction>()
|
||||
for (plugin in plugins) {
|
||||
serviceLoop@
|
||||
for (service in getContainerDescriptor(plugin).services) {
|
||||
@@ -913,18 +909,20 @@ abstract class ComponentManagerImpl @JvmOverloads constructor(internal val paren
|
||||
asyncPreloadedServices
|
||||
}
|
||||
}
|
||||
PreloadMode.AWAIT -> {
|
||||
syncPreloadedServices
|
||||
}
|
||||
PreloadMode.AWAIT -> syncPreloadedServices
|
||||
PreloadMode.FALSE -> continue@serviceLoop
|
||||
else -> throw IllegalStateException("Unknown preload mode ${service.preload}")
|
||||
}
|
||||
|
||||
val future = CompletableFuture.runAsync(Runnable {
|
||||
if (!isServicePreloadingCancelled && !isDisposed) {
|
||||
val adapter = componentKeyToAdapter.get(service.getInterface()) as ServiceComponentAdapter? ?: return@Runnable
|
||||
list.add(object : RecursiveAction() {
|
||||
override fun compute() {
|
||||
if (isServicePreloadingCancelled || isDisposed) {
|
||||
return
|
||||
}
|
||||
|
||||
val adapter = componentKeyToAdapter.get(service.getInterface()) as ServiceComponentAdapter? ?: return
|
||||
try {
|
||||
adapter.getInstance<Any>(this, null)
|
||||
adapter.getInstance<Any>(this@ComponentManagerImpl, null)
|
||||
}
|
||||
catch (ignore: AlreadyDisposedException) {
|
||||
}
|
||||
@@ -933,13 +931,22 @@ abstract class ComponentManagerImpl @JvmOverloads constructor(internal val paren
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}, executor)
|
||||
|
||||
list.add(future)
|
||||
})
|
||||
}
|
||||
}
|
||||
return ServicePreloadingResult(asyncPreloadedServices = CompletableFuture.allOf(*asyncPreloadedServices.toTypedArray()),
|
||||
syncPreloadedServices = CompletableFuture.allOf(*syncPreloadedServices.toTypedArray()))
|
||||
|
||||
return ServicePreloadingResult(
|
||||
asyncPreloadedServices = CompletableFuture.runAsync({
|
||||
runActivity("${activityPrefix}service async preloading") {
|
||||
ForkJoinTask.invokeAll(asyncPreloadedServices)
|
||||
}
|
||||
}, ForkJoinPool.commonPool()),
|
||||
syncPreloadedServices = CompletableFuture.runAsync({
|
||||
runActivity("${activityPrefix}service sync preloading") {
|
||||
ForkJoinTask.invokeAll(syncPreloadedServices)
|
||||
}
|
||||
}, ForkJoinPool.commonPool())
|
||||
)
|
||||
}
|
||||
|
||||
override fun isDisposed(): Boolean {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij
|
||||
|
||||
import com.intellij.concurrency.IdeaForkJoinWorkerThreadFactory
|
||||
@@ -17,10 +17,7 @@ import com.intellij.ui.IconManager
|
||||
import com.intellij.util.SystemProperties
|
||||
import com.intellij.util.concurrency.AppExecutorUtil
|
||||
import java.awt.EventQueue
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import java.util.concurrent.ExecutionException
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.TimeoutException
|
||||
import java.util.concurrent.*
|
||||
import java.util.function.Supplier
|
||||
|
||||
fun loadHeadlessAppInUnitTestMode() {
|
||||
@@ -63,14 +60,12 @@ internal fun doLoadApp(setupEventQueue: () -> Unit) {
|
||||
plugins = registerRegistryAndInitStore(registerAppComponents(loadedPluginFuture, app), app)
|
||||
.get(40, TimeUnit.SECONDS)
|
||||
|
||||
val boundedExecutor = createExecutorToPreloadServices()
|
||||
|
||||
Registry.getInstance().markAsLoaded()
|
||||
val preloadServiceFuture = preloadServices(plugins, app, activityPrefix = "", executor = boundedExecutor)
|
||||
val preloadServiceFuture = preloadServices(plugins, app, activityPrefix = "")
|
||||
app.loadComponents(null)
|
||||
|
||||
preloadServiceFuture
|
||||
.thenCompose { callAppInitialized(app, boundedExecutor) }
|
||||
.thenRun { ForkJoinTask.invokeAll(callAppInitialized(app)) }
|
||||
.get(40, TimeUnit.SECONDS)
|
||||
|
||||
(PersistentFS.getInstance() as PersistentFSImpl).cleanPersistedContents()
|
||||
|
||||
@@ -23,7 +23,6 @@ final class EdtScheduledExecutorServiceImpl extends SchedulingWrapper implements
|
||||
super(EdtExecutorServiceImpl.INSTANCE, ((AppScheduledExecutorService)AppExecutorUtil.getAppScheduledExecutorService()).delayQueue);
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ScheduledFuture<?> schedule(@NotNull Runnable command, @NotNull ModalityState modalityState, long delay, TimeUnit unit) {
|
||||
|
||||
@@ -1839,9 +1839,6 @@ idea.lazy.classloading.caches=false
|
||||
idea.lazy.classloading.caches.description=Flag for UrlClassLoader to use lazy caching of package contents
|
||||
idea.use.loader.for.jdk9=true
|
||||
|
||||
enable.activity.preloading=true
|
||||
enable.activity.preloading.description=While application starts, preload classes and other resources for popular subsystems to reduce delays when they're first invoked
|
||||
|
||||
toolwindow.active.tab.use.contrast.background=false
|
||||
toolwindow.active.tab.use.contrast.background.description=When enabled contrast color is used for selected tab background in tool windows
|
||||
toolwindow.active.tab.contrast.background.color=808080
|
||||
|
||||
@@ -7,7 +7,6 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.SystemInfoRt;
|
||||
import com.intellij.openapi.util.text.StringUtilRt;
|
||||
import com.intellij.util.concurrency.AppExecutorUtil;
|
||||
import com.intellij.util.containers.CollectionFactory;
|
||||
import com.intellij.util.io.BaseOutputReader;
|
||||
import org.jetbrains.annotations.*;
|
||||
@@ -23,6 +22,7 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
@@ -118,7 +118,7 @@ public final class EnvironmentUtil {
|
||||
callback.run();
|
||||
state.complete(result);
|
||||
}
|
||||
}, AppExecutorUtil.getAppExecutorService()));
|
||||
}, ForkJoinPool.commonPool()));
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -487,7 +487,7 @@ public final class EnvironmentUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private static class StreamGobbler extends BaseOutputReader {
|
||||
private static final class StreamGobbler extends BaseOutputReader {
|
||||
private static final Options OPTIONS = new Options() {
|
||||
@Override
|
||||
public SleepingPolicy policy() {
|
||||
@@ -510,7 +510,7 @@ public final class EnvironmentUtil {
|
||||
|
||||
@Override
|
||||
protected @NotNull Future<?> executeOnPooledThread(@NotNull Runnable runnable) {
|
||||
return AppExecutorUtil.getAppExecutorService().submit(runnable);
|
||||
return ForkJoinPool.commonPool().submit(runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user