void (@NotNull Project project, @NotNull Component component) { AtomicReference<String> activityName = new AtomicReference<>(); PotemkinProgress progress = new PotemkinProgress("Updating all actions", project, null, null); progress.setText("Warming up..."); progress.setDelayInMillis(0); AtomicLong lastCheckCanceled = new AtomicLong(System.nanoTime()); Map<String, TraceData> noCheckCanceled = new HashMap<>(); Runnable noCheckCanceledChecker = () -> { long maxDiff = MIN_REPORTED_NO_CHECK_CANCELED_MILLIS; while (progress.isRunning()) { String text = activityName.get(); long last = lastCheckCanceled.get(); long curDiff = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - last); if (last != 0 && text != null && curDiff > maxDiff) { StackTraceElement[] trace = EDT.getEventDispatchThread().getStackTrace(); if (TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - last) > maxDiff && text.equals(activityName.get())) { noCheckCanceled.put(text, new TraceData(curDiff, trace, noCheckCanceled.get(text))); } } TimeoutUtil.sleep(maxDiff / 3 + 1); } }; MyProgress cancellationChecker = new MyProgress() { @Override public void interact() { lastCheckCanceled.set(System.nanoTime()); } }; try { progress.start(); // show progress but avoid the overhead when measuring AppExecutorUtil.getAppExecutorService().execute(noCheckCanceledChecker); updateAllActionsInner(project, component, (name, displayName, runnable) -> { progress.setText("Checking '" + Objects.requireNonNullElse(displayName, name) + "'"); progress.interact(); return ProgressManager.getInstance().runProcess(() -> { long start = System.nanoTime(); try { activityName.set(name); lastCheckCanceled.set(start); runnable.run(); } catch (Throwable th) { if (!(th instanceof ControlFlowException)) { LOG.error(th); // KotlinStdlibCacheImpl.findStdlibInModuleDependencies PCE } } finally { activityName.set(null); } return TimeoutUtil.getDurationMillis(start); }, cancellationChecker); }); } finally { progress.stop(); } LOG.info("---- " + noCheckCanceled.size() + " no-checkCanceled places detected ----"); if (!noCheckCanceled.isEmpty()) { String[] keys = ArrayUtil.toStringArray(noCheckCanceled.keySet()); Arrays.sort(keys, Comparator.comparing(o -> -noCheckCanceled.get(o).delta)); for (int i = 0; i < keys.length; i++) { TraceData last = Objects.requireNonNull(noCheckCanceled.get(keys[i])); int traceCount = 0; for (TraceData cur = last; cur != null; cur = cur.next) traceCount++; LOG.info("no checkCanceled (" + i + ") (" + traceCount + " hits) in " + last.delta + " ms - " + keys[i]); } int min = Math.min(noCheckCanceled.size(), 5); LOG.info("---- top " + min + " of " + noCheckCanceled.size() + " no-checkCanceled places ----"); for (int i = 0; i < keys.length && i < min; i++) { TraceData last = noCheckCanceled.get(keys[i]); int traceCount = 0, traceIdx = 0; for (TraceData cur = last; cur != null; cur = cur.next) traceCount++; for (TraceData cur = last; cur != null && traceIdx < 3; cur = cur.next, traceIdx++) { Throwable throwable = new Throwable("no checkCanceled (" + i + ") (" + (traceIdx + 1) + " of " + traceCount + " hits)" + " in " + cur.delta + " ms - " + keys[i]); throwable.setStackTrace(cur.trace); LOG.info(ExceptionUtil.getThrowableText(throwable, ActionUpdatesBenchmarkAction.class.getName())); } } } }