Skip to content

Commit

Permalink
feat(terminal): add cancel logic when user close terminal
Browse files Browse the repository at this point in the history
  • Loading branch information
JiyuShao committed Jul 5, 2024
1 parent d22550b commit ef904b5
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
type CancelHandler = () => void;

class CancelSignal {
private _cancelled: boolean = false;
private _handlers: CancelHandler[] = [];

get cancelled(): boolean {
return this._cancelled;
}

addEventListener(type: 'cancel', handler: CancelHandler) {
if (type === 'cancel') {
this._handlers.push(handler);
}
}

removeEventListener(type: 'cancel', handler: CancelHandler) {
if (type === 'cancel') {
this._handlers = this._handlers.filter(h => h !== handler);
}
}

dispatchEvent(type: 'cancel') {
if (type === 'cancel' && !this._cancelled) {
this._cancelled = true;
this._handlers.forEach(handler => handler());
}
}
}

export class CancelManager {
private _signal: CancelSignal;

constructor() {
this._signal = new CancelSignal();
}

get signal(): CancelSignal {
return this._signal;
}

async runCancellable<T>(promise: Promise<T>): Promise<T> {
return new Promise<T>((resolve, reject) => {
this._signal.addEventListener('cancel', () =>
reject(new Error('Operation cancelled'))
);
promise.then(resolve).catch(reject);
});
}

cancel() {
this._signal.dispatchEvent('cancel');
}
}
28 changes: 20 additions & 8 deletions packages/extensions/js-runner-and-debugger/src/web/utils/wasi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import {
WasmProcess,
PseudoterminalState,
} from '@vscode/wasm-wasi';
import { logger } from './logger';
import { ansiColor } from './ansi-color';
import { CancelManager } from './cancel-manager';

export interface WasiEnv {
wasm: Wasm;
Expand Down Expand Up @@ -180,6 +182,8 @@ export async function runWasiCommand(
lifecycle.postCommandFn();
return;
}
// 取消管理器
const cancelManager = new CancelManager();

// Use coreutils as default command
let commandName = 'coreutils';
Expand Down Expand Up @@ -262,6 +266,10 @@ export async function runWasiCommand(

if (!wasiTerminal.state.isReadlineMode) {
wasiTerminal.state.isReadlineMode = true;
pty.onDidCloseTerminal(() => {
cancelManager.cancel();
wasiTerminal.terminal.dispose();
});
const orignalHandleInput = pty.handleInput;
pty.handleInput = function (data: string) {
if (
Expand All @@ -284,14 +292,18 @@ export async function runWasiCommand(
return orignalHandleInput?.apply(this, [data]);
};
let nextCommand: string = '';
while (true) {
nextCommand = await pty.readline();
if (nextCommand) {
await runWasiCommand(
context,
wasiTerminal,
nextCommand ? nextCommand.trim().split(' ') : []
);
while (!cancelManager.signal.cancelled) {
try {
nextCommand = await cancelManager.runCancellable(pty.readline());
if (nextCommand) {
await runWasiCommand(
context,
wasiTerminal,
nextCommand ? nextCommand.trim().split(' ') : []
);
}
} catch (error) {
logger.error('Terminal run command failed', error);
}
}
}
Expand Down

0 comments on commit ef904b5

Please # to comment.