IntelliJ Platform Plugin SDK Help

Launching Coroutines

There are two approaches to launching coroutines in the IntelliJ Platform:

  1. Service with its own scope. (recommended)

  2. The runBlockingCancellable function.

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. Please note that while creating a service instance does allocate additional resources, using a dedicated service and scope remains a lightweight and, most importantly, safe solution for launching coroutines. It should be used whenever possible.

The pattern is as follows:

@Service class MyApplicationService( private val cs: CoroutineScope ) { fun scheduleSomething() { cs.launch { // do something } } }
@Service(Service.Level.PROJECT) class MyProjectService( private val project: Project, private val cs: CoroutineScope ) { fun scheduleSomething() { cs.launch { // do something } } }

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 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.

Last modified: 13 June 2024