Launching Coroutines
In the IntelliJ Platform, coroutines can be launched with one of the following approaches:
The
currentThreadCoroutineScope
function for executing actions.The
runBlockingCancellable
function. (not recommended)
Launching Coroutine From Service Scope
The recommended approach is creating a service that receives its scope via the constructor injection and launching a coroutine from the service methods. Note that while creating a service instance does allocate additional resources, using a dedicated service and scope remains a lightweight and fundamentally safe solution for launching coroutines. It should be used whenever possible.
The pattern is as follows:
The injected scope is created per service, so each instance has its own isolated scope with a common parent, which is an intersection scope. The injected scope is canceled when the container (application/project) is shut down or when the plugin is unloaded.
Using currentThreadCoroutineScope
Action behavior performed in AnAction.actionPerformed()
can be executed in a coroutine via currentThreadCoroutineScope
:
Compared to the service scope approach, using currentThreadCoroutineScope()
enables Action System infrastructure to control the launched coroutine and cancel it if needed. In the case of service scopes, the infrastructure code can't control a coroutine launched from an action, as service scopes are "more global" and live longer than the action trigger.
Using runBlockingCancellable
In a standard coroutine-based application, the bridge between the regular blocking code and the suspending code is the runBlocking
function.
In the IntelliJ Platform, a similar purpose is achieved by the runBlockingCancellable
function. In addition to the same semantics as runBlocking
, the action gets canceled when the current progress indicator or the current job is canceled.