mirror of
https://github.com/JetBrains/intellij-sdk-code-samples.git
synced 2025-07-27 16:57:49 +08:00
execution_contexts.topic: Describe contexts for 2024.2+
This commit is contained in:
parent
fec5190b76
commit
bbb7cadd37
2
ijs.tree
2
ijs.tree
@ -75,7 +75,7 @@
|
||||
<toc-element topic="coroutine_dumps.md"/>
|
||||
</toc-element>
|
||||
<toc-element topic="background_processes.md"/>
|
||||
<toc-element topic="execution_contexts.md" accepts-web-file-names="coroutine-execution-contexts.html"/>
|
||||
<toc-element topic="execution_contexts.topic" accepts-web-file-names="coroutine-execution-contexts.html"/>
|
||||
</toc-element>
|
||||
<toc-element topic="messaging_infrastructure.md"/>
|
||||
<toc-element toc-title="Queries and Query Executors"/>
|
||||
|
@ -19,7 +19,7 @@ Annotator
|
||||
## B
|
||||
|
||||
Blocking Context
|
||||
: Executing in the [blocking context](execution_contexts.md#blocking-context) means executing tasks on a thread without access to a coroutine context.
|
||||
: Executing in the [blocking context](execution_contexts.topic#blocking-context) means executing tasks on a thread without access to a coroutine context.
|
||||
→ _Suspending Context_
|
||||
→ _Coroutine_
|
||||
|
||||
@ -130,7 +130,7 @@ Stubs
|
||||
: A subset of a → _Program Structure Interface_ tree in a binary serialized compact format, see [](stub_indexes.md).
|
||||
|
||||
Suspending Context
|
||||
: Executing in the [suspending context](execution_contexts.md#suspending-context-coroutines) means executing tasks in Kotlin coroutines.
|
||||
: Executing in the [suspending context](execution_contexts.topic#suspending-context-coroutines) means executing tasks in Kotlin coroutines.
|
||||
→ _Blocking Context_
|
||||
→ _Coroutine_
|
||||
|
||||
|
@ -14,7 +14,7 @@ The IntelliJ Platform executes background processes widely and provides two main
|
||||
|
||||
> Plugins targeting 2024.1+ should use [Kotlin coroutines](kotlin_coroutines.md), which is a more performant solution and provides the cancellation mechanism out of the box.
|
||||
>
|
||||
> See [](execution_contexts.md) for coroutine-based APIs to use in different contexts.
|
||||
> See [](execution_contexts.topic) for coroutine-based APIs to use in different contexts.
|
||||
>
|
||||
{style="warning" title="Use Kotlin Coroutines"}
|
||||
|
||||
|
@ -161,7 +161,7 @@ Sometimes it is not desired, as the coroutine in question was scheduled on [`Dis
|
||||
Anyway, it is suspicious when a read action cannot be executed on a background thread and a part of coroutine code cannot be suspended and rescheduled on EDT.
|
||||
This may signal a code issue.
|
||||
|
||||
Note that this API cannot be used in the [blocking context](execution_contexts.md#blocking-context).
|
||||
Note that this API cannot be used in the [blocking context](execution_contexts.topic#blocking-context).
|
||||
|
||||
### Suspending `readAndWriteAction()`
|
||||
|
||||
@ -176,7 +176,7 @@ Consider rewriting code to use it, if possible.
|
||||
|
||||
Use them if a read action is required, but it is unacceptable to reschedule code execution on a different dispatcher.
|
||||
|
||||
These APIs are marked to use only in the [blocking context](execution_contexts.md#blocking-context), so their usage in the [suspending context](execution_contexts.md#suspending-context-coroutines) will trigger a warning.
|
||||
These APIs are marked to use only in the [blocking context](execution_contexts.topic#blocking-context), so their usage in the [suspending context](execution_contexts.topic#suspending-context-coroutines) will trigger a warning.
|
||||
It is intentional, as coroutines should be prepared to be rescheduled and should use `readAction()`.
|
||||
|
||||
### Suspending `writeIntentReadAction()` and Blocking `WriteIntentReadAction.run()`/`compute()`
|
||||
|
@ -1,188 +0,0 @@
|
||||
<!-- Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
||||
|
||||
# Execution Contexts
|
||||
|
||||
<link-summary>Tracking execution progress, checking for cancellations, and switching between different execution contexts.</link-summary>
|
||||
|
||||
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.
|
||||
|
||||
Background processes can be executed in three contexts:
|
||||
- [](#suspending-context-coroutines) — available since 2024.1
|
||||
- [](#blocking-context)
|
||||
- [](#progress-indicator) — obsolete since 2024.1
|
||||
|
||||
Currently, the Progress Indicator context is the most widely used approach in the IntelliJ Platform.
|
||||
As the platform's execution model moves towards [coroutines](launching_coroutines.md), this approach can be considered obsolete.
|
||||
Starting with 2024.1, it is recommended to execute new code in the [suspending context](#suspending-context-coroutines).
|
||||
|
||||
The following sections explain the contexts and provide information about process cancellation, progress tracking, and switching between different contexts.
|
||||
|
||||
## Suspending Context (Coroutines)
|
||||
<primary-label ref="2024.1"/>
|
||||
|
||||
Code [executed in Kotlin coroutines](launching_coroutines.md) 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 a suspending context is possible only with [Kotlin](using_kotlin.md).
|
||||
>
|
||||
{style="warning"}
|
||||
|
||||
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](#switching-between-contexts).
|
||||
|
||||
> Inspection <control>Plugin DevKit | Code | Forbidden in suspend context method usage</control> reports calling blocking code from suspending context.
|
||||
|
||||
## Blocking Context
|
||||
|
||||
Executing tasks in a blocking context means executing them on a thread without access to the [coroutine context](#suspending-context-coroutines) (basically, in non-suspending functions) and not under [a progress indicator](#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](#suspending-context-coroutines) or under the [progress indicator](#progress-indicator) if a plugin cannot use Kotlin.
|
||||
|
||||
> Functions which schedule execution via [`Application.executeOnPooledThread()`](%gh-ic%/platform/core-api/src/com/intellij/openapi/application/Application.java)
|
||||
> and similar methods, and which rely on [`ProgressManager.checkCanceled()`](%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java)
|
||||
> should be annotated with [`@RequiresBlockingContext`](%gh-ic%/platform/core-api/src/com/intellij/util/concurrency/annotations/RequiresBlockingContext.kt)
|
||||
> to inform clients about the required switch to a blocking context.
|
||||
>
|
||||
> Inspection <control>Plugin DevKit | Code | Calling method should be annotated with @RequiresBlockingContext</control> reports missing annotations.
|
||||
|
||||
## Progress Indicator
|
||||
<primary-label ref="obsolete-2024.1"/>
|
||||
|
||||
Code executed via the Progress API
|
||||
([`ProgressManager`](%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java),
|
||||
[`ProgressIndicator`](%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicator.java), etc.)
|
||||
is executed in a progress indicator context.
|
||||
See the [](background_processes.md#progress-api) 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.
|
||||
>
|
||||
{style="tip" title="Obsolete approach since 2024.1"}
|
||||
|
||||
## Execution Contexts APIs
|
||||
|
||||
### Cancellation Check
|
||||
|
||||
The following table presents APIs to use for checking whether a task was canceled in different execution contexts.
|
||||
|
||||
<table style="header-column">
|
||||
<tr>
|
||||
<td width="16%">Suspending</td>
|
||||
<td>
|
||||
<code><a href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/ensure-active.html">ensureActive()</a></code> from Kotlin coroutine's API
|
||||
<warning>
|
||||
Note that <code><a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java">ProgressManager.checkCanceled()</a></code> does not work in a suspending context.
|
||||
</warning>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Blocking</td>
|
||||
<td>
|
||||
<code><a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java">ProgressManager.checkCanceled()</a></code>
|
||||
<p>See <a href="background_processes.md#cancellation">Background Processes: Cancellation</a> for details.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Progress Indicator</td>
|
||||
<td>
|
||||
<code><a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicator.java">ProgressIndicator.checkCanceled()</a></code>, <code><a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java">ProgressManager.checkCanceled()</a></code>
|
||||
<p>See <a href="background_processes.md#cancellation">Background Processes: Cancellation</a> for details.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### Progress Reporting
|
||||
|
||||
The following table presents the possibilities and APIs to use for reporting progress in different execution contexts.
|
||||
|
||||
<table style="header-column">
|
||||
<tr>
|
||||
<td width="16%">Suspending</td>
|
||||
<td>
|
||||
<ul>
|
||||
<li><code><a href="%gh-ic%/platform/util/progress/src/impl/ProgressStep.kt">ProgressStep</a></code> - a step-based progress reporting (see its KDoc for details)</li>
|
||||
<li><code><a href="%gh-ic%/platform/util/progress/src/RawProgressReporter.kt">RawProgressReporter</a></code> - a raw text, details, and fraction reporting (invoked via <code><a href="%gh-ic%/platform/util/progress/src/steps.kt">reportRawProgress()</a></code>)</li>
|
||||
</ul>
|
||||
<p>
|
||||
Any <code><a href="%gh-ic%/platform/util/progress/src/steps.kt">report*Progress()</a></code> function must be used inside <code>withBackgroundProgress()</code>, <code>withModalProgress()</code>, or <code>runWithModalProgressBlocking()</code> from <a href="%gh-ic%/platform/progress/shared/src/tasks.kt"><path>tasks.kt</path></a>.
|
||||
Otherwise, if there is no reporter in the context, using <code>report*Progress()</code> will have no effect.
|
||||
Example:
|
||||
</p>
|
||||
<code-block lang="kotlin">
|
||||
withBackgroundProgress(...) { // or other
|
||||
// ...
|
||||
reportProgress { reporter -> // or another report*Progress
|
||||
// do tasks and report progress
|
||||
}
|
||||
// ...
|
||||
}
|
||||
</code-block>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Blocking</td>
|
||||
<td>
|
||||
unavailable
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Progress Indicator</td>
|
||||
<td>
|
||||
<a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicator.java"><code>ProgressIndicator</code>'s</a> or <a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java"><code>ProgressManager</code>'s</a> methods
|
||||
<p>See <a href="background_processes.md#tracking-progress">Background Processes: Tracking Progress</a> for details.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### Switching Between Contexts
|
||||
|
||||
The following table presents the possibilities and APIs to use for switching between different execution contexts.
|
||||
|
||||
<table style="both">
|
||||
<tr>
|
||||
<td width="16%"></td>
|
||||
<td>To Suspending</td>
|
||||
<td>To Blocking</td>
|
||||
<td>To Progress Indicator</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>From Suspending</td>
|
||||
<td>-</td>
|
||||
<td><code>blockingContext()</code> <sup>1</sup></td>
|
||||
<td>unavailable <sup>3</sup></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>From Blocking</td>
|
||||
<td><code>runBlockingCancellable()</code> <sup>2</sup></td>
|
||||
<td>-</td>
|
||||
<td>unavailable <sup>4</sup></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>From Progress Indicator</td>
|
||||
<td><code>runBlockingCancellable()</code> <sup>2</sup></td>
|
||||
<td>unavailable</td>
|
||||
<td>-</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<sup>1</sup> <i><a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/coroutines.kt"><code>blockingContext()</code></a> enables <code>ProgressManager.checkCanceled()</code>, forwards modality state, etc. It has an opposite behavior to <code>runBlockingCancellable()</code>.</i><br/>
|
||||
<sup>2</sup> <i><a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/coroutines.kt"><code>runBlockingCancellable()</code></a> has an opposite behavior to <code>blockingContext()</code></i><br/>
|
||||
<sup>3</sup> <i><a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/coroutines.kt"><code>coroutineToIndicator()</code></a> is an internal API to aid platform migration</i><br/>
|
||||
<sup>4</sup> <i><a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/coroutines.kt"><code>blockingContextToIndicator()</code></a> is an internal API to aid platform migration</i>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
It is only possible to:
|
||||
- switch from the blocking context or progress indicator to the suspending context
|
||||
- switch from the suspending context to the blocking context
|
||||
|
||||
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.
|
||||
|
||||
<include from="snippets.md" element-id="missingContent"/>
|
@ -0,0 +1,408 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
||||
<!DOCTYPE topic SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
id="execution_contexts" title="Execution Contexts">
|
||||
|
||||
<title>Execution Contexts</title>
|
||||
<link-summary>Tracking execution progress, checking for cancellations, and switching between different execution contexts.</link-summary>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<!--TODO: what if someone wants to support 2024.1 and 2024.2. Can they safely call blockingContext as it is no-op now?-->
|
||||
<!--TODO: any caveats for progress reporting in Job context?-->
|
||||
|
||||
<p>Available execution contexts differ depending on the IntelliJ Platform version.
|
||||
For the details, select the required tab below.</p>
|
||||
|
||||
<tabs group="execution-contexts">
|
||||
<tab title="2024.2+" group-key="2024.2">
|
||||
<p>Background processes can be executed in two contexts:</p>
|
||||
<list>
|
||||
<li><a anchor="job-context-coroutines"/> — available since 2024.2</li>
|
||||
<li><a anchor="progress-indicator"/> — obsolete since 2024.1</li>
|
||||
</list>
|
||||
|
||||
<p id="progress-indicator-migration-note">Currently, the Progress Indicator context is the most widely used approach in the IntelliJ Platform.
|
||||
As the platform's execution model moves towards <a href="launching_coroutines.md">coroutines</a>, this approach
|
||||
can be considered obsolete.</p>
|
||||
|
||||
<p>Starting with 2024.2, it is recommended to execute new code in the
|
||||
<a anchor="job-context-coroutines">Job context</a>.</p>
|
||||
|
||||
<p id="sections-note">The following sections explain the contexts and provide information about process cancellation, progress
|
||||
tracking, and switching between contexts.</p>
|
||||
|
||||
<!-- TODO: I'm not convinced the Job context is a good name. Suspending or Coroutine Context would be clearer, IHMO. -->
|
||||
<chapter title="Job Context (Coroutines)" id="job-context-coroutines">
|
||||
<primary-label ref="2024.2"/>
|
||||
|
||||
<tip>
|
||||
Suspending and Blocking contexts available in 2024.1 have been unified into the Job context.
|
||||
See the <a href="https://youtrack.jetbrains.com/issue/IJPL-445/Reconsider-blockingContext">
|
||||
<i>Reconsider blockingContext</i></a> issue for more details.
|
||||
</tip>
|
||||
|
||||
<p>Code <a href="launching_coroutines.md">executed in Kotlin coroutines</a> 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 <a href="using_kotlin.md">Kotlin</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
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
|
||||
<code>ProgressManager.checkCanceled()</code> or <code>ModalityState.defaultModalityState()</code>.
|
||||
Since 2024.2, these methods work as expected without the need to switch to the blocking context.
|
||||
</p>
|
||||
|
||||
<tip>The "Job" word in the name refers to the
|
||||
<a href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-job/">
|
||||
<code>Job</code></a> class, which is used for task cancellation in suspending and non-suspending
|
||||
functions.
|
||||
</tip>
|
||||
|
||||
<tip>
|
||||
<p>Inspection
|
||||
<control>Plugin DevKit | Code | Forbidden in suspend context method usage</control>
|
||||
reports calling blocking code from suspending context.
|
||||
While this is not an error, it is recommended to use suspending counterparts if they exist.
|
||||
</p>
|
||||
</tip>
|
||||
</chapter>
|
||||
</tab>
|
||||
|
||||
<tab title="2024.1" group-key="2024.1">
|
||||
<p>Background processes can be executed in three contexts:</p>
|
||||
<list>
|
||||
<li><a anchor="suspending-context-coroutines"/> — available since 2024.1</li>
|
||||
<li><a anchor="blocking-context"/></li>
|
||||
<li><a anchor="progress-indicator"/> — obsolete since 2024.1</li>
|
||||
</list>
|
||||
<include from="execution_contexts.topic" element-id="progress-indicator-migration-note"/>
|
||||
|
||||
<p>Starting with 2024.1, it is recommended to execute new code in the
|
||||
<a anchor="suspending-context-coroutines">suspending context</a>.</p>
|
||||
|
||||
<include from="execution_contexts.topic" element-id="sections-note"/>
|
||||
|
||||
<chapter title="Suspending Context (Coroutines)" id="suspending-context-coroutines">
|
||||
<primary-label ref="2024.1"/>
|
||||
<p>Code <a href="launching_coroutines.md">executed in Kotlin coroutines</a> 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 <a href="using_kotlin.md">Kotlin</a>.
|
||||
</p>
|
||||
<p>In a suspending context, methods such as <code>ProgressManager.checkCanceled()</code> or <code>ModalityState.defaultModalityState()</code>
|
||||
won't have any effect.
|
||||
Therefore, if their behavior is required, <a anchor="switching-between-contexts">switch to a blocking
|
||||
context</a>.</p>
|
||||
<tip>
|
||||
<p>Inspection
|
||||
<control>Plugin DevKit | Code | Forbidden in suspend context method usage</control>
|
||||
reports calling blocking code from suspending context.
|
||||
</p>
|
||||
</tip>
|
||||
</chapter>
|
||||
|
||||
<chapter title="Blocking Context" id="blocking-context">
|
||||
<p>Executing tasks in a blocking context means executing them on a thread without access to the <a
|
||||
anchor="suspending-context-coroutines">coroutine context</a> (basically, in non-suspending functions)
|
||||
and not under <a anchor="progress-indicator">a progress indicator</a>.
|
||||
Such tasks can still be canceled, but they can't report progress.</p>
|
||||
<p>Plugins should not execute new code in the blocking context.
|
||||
Always prefer executing tasks in the <a anchor="suspending-context-coroutines">suspending context</a> or
|
||||
under the <a anchor="progress-indicator">progress indicator</a> if a plugin cannot use Kotlin.</p>
|
||||
<tip>
|
||||
<!--TODO: copy it to Job Context and state that it is used for choosing a better non-blocking API? revise what Daniil said -->
|
||||
<p>Functions which schedule execution via <a
|
||||
href="%gh-ic%/platform/core-api/src/com/intellij/openapi/application/Application.java"><code>Application.executeOnPooledThread()</code></a>
|
||||
and similar methods, and which rely on <a
|
||||
href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java"><code>ProgressManager.checkCanceled()</code></a>
|
||||
should be annotated with <a
|
||||
href="%gh-ic%/platform/core-api/src/com/intellij/util/concurrency/annotations/RequiresBlockingContext.kt"><code>@RequiresBlockingContext</code></a>
|
||||
to inform clients about the required switch to a blocking context.</p>
|
||||
<p>Inspection
|
||||
<control>Plugin DevKit | Code | Calling method should be annotated with @RequiresBlockingContext
|
||||
</control>
|
||||
reports missing annotations.
|
||||
</p>
|
||||
</tip>
|
||||
</chapter>
|
||||
</tab>
|
||||
</tabs>
|
||||
|
||||
|
||||
<chapter title="Progress Indicator" id="progress-indicator">
|
||||
<primary-label ref="obsolete-2024.1"/>
|
||||
<p>Code executed via the Progress API
|
||||
(<a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java"><code>ProgressManager</code></a>,
|
||||
<a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicator.java"><code>ProgressIndicator</code></a>,
|
||||
etc.)
|
||||
is executed in a progress indicator context.
|
||||
See the <a href="background_processes.md" anchor="progress-api"/> section for details.</p>
|
||||
<tip title="Obsolete approach since 2024.1">
|
||||
<p>Executing code under the progress indicator is obsolete since 2024.1.
|
||||
It is advised to use Kotlin coroutines in new code.</p>
|
||||
<p>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.</p>
|
||||
</tip>
|
||||
</chapter>
|
||||
<chapter title="Execution Contexts APIs" id="execution-contexts-apis">
|
||||
<chapter title="Cancellation Check" id="cancellation-check">
|
||||
<p>The following table presents APIs to use for checking whether a task was canceled in different execution
|
||||
contexts.</p>
|
||||
|
||||
<tip>
|
||||
See <a href="background_processes.md#cancellation">Background Processes: Cancellation</a> for
|
||||
general cancellation mechanism explanation.
|
||||
</tip>
|
||||
|
||||
<tabs group="execution-contexts">
|
||||
<tab title="2024.2+" group-key="2024.2">
|
||||
<table style="header-column">
|
||||
<tr>
|
||||
<td width="16%">Job Context</td>
|
||||
<td>
|
||||
<list>
|
||||
<li><a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/coroutines.kt">
|
||||
<code>checkCanceled()</code></a></li>
|
||||
<li><a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java">
|
||||
<code>ProgressManager.checkCanceled()</code></a></li>
|
||||
</list>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="cancellation-check-progress-indicator-row">
|
||||
<td>Progress Indicator</td>
|
||||
<td>
|
||||
<list>
|
||||
<li><a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicator.java">
|
||||
<code>ProgressIndicator.checkCanceled()</code></a></li>
|
||||
<li><a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java">
|
||||
<code>ProgressManager.checkCanceled()</code></a></li>
|
||||
</list>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</tab>
|
||||
<tab title="2024.1" group-key="2024.1">
|
||||
<table style="header-column">
|
||||
<tr>
|
||||
<td width="16%">Suspending Context</td>
|
||||
<td>
|
||||
<list>
|
||||
<li><a href="https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/ensure-active.html"><code>ensureActive()</code></a>
|
||||
from Kotlin coroutine's API</li>
|
||||
</list>
|
||||
|
||||
<warning>
|
||||
Note that
|
||||
<a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java"><code>ProgressManager.checkCanceled()</code></a>
|
||||
does not work in the suspending context.
|
||||
To enable it,
|
||||
<a anchor="switching-between-contexts">switch to <code>blockingContext()</code></a>,
|
||||
if it is not possible to change the code.
|
||||
</warning>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Blocking Context</td>
|
||||
<td>
|
||||
<list>
|
||||
<li><a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java"><code>ProgressManager.checkCanceled()</code></a></li>
|
||||
</list>
|
||||
</td>
|
||||
</tr>
|
||||
<include from="execution_contexts.topic" element-id="cancellation-check-progress-indicator-row"/>
|
||||
</table>
|
||||
</tab>
|
||||
</tabs>
|
||||
</chapter>
|
||||
|
||||
<chapter title="Progress Reporting" id="progress-reporting">
|
||||
<p>The following table presents the possibilities and APIs to use for reporting progress in different
|
||||
execution contexts.</p>
|
||||
|
||||
<tabs group="execution-contexts">
|
||||
<tab title="2024.2+" group-key="2024.2">
|
||||
<table style="header-column">
|
||||
<tr>
|
||||
<td width="16%">Job Context</td>
|
||||
<td id="progress-reporting-job-context-cell">
|
||||
<list>
|
||||
<li><a href="%gh-ic%/platform/util/progress/src/impl/ProgressStep.kt"><code>ProgressStep</code></a>
|
||||
- a step-based progress reporting (see its KDoc for details)
|
||||
</li>
|
||||
<li><a href="%gh-ic%/platform/util/progress/src/RawProgressReporter.kt"><code>RawProgressReporter</code></a>
|
||||
- a raw text, details, and fraction reporting (invoked via <a
|
||||
href="%gh-ic%/platform/util/progress/src/steps.kt"><code>reportRawProgress()</code></a>)
|
||||
</li>
|
||||
</list>
|
||||
<p>
|
||||
Any <a href="%gh-ic%/platform/util/progress/src/steps.kt"><code>report*Progress()</code></a>
|
||||
function must be used inside <code>withBackgroundProgress()</code>, <code>withModalProgress()</code>,
|
||||
or <code>runWithModalProgressBlocking()</code> from <a
|
||||
href="%gh-ic%/platform/progress/shared/src/tasks.kt">
|
||||
<path>tasks.kt</path>
|
||||
</a>.
|
||||
Otherwise, if there is no reporter in the context, using <code>report*Progress()</code> will
|
||||
have no effect.
|
||||
Example:
|
||||
</p>
|
||||
<code-block lang="kotlin">
|
||||
withBackgroundProgress(...) { // or other
|
||||
// ...
|
||||
reportProgress { reporter -> // or another report*Progress
|
||||
// do tasks and report progress
|
||||
}
|
||||
// ...
|
||||
}
|
||||
</code-block>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="progress-reporting-progress-indicator-row">
|
||||
<td>Progress Indicator</td>
|
||||
<td>
|
||||
<a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/ProgressIndicator.java"><code>ProgressIndicator</code>'s</a>
|
||||
or <a
|
||||
href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/ProgressManager.java"><code>ProgressManager</code>'s</a>
|
||||
methods
|
||||
<p>See <a href="background_processes.md#tracking-progress">Background Processes: Tracking
|
||||
Progress</a> for details.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</tab>
|
||||
<tab title="2024.1" group-key="2024.1">
|
||||
<table style="header-column">
|
||||
<tr>
|
||||
<td width="16%">Suspending Context</td>
|
||||
<include from="execution_contexts.topic" element-id="progress-reporting-job-context-cell"/>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Blocking Context</td>
|
||||
<td>
|
||||
unavailable
|
||||
</td>
|
||||
</tr>
|
||||
<include from="execution_contexts.topic" element-id="progress-reporting-progress-indicator-row"/>
|
||||
</table>
|
||||
</tab>
|
||||
</tabs>
|
||||
</chapter>
|
||||
|
||||
<chapter title="Switching Between Contexts" id="switching-between-contexts">
|
||||
<p>The following table presents the possibilities and APIs to use for switching between different execution
|
||||
contexts.</p>
|
||||
|
||||
<tabs group="execution-contexts">
|
||||
<tab title="2024.2+" group-key="2024.2">
|
||||
<table style="both">
|
||||
<tr>
|
||||
<td width="16%"/>
|
||||
<td width="42%">To Job Context</td>
|
||||
<td width="42%">To Progress Indicator</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>From Job Context</td>
|
||||
<td>-</td>
|
||||
<td><a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/coroutines.kt">
|
||||
<code>coroutineToIndicator()</code></a> <sup>1</sup></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>From Progress Indicator</td>
|
||||
<td><a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/coroutines.kt">
|
||||
<code>runBlockingCancellable()</code></a></td>
|
||||
<td>-</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<sup>1</sup>
|
||||
<i><code>coroutineToIndicator()</code>
|
||||
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.</i>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</tab>
|
||||
<tab title="2024.1" group-key="2024.1">
|
||||
<table style="both">
|
||||
<tr>
|
||||
<td width="16%"/>
|
||||
<td>To Suspending Context</td>
|
||||
<td>To Blocking Context</td>
|
||||
<td>To Progress Indicator</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>From Suspending Context</td>
|
||||
<td>-</td>
|
||||
<td><code>blockingContext()</code> <sup>1</sup></td>
|
||||
<td>unavailable <sup>3</sup></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>From Blocking Context</td>
|
||||
<td><code>runBlockingCancellable()</code> <sup>2</sup></td>
|
||||
<td>-</td>
|
||||
<td>unavailable <sup>4</sup></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>From Progress Indicator</td>
|
||||
<td><code>runBlockingCancellable()</code> <sup>2</sup></td>
|
||||
<td>unavailable</td>
|
||||
<td>-</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<sup>1</sup>
|
||||
<i><a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/coroutines.kt">
|
||||
<code>blockingContext()</code></a>
|
||||
enables <code>ProgressManager.checkCanceled()</code>, forwards modality state, etc.
|
||||
It has an opposite behavior to <code>runBlockingCancellable()</code>.
|
||||
Since 2024.2, it is a no-operation function, as the blocking context was unified
|
||||
with the suspending context into the Job context.</i>
|
||||
<br/>
|
||||
|
||||
<sup>2</sup>
|
||||
<i><a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/coroutines.kt">
|
||||
<code>runBlockingCancellable()</code></a>
|
||||
has an opposite behavior to <code>blockingContext()</code></i>
|
||||
<br/>
|
||||
|
||||
<sup>3</sup>
|
||||
<i><a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/coroutines.kt">
|
||||
<code>coroutineToIndicator()</code></a>
|
||||
is an internal API to aid platform migration</i>
|
||||
<br/>
|
||||
|
||||
<sup>4</sup>
|
||||
<i><a href="%gh-ic%/platform/core-api/src/com/intellij/openapi/progress/coroutines.kt">
|
||||
<code>blockingContextToIndicator()</code></a>
|
||||
is an internal API to aid platform migration</i>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>It is only possible to:</p>
|
||||
<list>
|
||||
<li>switch from the blocking context or progress indicator to the suspending context</li>
|
||||
<li>switch from the suspending context to the blocking context</li>
|
||||
</list>
|
||||
<p>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.</p>
|
||||
</tab>
|
||||
</tabs>
|
||||
|
||||
<include from="snippets.md" element-id="missingContent"/>
|
||||
</chapter>
|
||||
</chapter>
|
||||
|
||||
</topic>
|
||||
|
||||
<!--TODO: glossary: Job context-->
|
||||
<!--TODO: search for execution_context.topic and adjust dependant content-->
|
||||
<!--TODO: add to content updates-->
|
@ -6,7 +6,7 @@
|
||||
|
||||
<tldr>
|
||||
|
||||
**Implementation**: Progress tracking in [Progress API](background_processes.md#tracking-progress) and [Kotlin Coroutines](execution_contexts.md#progress-reporting)
|
||||
**Implementation**: Progress tracking in [Progress API](background_processes.md#tracking-progress) and [Kotlin Coroutines](execution_contexts.topic#progress-reporting)
|
||||
|
||||
</tldr>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user