Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

prevent debugpy from getting stuck #7612

Merged
merged 16 commits into from
Sep 24, 2021
91 changes: 50 additions & 41 deletions src/client/debugger/jupyter/debuggingManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import {
ProgressLocation,
DebugAdapterDescriptor,
Event,
EventEmitter
EventEmitter,
NotebookEditor
} from 'vscode';
import * as path from 'path';
import { IKernel, IKernelProvider } from '../../datascience/jupyter/kernels/types';
Expand Down Expand Up @@ -51,6 +52,7 @@ export class DebuggingManager implements IExtensionSingleActivationService, IDeb
private notebookToDebugger = new Map<NotebookDocument, Debugger>();
private notebookToDebugAdapter = new Map<NotebookDocument, KernelDebugAdapter>();
private notebookToRunByLineController = new Map<NotebookDocument, RunByLineController>();
private notebookInProgress = new Set<NotebookDocument>();
private cache = new Map<PythonEnvironment, boolean>();
private readonly disposables: IDisposable[] = [];
private _doneDebugging = new EventEmitter<void>();
Expand Down Expand Up @@ -94,19 +96,7 @@ export class DebuggingManager implements IExtensionSingleActivationService, IDeb

this.commandManager.registerCommand(DSCommands.DebugNotebook, async () => {
const editor = this.vscNotebook.activeNotebookEditor;
if (editor) {
if (this.notebookToDebugger.has(editor.document)) {
return;
}
if (await this.checkForIpykernel6(editor.document)) {
this.updateToolbar(true);
void this.startDebugging(editor.document);
} else {
void this.installIpykernel6();
}
} else {
void this.appShell.showErrorMessage(DataScience.noNotebookToDebug());
}
await this.tryToStartDebugging(KernelDebugMode.Everything, editor);
}),

this.commandManager.registerCommand(DSCommands.RunByLine, async (cell: NotebookCell | undefined) => {
Expand All @@ -123,20 +113,7 @@ export class DebuggingManager implements IExtensionSingleActivationService, IDeb
return;
}

if (editor) {
if (this.notebookToDebugger.has(editor.document)) {
return;
}
if (await this.checkForIpykernel6(editor.document, DataScience.startingRunByLine())) {
this.updateToolbar(true);
this.updateCellToolbar(true);
await this.startDebuggingCell(editor.document, KernelDebugMode.RunByLine, cell);
} else {
void this.installIpykernel6();
}
} else {
void this.appShell.showErrorMessage(DataScience.noNotebookToDebug());
}
await this.tryToStartDebugging(KernelDebugMode.RunByLine, editor, cell);
}),

this.commandManager.registerCommand(DSCommands.RunByLineNext, (cell: NotebookCell | undefined) => {
Expand Down Expand Up @@ -185,19 +162,7 @@ export class DebuggingManager implements IExtensionSingleActivationService, IDeb
return;
}

if (editor) {
if (this.notebookToDebugger.has(editor.document)) {
return;
}
if (await this.checkForIpykernel6(editor.document)) {
this.updateToolbar(true);
void this.startDebuggingCell(editor.document, KernelDebugMode.Cell, cell);
} else {
void this.installIpykernel6();
}
} else {
void this.appShell.showErrorMessage(DataScience.noNotebookToDebug());
}
await this.tryToStartDebugging(KernelDebugMode.Cell, editor, cell);
})
);
}
Expand Down Expand Up @@ -243,6 +208,50 @@ export class DebuggingManager implements IExtensionSingleActivationService, IDeb
this.runByLineInProgress.set(runningByLine).ignoreErrors();
}

private async tryToStartDebugging(mode: KernelDebugMode, editor?: NotebookEditor, cell?: NotebookCell) {
if (editor) {
if (this.notebookInProgress.has(editor.document)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is checking the case where debugging is starting, but doesn't it still need to check this.notebookToDebugger.has?

return;
}

try {
this.notebookInProgress.add(editor.document);
if (
await this.checkForIpykernel6(
editor.document,
mode === KernelDebugMode.RunByLine ? DataScience.startingRunByLine() : undefined
)
) {
switch (mode) {
case KernelDebugMode.Everything:
this.updateToolbar(true);
void this.startDebugging(editor.document);
break;
case KernelDebugMode.Cell:
if (cell) {
this.updateToolbar(true);
void this.startDebuggingCell(editor.document, KernelDebugMode.Cell, cell);
}
break;
case KernelDebugMode.RunByLine:
if (cell) {
this.updateToolbar(true);
this.updateCellToolbar(true);
await this.startDebuggingCell(editor.document, KernelDebugMode.RunByLine, cell);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in line 233 we're not awaiting, but here we're awaiting.
Confused why that's the case, comments would help.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'll be good to await them all

}
break;
}
} else {
void this.installIpykernel6();
}
} finally {
this.notebookInProgress.delete(editor.document);
}
} else {
void this.appShell.showErrorMessage(DataScience.noNotebookToDebug());
}
}

private async startDebuggingCell(
doc: NotebookDocument,
mode: KernelDebugMode.Cell | KernelDebugMode.RunByLine,
Expand Down