A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://plugins.jetbrains.com/docs/intellij/coroutine-scopes.html below:

Coroutine Scopes | IntelliJ Platform Plugin SDK

Coroutine Scopes

This section focuses on explaining coroutines in the specific context of the IntelliJ Platform. If you are not experienced with Kotlin Coroutines, it is highly recommended to get familiar with Learning Resources first.

Kotlin's coroutines follow the principle of structured concurrency. It means that each coroutine is run in a specific CoroutineScope, which delimits the lifetime of the coroutine. This ensures that they are not lost and do not leak. An outer scope does not complete until all its child coroutines are completed. Cancellation of the outer scope also cancels its child coroutines. Structured concurrency ensures that any errors in the code are properly reported and never lost.

IntelliJ Platform Scopes

IntelliJ Platform provides special coroutine scopes that help ensure proper structured concurrency of coroutines run from the platform or plugin code. After cancellation, the platform awaits the completion of each scope. Using correct parent scopes guarantees that child coroutines will be properly canceled when no longer needed, preventing resource leaks.

The following diagram presents the scopes and their parent-child relationships:

All scopes presented on the diagram are supervisor scopes — they ignore the failures of their children.

Each coroutine scope can have only one actual parent, pointed with solid arrow lines. Dashed arrow lines point to fictional parents, which follow the actual coroutine parent-child semantics:

The Application×Plugin and Project×Plugin are intersection scopes with two semantic parents (actual and fictional).

Main Scopes Intersection Scopes

Intersection scopes enable creating coroutines whose lifetime is limited by application/project and plugin lifetimes, e.g., application/project services provided by a plugin.

Service Scopes

The Application Service and Project Service scopes are bound to an application and project service lifetimes accordingly. They are children of the Intersection Scopes, which means that they are canceled when the application/project is closed or a plugin is unloaded.

The service scope is provided to services via constructor injection. The following constructor signatures are supported:

Each service instance receives its own scope instance. The injected scopes' contexts contain Dispatchers.Default and CoroutineName(serviceClass).

See Launching Coroutine From Service Scope for full samples.

Using a Correct Scope Use Service Scopes

If a plugin requires running some code in a coroutine, the approach recommended in most cases is to create a separate service that will receive its own scope via constructor and launch the coroutine in this scope. This approach guarantees the usage of the correct scope, preventing leaks and canceling wrong scopes and killing all their (e.g., application's or project's) coroutines accidentally.

Note that since 2024.2, AnAction.actionPerformed() logic can be executed in the current thread coroutine scope.

See the Launching Coroutines section for details.

The following sections describe the potential problems that would occur if the wrong coroutine scopes were used. This allows better understanding of the platform scopes and why the service approach mentioned above must be used.

Do Not Use Application/Project Scope

Application and Project scopes are exposed with Application.getCoroutineScope() and Project.getCoroutineScope(). Never use these methods, as they are deprecated and will be removed in the future.

Using these scopes could easily lead to project or plugin class leaks.

  1. Project leak:

    application.coroutineScope.launch { project.getService(PsiDirectoryFactory::class.java) }

    Closing the project cancels its scope. The application scope remains active, and the project is leaked.

    ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ Application Scope Project Scope Project leak Lifetimes
  2. Plugin leak:

    project.coroutineScope.launch { project.getService(MyPluginService::class.java) }

    Unloading of the plugin cancels its scope. The project scope remains active, and the plugin classes are leaked.

    ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ Project Scope Plugin Scope MyPluginService leak Lifetimes
Do Not Use Intersection Scopes

There is no API for retrieving Application×Plugin and Project×Plugin intersection scopes, but let's assume there is a method exposing the Project×Plugin scope:

/** * Returns the correct intersection scope for the project and plugin * by a given plugin class. */ fun Project.getCoroutineScope(pluginClass: Class<*>): CoroutineScope

Using this scope could lead to a plugin leak:

project.getCoroutineScope(PluginBService::class.java).launch { project.getService(PluginAService::class.java) }

Unloading of Plugin A cancels its scope. The Project × Plugin B scope remains active, and the Plugin A classes are leaked.

‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ ‎ Application Scope Plugin A Scope Project Scope Project × Plugin A Scope Plugin B Scope Project × Plugin B Scope PluginAService leak Correct PluginAService lifetime should end here Lifetimes

If a topic is not covered in the above sections, let us know via the Was this page helpful? feedback form below or other channels.

Be specific about the topics and reasons for adding them and leave your email in case we need more details. Thanks for your feedback!

11 August 2025


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4