IDEA-203054 Thread leaks in tests

This commit is contained in:
Mikhail Sokolov
2018-12-04 16:51:50 +03:00
parent e05941f3d4
commit 47fac811d8
6 changed files with 22 additions and 32 deletions
@@ -25,22 +25,22 @@ import static com.intellij.ide.actions.searcheverywhere.SEResultsEqualityProvide
/**
* @author msokolov
*/
class MultithreadSearcher implements SESearcher {
class MultiThreadSearcher implements SESearcher {
private static final Logger LOG = Logger.getInstance(MultithreadSearcher.class);
private static final Logger LOG = Logger.getInstance(MultiThreadSearcher.class);
@NotNull private final Listener myListener;
@NotNull private final Executor myNotificationExecutor;
@NotNull private final SEResultsEqualityProvider myEqualityProvider;
/**
* Creates MultithreadSearcher with search results {@link Listener} and specifies executor which going to be used to call listener methods.
* Creates MultiThreadSearcher with search results {@link Listener} and specifies executor which going to be used to call listener methods.
* Use this constructor when you for example need to receive listener events only in AWT thread
* @param listener {@link Listener} to get notifications about searching process
* @param notificationExecutor searcher guarantees that all listener methods will be called only through this executor
* @param equalityProviders collection of equailty providers that checks if found elements is already in the search results
* @param equalityProviders collection of equality providers that checks if found elements are already in the search results
*/
MultithreadSearcher(@NotNull Listener listener,
MultiThreadSearcher(@NotNull Listener listener,
@NotNull Executor notificationExecutor,
@NotNull Collection<? extends SEResultsEqualityProvider> equalityProviders) {
myListener = listener;
@@ -48,17 +48,6 @@ class MultithreadSearcher implements SESearcher {
myEqualityProvider = SEResultsEqualityProvider.composite(equalityProviders);
}
/**
* Creates MultithreadSearcher with no guarantees about what thread gonna call {@code listener} methods.
* In this case listener will be called from different threads, so you have to care about thread safety
* @param listener {@link Listener} to get notifications about searching process
* @param equalityProviders collection of equailty providers that checks if found elements is already in the search results
*/
@SuppressWarnings("unused")
MultithreadSearcher(@NotNull Listener listener, @NotNull Collection<? extends SEResultsEqualityProvider> equalityProviders) {
this(listener, Runnable::run, equalityProviders);
}
/**
* Starts searching process with given search parameters
* @param contributorsAndLimits map of used searching contributors and maximum elements limit for them
@@ -68,9 +57,10 @@ class MultithreadSearcher implements SESearcher {
* @return {@link ProgressIndicator} that could be used to track and/or cancel searching process
*/
@Override
public ProgressIndicator search(Map<SearchEverywhereContributor<?>, Integer> contributorsAndLimits, String pattern,
public ProgressIndicator search(@NotNull Map<SearchEverywhereContributor<?>, Integer> contributorsAndLimits,
@NotNull String pattern,
boolean useNonProjectItems,
Function<SearchEverywhereContributor<?>, SearchEverywhereContributorFilter<?>> filterSupplier) {
@NotNull Function<SearchEverywhereContributor<?>, SearchEverywhereContributorFilter<?>> filterSupplier) {
LOG.debug("Search started for pattern [", pattern, "]");
FullSearchResultsAccumulator accumulator = new FullSearchResultsAccumulator(contributorsAndLimits, myEqualityProvider, myListener, myNotificationExecutor);
@@ -230,7 +220,7 @@ class MultithreadSearcher implements SESearcher {
private static abstract class ResultsAccumulator {
protected final Map<SearchEverywhereContributor<?>, Collection<ElementInfo>> sections;
protected final MultithreadSearcher.Listener myListener;
protected final MultiThreadSearcher.Listener myListener;
protected final Executor myNotificationExecutor;
protected final SEResultsEqualityProvider myEqualityProvider;
@@ -113,7 +113,7 @@ public class SearchEverywhereUI extends BigPopupUI implements DataProvider, Quic
myBufferedListener = null;
} else {
myBufferedListener = new ThrottlingListenerWrapper(THROTTLING_TIMEOUT, mySearchListener, Runnable::run);
mySearcher = new MultithreadSearcher(myBufferedListener, run -> ApplicationManager.getApplication().invokeLater(run), equalityProviders);
mySearcher = new MultiThreadSearcher(myBufferedListener, run -> ApplicationManager.getApplication().invokeLater(run), equalityProviders);
}
myServiceContributors = serviceContributors;
@@ -14,7 +14,7 @@ import java.util.stream.Collector;
/**
* Single thread implementation of {@link SESearcher}.
* Being used only as a temporary solution in case of problems with {@link MultithreadSearcher}.
* Being used only as a temporary solution in case of problems with {@link MultiThreadSearcher}.
*/
@Deprecated
class SingleThreadSearcher implements SESearcher {
@@ -10,16 +10,16 @@ import java.util.concurrent.Executor;
import java.util.function.BiConsumer;
/**
* Implementation of {@link MultithreadSearcher.Listener} which decrease events rate and raise batch updates
* Implementation of {@link MultiThreadSearcher.Listener} which decrease events rate and raise batch updates
* each {@code throttlingDelay} milliseconds.
* <br>
* Not thread-safe and should be notified only in EDT
*/
class ThrottlingListenerWrapper implements MultithreadSearcher.Listener {
class ThrottlingListenerWrapper implements MultiThreadSearcher.Listener {
public final int myThrottlingDelay;
private final MultithreadSearcher.Listener myDelegateListener;
private final MultiThreadSearcher.Listener myDelegateListener;
private final Executor myDelegateExecutor;
private final Buffer myBuffer = new Buffer();
@@ -28,7 +28,7 @@ class ThrottlingListenerWrapper implements MultithreadSearcher.Listener {
private final Alarm flushAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
private boolean flushScheduled;
ThrottlingListenerWrapper(int throttlingDelay, MultithreadSearcher.Listener delegateListener, Executor delegateExecutor) {
ThrottlingListenerWrapper(int throttlingDelay, MultiThreadSearcher.Listener delegateListener, Executor delegateExecutor) {
myThrottlingDelay = throttlingDelay;
myDelegateListener = delegateListener;
myDelegateExecutor = delegateExecutor;
@@ -22,7 +22,7 @@ import java.util.function.Function;
/**
* @author mikhail.sokolov
*/
public class MultithreadSearchDeadlockTest extends LightPlatformCodeInsightFixtureTestCase {
public class MultiThreadSearchDeadlockTest extends LightPlatformCodeInsightFixtureTestCase {
private static final Collection<SEResultsEqualityProvider> ourEqualityProviders = Collections.singleton(new TrivialElementsEqualityProvider());
@@ -44,7 +44,7 @@ public class MultithreadSearchDeadlockTest extends LightPlatformCodeInsightFixtu
Collector collector = new Collector();
Alarm alarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, getTestRootDisposable());
MultithreadSearcher searcher = new MultithreadSearcher(collector, command -> alarm.addRequest(command, 0), ourEqualityProviders);
MultiThreadSearcher searcher = new MultiThreadSearcher(collector, command -> alarm.addRequest(command, 0), ourEqualityProviders);
ProgressIndicator progressIndicator = searcher.search(contributorsMap, "tst", false, ignrd -> null);
try {
@@ -71,7 +71,7 @@ public class MultithreadSearchDeadlockTest extends LightPlatformCodeInsightFixtu
Collector collector = new Collector();
Alarm alarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, getTestRootDisposable());
MultithreadSearcher searcher = new MultithreadSearcher(collector, command -> alarm.addRequest(command, 0), ourEqualityProviders);
MultiThreadSearcher searcher = new MultiThreadSearcher(collector, command -> alarm.addRequest(command, 0), ourEqualityProviders);
ProgressIndicator progressIndicator = searcher.search(contributorsMap, "tst", false, ignrd -> null);
try {
@@ -103,7 +103,7 @@ public class MultithreadSearchDeadlockTest extends LightPlatformCodeInsightFixtu
Collector collector = new Collector();
Alarm alarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, getTestRootDisposable());
MultithreadSearcher searcher = new MultithreadSearcher(collector, command -> alarm.addRequest(command, 0), ourEqualityProviders);
MultiThreadSearcher searcher = new MultiThreadSearcher(collector, command -> alarm.addRequest(command, 0), ourEqualityProviders);
ProgressIndicator progressIndicator = searcher.search(contributorsMap, "tst", false, ignrd -> null);
try {
@@ -22,7 +22,7 @@ import java.util.function.Function;
/**
* @author mikhail.sokolov
*/
public class MultithreadSearchTest extends LightPlatformCodeInsightFixtureTestCase {
public class MultiThreadSearchTest extends LightPlatformCodeInsightFixtureTestCase {
private static final String MORE_ITEM = "...MORE";
private static final Collection<SEResultsEqualityProvider> ourEqualityProviders = Collections.singleton(new TrivialElementsEqualityProvider());
@@ -31,7 +31,7 @@ public class MultithreadSearchTest extends LightPlatformCodeInsightFixtureTestCa
Collection<Scenario> scenarios = createMultithreadScenarios();
SearchResultsCollector collector = new SearchResultsCollector();
Alarm alarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, getTestRootDisposable());
MultithreadSearcher searcher = new MultithreadSearcher(collector, command -> alarm.addRequest(command, 0), ourEqualityProviders);
MultiThreadSearcher searcher = new MultiThreadSearcher(collector, command -> alarm.addRequest(command, 0), ourEqualityProviders);
scenarios.forEach(scenario -> {
ProgressIndicator indicator = searcher.search(scenario.contributorsAndLimits, "tst", false, ignrd -> null);
@@ -418,7 +418,7 @@ public class MultithreadSearchTest extends LightPlatformCodeInsightFixtureTestCa
}
}
private static class SearchResultsCollector implements MultithreadSearcher.Listener {
private static class SearchResultsCollector implements MultiThreadSearcher.Listener {
private final Map<String, List<String>> myMap = new ConcurrentHashMap<>();
private final AtomicBoolean myFinished = new AtomicBoolean(false);