diff --git a/ijs.tree b/ijs.tree
index 80252f0e9..e63612bb9 100644
--- a/ijs.tree
+++ b/ijs.tree
@@ -75,7 +75,7 @@
Suspending | -
- ensureActive() from Kotlin coroutine's API
- ProgressManager.checkCanceled() does not work in a suspending context.
- |
-
Blocking | -
- ProgressManager.checkCanceled()
- See Background Processes: Cancellation for details. - |
-
Progress Indicator | -
- ProgressIndicator.checkCanceled() , ProgressManager.checkCanceled()
- See Background Processes: Cancellation for details. - |
-
Suspending | -
-
- Any |
-
Blocking | -- unavailable - | -
Progress Indicator | -
- ProgressIndicator 's or ProgressManager 's methods
- See Background Processes: Tracking Progress for details. - |
-
- | To Suspending | -To Blocking | -To Progress Indicator | -
From Suspending | -- | -blockingContext() 1 |
- unavailable 3 | -
From Blocking | -runBlockingCancellable() 2 |
- - | -unavailable 4 | -
From Progress Indicator | -runBlockingCancellable() 2 |
- unavailable | -- | -
- 1 blockingContext() enables ProgressManager.checkCanceled() , forwards modality state, etc. It has an opposite behavior to runBlockingCancellable() .- 2 runBlockingCancellable() has an opposite behavior to blockingContext() - 3 coroutineToIndicator() is an internal API to aid platform migration- 4 blockingContextToIndicator() is an internal API to aid platform migration
- |
-
The IntelliJ Platform provides APIs that allow tracking the progress of background processes and canceling their + execution when they are canceled by a user, or they become obsolete due to some changes in the data model.
+ + + + +Available execution contexts differ depending on the IntelliJ Platform version. + For the details, select the required tab below.
+ +Background processes can be executed in two contexts:
+ + +Currently, the Progress Indicator context is the most widely used approach in the IntelliJ Platform. + As the platform's execution model moves towards coroutines, this approach + can be considered obsolete.
+ +Starting with 2024.2, it is recommended to execute new code in the + Job context.
+ +The following sections explain the contexts and provide information about process cancellation, progress + tracking, and switching between contexts.
+ + +Code executed in Kotlin coroutines is executed in the Job context. + Since 2024.2, coroutines are recommended for executing background tasks to maximize CPU utilization. + Note that executing code in coroutines is possible only with Kotlin. +
+ +
+ While code executed in the Job context should use suspending functions,
+ sometimes it is required to call non-suspending/blocking APIs that use methods such as
+ ProgressManager.checkCanceled()
or ModalityState.defaultModalityState()
.
+ Since 2024.2, these methods work as expected without the need to switch to the blocking context.
+
Job
class, which is used for task cancellation in suspending and non-suspending
+ functions.
+ Inspection
+
Background processes can be executed in three contexts:
+ +Starting with 2024.1, it is recommended to execute new code in the + suspending context.
+ +Code executed in Kotlin coroutines is executed in a suspending context. + Since 2024.1, this context is recommended for executing background tasks to maximize CPU utilization. + Note that executing code in coroutines is possible only with Kotlin. +
+In a suspending context, methods such as ProgressManager.checkCanceled()
or ModalityState.defaultModalityState()
+ won't have any effect.
+ Therefore, if their behavior is required, switch to a blocking
+ context.
Inspection
+
Executing tasks in a blocking context means executing them on a thread without access to the coroutine context (basically, in non-suspending functions) + and not under a progress indicator. + Such tasks can still be canceled, but they can't report progress.
+Plugins should not execute new code in the blocking context. + Always prefer executing tasks in the suspending context or + under the progress indicator if a plugin cannot use Kotlin.
+Functions which schedule execution via Application.executeOnPooledThread()
+ and similar methods, and which rely on ProgressManager.checkCanceled()
+ should be annotated with @RequiresBlockingContext
+ to inform clients about the required switch to a blocking context.
Inspection
+
Code executed via the Progress API
+ (ProgressManager
,
+ ProgressIndicator
,
+ etc.)
+ is executed in a progress indicator context.
+ See the section for details.
Executing code under the progress indicator is obsolete since 2024.1. + It is advised to use Kotlin coroutines in new code.
+Please note that obsolete status does not mean deprecation. + Executing code using the Progress API is still allowed, but coroutines are recommended as a more + performant solution.
+The following table presents APIs to use for checking whether a task was canceled in different execution + contexts.
+ +Job Context | ++ + | +
Progress Indicator | ++ + | +
Suspending Context | +
+
ensureActive()
+ from Kotlin coroutine's APIProgressManager.checkCanceled()
+ does not work in the suspending context.
+ To enable it,
+ switch to blockingContext() ,
+ if it is not possible to change the code.
+ |
+
Blocking Context | ++ + | +
The following table presents the possibilities and APIs to use for reporting progress in different + execution contexts.
+ +Job Context | +
+
ProgressStep
+ - a step-based progress reporting (see its KDoc for details)
+ RawProgressReporter
+ - a raw text, details, and fraction reporting (invoked via reportRawProgress() )
+
+ Any |
+
Progress Indicator | +
+ ProgressIndicator 's
+ or ProgressManager 's
+ methods
+ See Background Processes: Tracking + Progress for details. + |
+
Suspending Context | +|
Blocking Context | ++ unavailable + | +
The following table presents the possibilities and APIs to use for switching between different execution + contexts.
+ ++ | To Job Context | +To Progress Indicator | +|
From Job Context | +- | +
+ coroutineToIndicator() 1 |
+ |
From Progress Indicator | +
+ runBlockingCancellable() |
+ - | +|
+ 1
+ coroutineToIndicator()
+ is an experimental API, which was originally internal and created to aid
+ platform migration.
+ It is not recommended to switch from the Job context to the progress indicator.
+ Use it only if there is no other option.
+ |
+
+ | To Suspending Context | +To Blocking Context | +To Progress Indicator | +
From Suspending Context | +- | +blockingContext() 1 |
+ unavailable 3 | +
From Blocking Context | +runBlockingCancellable() 2 |
+ - | +unavailable 4 | +
From Progress Indicator | +runBlockingCancellable() 2 |
+ unavailable | +- | +
+ 1
+
+ blockingContext()
+ enables ProgressManager.checkCanceled() , forwards modality state, etc.
+ It has an opposite behavior to runBlockingCancellable() .
+ Since 2024.2, it is a no-operation function, as the blocking context was unified
+ with the suspending context into the Job context.
+ + + 2 + + runBlockingCancellable()
+ has an opposite behavior to blockingContext()
+ + + 3 + + coroutineToIndicator()
+ is an internal API to aid platform migration
+ + + 4 + + blockingContextToIndicator()
+ is an internal API to aid platform migration
+ |
+
It is only possible to:
+The lack of an API for switching from suspending and blocking contexts to progress indicator is + intentional. + Cancellable and trackable tasks should be run in coroutines as the progress indicator is obsolete since + 2024.1.
+