diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java index 9e7a59b5b6f2..b56555c5b522 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -10,7 +10,6 @@ import com.intellij.codeInsight.editorActions.smartEnter.SmartEnterProcessor; import com.intellij.codeInsight.editorActions.smartEnter.SmartEnterProcessors; import com.intellij.codeInsight.lookup.*; import com.intellij.codeInsight.lookup.impl.LookupImpl; -import com.intellij.concurrency.JobScheduler; import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.ide.DataManager; import com.intellij.lang.Language; @@ -30,10 +29,7 @@ import com.intellij.openapi.editor.EditorModificationUtil; import com.intellij.openapi.editor.actionSystem.EditorActionManager; import com.intellij.openapi.editor.ex.DocumentEx; import com.intellij.openapi.fileEditor.FileDocumentManager; -import com.intellij.openapi.progress.ProcessCanceledException; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.progress.ProgressManager; -import com.intellij.openapi.progress.util.ProgressIndicatorBase; +import com.intellij.openapi.progress.util.ProgressIndicatorUtils; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; @@ -58,8 +54,6 @@ import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.concurrent.Future; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; @SuppressWarnings("deprecation") public class CodeCompletionHandlerBase { @@ -712,18 +706,7 @@ public class CodeCompletionHandlerBase { return task.compute(); } - ProgressIndicator indicator = new ProgressIndicatorBase(); - - ScheduledFuture future = JobScheduler.getScheduler().schedule(() -> indicator.cancel(), maxDurationMillis, TimeUnit.MILLISECONDS); - try { - return ProgressManager.getInstance().runProcess(task, indicator); - } - catch (ProcessCanceledException e) { - return null; - } - finally { - future.cancel(false); - } + return ProgressIndicatorUtils.withTimeout(maxDurationMillis, task); } private static int calcSyncTimeOut(long startTime) { diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionUpdater.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionUpdater.java index f11b014728b8..6aec002bd234 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionUpdater.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionUpdater.java @@ -15,7 +15,6 @@ import com.intellij.openapi.progress.util.ProgressIndicatorUtils; import com.intellij.openapi.progress.util.ProgressWrapper; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Conditions; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.registry.Registry; @@ -37,8 +36,6 @@ import java.awt.event.PaintEvent; import java.util.List; import java.util.*; import java.util.concurrent.ExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; import java.util.function.Predicate; import java.util.function.Supplier; @@ -133,8 +130,8 @@ class ActionUpdater { */ @NotNull List expandActionGroupWithTimeout(ActionGroup group, boolean hideDisabled) { - List result = withTimeout(Registry.intValue("actionSystem.update.timeout.ms"), - () -> expandActionGroup(group, hideDisabled)); + List result = ProgressIndicatorUtils.withTimeout(Registry.intValue("actionSystem.update.timeout.ms"), + () -> expandActionGroup(group, hideDisabled)); try { return result != null ? result : expandActionGroup(group, hideDisabled, myCheapStrategy); } @@ -191,22 +188,6 @@ class ActionUpdater { promise.onProcessed(__ -> Disposer.dispose(disposable)); } - @Nullable - private static T withTimeout(int timeoutMs, Computable computable) { - ProgressManager.checkCanceled(); - ProgressIndicatorBase progress = new ProgressIndicatorBase(); - ScheduledFuture cancelProgress = AppExecutorUtil.getAppScheduledExecutorService().schedule(progress::cancel, timeoutMs, TimeUnit.MILLISECONDS); - try { - return ProgressManager.getInstance().runProcess(computable, progress); - } - catch (ProcessCanceledException e) { - return null; - } - finally { - cancelProgress.cancel(false); - } - } - private List doExpandActionGroup(ActionGroup group, boolean hideDisabled, UpdateStrategy strategy) { ProgressManager.checkCanceled(); Presentation presentation = update(group, strategy); @@ -226,7 +207,7 @@ class ActionUpdater { */ @Nullable private List expandIfCheap(AnAction action, boolean hideDisabled, UpdateStrategy strategy) { - return strategy == myCheapStrategy ? null : withTimeout(1, () -> expandGroupChild(action, hideDisabled, strategy)); + return strategy == myCheapStrategy ? null : ProgressIndicatorUtils.withTimeout(1, () -> expandGroupChild(action, hideDisabled, strategy)); } private void expandMoreExpensiveActions(List children, diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java index 5470595fab2b..1fbb47631be6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java @@ -8,17 +8,21 @@ import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.EmptyRunnable; import com.intellij.openapi.util.Ref; +import com.intellij.util.concurrency.AppExecutorUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.ide.PooledThreadExecutor; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; /** - * Methods in this class are used to equip long background processes which take read actions with a special listener + * Most methods in this class are used to equip long background processes which take read actions with a special listener * that fires when a write action is about to begin, and cancels corresponding progress indicators to avoid blocking the UI. * These processes should be ready to get {@link ProcessCanceledException} at any moment. * Processes may want to react on cancellation event by restarting the activity, see @@ -240,4 +244,20 @@ public class ProgressIndicatorUtils { } application.invokeAndWait(EmptyRunnable.INSTANCE, ModalityState.any()); } + + @Nullable + public static T withTimeout(long timeoutMs, Computable computable) { + ProgressManager.checkCanceled(); + ProgressIndicatorBase progress = new ProgressIndicatorBase(); + ScheduledFuture cancelProgress = AppExecutorUtil.getAppScheduledExecutorService().schedule(progress::cancel, timeoutMs, TimeUnit.MILLISECONDS); + try { + return ProgressManager.getInstance().runProcess(computable, progress); + } + catch (ProcessCanceledException e) { + return null; + } + finally { + cancelProgress.cancel(false); + } + } }