дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 11:15:40 +02:00
fix(tasks): Make every background task cancellable, queued or running (#177)
Background tasks often couldn't be cancelled, or cancelling didn't stop them: - A cancel that arrived before the backend registered the request was dropped (build while saving files, multi-repository fetch/pull between repositories). The host now remembers early cancels (bounded, 2 min), and request ids start at a random value per page. - There was no queue and no common cancel path: backend-reported tasks (LSP progress, deployment transfers) couldn't be cancelled, and tool installs, VCS operations and update checks had no cancel button in Background Tasks. - Only the direct child process was killed, and JDK / tool archives were extracted without checking for cancellation. Tool installs and JDK downloads now share a downloads queue; cancelling a queued task removes it without starting any work. Every task cancels through one path that shows "Cancelling…" and then removes it; tasks that can't be interrupted show a disabled cancel button with the reason. IdeEvent::Task carries `cancellable` with a cancel_task command, cancellable LSP progress sends window/workDoneProgress/cancel, installers, curl and tar run in their own process group and are killed as a group, and extraction checks for cancellation between entries. Claude-Session: https://claude.ai/code/session_01Dq6jQQn8ZhRfkkyj3PRutA
Цей коміт міститься в:
1 джерело
c6621c5c36
коміт
1c46a1cd04
40 files changed
+888
-148
No files matched your search
@@ -39,9 +39,13 @@ export function checkForUpdates(): Promise<void> {
|
||||
|
||||
async function runCheck() {
|
||||
const title = t("app.update.checking");
|
||||
upsertTask({ id: CHECK_TASK_ID, title, message: null, fraction: null, done: false });
|
||||
// The check only reads: cancelling drops its answer (the request finishes on its own).
|
||||
let abandon = () => {};
|
||||
const abandoned = new Promise<"cancelled">((resolve) => (abandon = () => resolve("cancelled")));
|
||||
upsertTask({ id: CHECK_TASK_ID, title, message: null, fraction: null, done: false, cancel: () => abandon() });
|
||||
try {
|
||||
const r = await call(commands.appCheckUpdate());
|
||||
const r = await Promise.race([call(commands.appCheckUpdate()), abandoned]);
|
||||
if (r === "cancelled") return;
|
||||
if (!r.enabled) {
|
||||
notifications().notify({
|
||||
level: "info",
|
||||
@@ -122,6 +126,8 @@ async function runInstall(version: string) {
|
||||
fraction,
|
||||
done: false,
|
||||
cancel: p.type === "installing" ? undefined : cancel,
|
||||
// Replacing the app happens in one step that must not be cut short.
|
||||
uncancellable: p.type === "installing" ? t("app.update.installUncancellable") : undefined,
|
||||
});
|
||||
};
|
||||
// The notification's action is spent: progress lives in the status bar from here.
|
||||
|
||||
Reference in new issue
Заблокувати користувача