CompletionContributor responsiveness

Is there some way to make a CompletionContributor more responsive?

According to the thread below "All CompletionContributors are called in a background thread." but that doesn't seem to be the case, or I'm misunderstanding what that means.  If I intentionally insert a Thread.sleep() into the contributions ("extend" based, not in "fillCompletionVariants") the UI will hang, where I expected it to just slow down the rate at which the completions are filled in.

https://intellij-support.jetbrains.com/hc/en-us/community/posts/206757935-Async-autocompletion-CompletionContribitor-

0
2 comments

My PsiReference#getVariants had a similar problem - they were taking too long to complete.  I started to manually filter their results BEFORE making LookupElements and it sped up the response even though the getVariants docs say your'e supposed to let the caller filters the full result set for you.

Background threads in Java can't safely kill each other (https://docs.oracle.com/javase/7/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html), so IntelliJ gets around this by having some of the core APIs, like the ones that touch the PSI tree check if they should be canceled, so a lot of the code we write on top of those APIs checks and sees those cancelations for background processing automatically.  When you do a Thread.sleep(), that's core Java, not a wrapper in the OpenAPI, so it can't see the process cancelation messages and so can block stuff. That is what https://intellij-support.jetbrains.com/hc/en-us/community/posts/206757935/comments/206100895 is talking about.

So, for your pre-existing code that is unresponsive, you need to either (1) figure out how to return less stuff like I did for my PsiReference#getVariants by filtering by what's already typed or using context of where they're typing or (2) keep checking if you're canceled due to the 5 second (I think) timeout as detailed in the linked comment.

0

There still appears to be something going wrong here.  ProgressManager.checkCancelled() doesn't seem to ever do anything.  I've narrowed down some of the slow parts of the completion (iterating all of the keys in StubIndex's in most cases), some of which take up to 200ms.  I'm calling check cancelled plenty, but they don't ever seem to actually get cancelled.  The JavaCompletionContributor never seems to have a negative effect on typing, no matter how many results.

Edit: Unsurprisingly, this appears to have been caused by running with -Didea.ProcessCanceledException=disabled... something I had enabled some time ago and forgotten about.

0

Please sign in to leave a comment.