boolean (@NotNull ChooseByNameViewModel base, @NotNull final String pattern, final boolean everywhere, @NotNull final ProgressIndicator cancelled, @NotNull Processor<Object> consumer) { GotoTaskAction.CREATE_NEW_TASK_ACTION.setTaskName(pattern); if (!consumer.process(GotoTaskAction.CREATE_NEW_TASK_ACTION)) return false; TaskManager taskManager = TaskManager.getManager(myProject); List<Task> allCachedAndLocalTasks = ContainerUtil.concat(taskManager.getCachedIssues(), taskManager.getLocalTasks()); List<Task> filteredCachedAndLocalTasks = TaskSearchSupport.getLocalAndCachedTasks(taskManager, pattern, everywhere); if (!processTasks(filteredCachedAndLocalTasks, consumer, cancelled)) return false; if (filteredCachedAndLocalTasks.size() >= base.getMaximumListSizeLimit()) { return true; } if (myDisposed) { return false; } int delay = myFutureReference.get() == null && pattern.length() > 5 ? 0 : DELAY_PERIOD; Future<List<Task>> future = JobScheduler.getScheduler().schedule(() -> fetchFromServer(pattern, everywhere, cancelled), delay, TimeUnit.MILLISECONDS); // Newer request always wins Future<List<Task>> oldFuture = myFutureReference.getAndSet(future); if (oldFuture != null) { LOG.debug("Cancelling existing task"); oldFuture.cancel(true); } try { List<Task> tasks; while (true) { try { tasks = future.get(10, TimeUnit.MILLISECONDS); break; } catch (TimeoutException ignore) { } } myFutureReference.compareAndSet(future, null); // Exclude *all* cached and local issues, not only those returned by TaskSearchSupport.getLocalAndCachedTasks(). // Previously used approach might lead to the following strange behavior. Local task excluded by getLocalAndCachedTasks() // as "locally closed" (i.e. having no associated change list) was indeed *included* in popup because it // was contained in server response (as not remotely closed). Moreover on next request with pagination when the // same issues was not returned again by server it was *excluded* from popup (thus subsequent update reduced total // number of items shown). tasks.removeAll(allCachedAndLocalTasks); return processTasks(tasks, consumer, cancelled); } catch (InterruptedException interrupted) { Thread.interrupted(); } catch (CancellationException e) { LOG.debug("Task cancelled"); } catch (ExecutionException e) { Throwable cause = e.getCause(); if (cause instanceof ProcessCanceledException) { LOG.debug("Task cancelled via progress indicator"); } ExceptionUtil.rethrow(cause); } return false; }