Running Quick Fix actions from the UI thread

Answered

In my plugin, I have a long-running task after which I want to show a Quick Fix action. I've read in this doc about the threading rules and I wanted to use executeOnPooledThread() to run the task in the background and then runReadAction() to switch to the UI thread. Unfortunately, using holder.registerProblem() doesn't show a Quick Fix on the UI (even though it works if not wrapped in executeOnPooledThread() and runReadAction()).

I have the following code:

class YamlElementVisitor(
private val holder: ProblemsHolder,
private val isOnTheFly: Boolean,
) : YamlPsiElementVisitor() {

override fun visitFile(file: PsiFile) {

ApplicationManager.getApplication().executeOnPooledThread {
           ... long running task in the background thread ...

ApplicationManager.getApplication().runReadAction {
... showing quick fix from the UI thread ...
holder.registerProblem(...)
}
}
}
}
}

What's the correct way of doing this?

0
4 comments

Could you please explain what this "long-running task" does and from where this visitor is invoked (local inspection?!)?

I assume its results will determine availability/behavior of eventually added quick fix?

0

The long-running task is making an HTTP request. After analysing the YAML file, I need to make the request to the API and show a quick fix based on the results. 

Currently, for showing a quick fix I'm using LocalQuickFixOnPsiElement (you can see the full code here).

Thanks for any suggestions!

0

Code analysis that does heavy lifting should preferrably use "External Annotator" API instead. It allows better decoupling of heavy process vs actual code annotation, https://plugins.jetbrains.com/docs/intellij/syntax-highlighting-and-error-highlighting.html#external-tool

I'd strongly suggest to consider migrating this use case.

0

I migrated my LocalInspectionTool to use ExternalAnnotator instead (as suggested) and it actually fixed my problem. Thanks for your help!

1

Please sign in to leave a comment.