diff --git a/TELEMETRY.md b/TELEMETRY.md
index 3cdc29c70cee..317eb470bc15 100644
--- a/TELEMETRY.md
+++ b/TELEMETRY.md
@@ -147,7 +147,7 @@ No properties for event
## Locations Used
-[src/interactive-window/interactiveWindowCommandListener.ts#L357](https://github.com/microsoft/vscode-jupyter/tree/main/src/interactive-window/interactiveWindowCommandListener.ts#L357)
+[src/interactive-window/interactiveWindowCommandListener.ts#L358](https://github.com/microsoft/vscode-jupyter/tree/main/src/interactive-window/interactiveWindowCommandListener.ts#L358)
```typescript
}
}
@@ -178,7 +178,7 @@ No properties for event
## Locations Used
-[src/webviews/extension-side/dataviewer/dataViewer.node.ts#L326](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/dataviewer/dataViewer.node.ts#L326)
+[src/webviews/extension-side/dataviewer/dataViewer.node.ts#L322](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/dataviewer/dataViewer.node.ts#L322)
```typescript
private maybeSendSliceDataDimensionalityTelemetry(numberOfDimensions: number) {
@@ -210,7 +210,7 @@ No properties for event
## Locations Used
-[src/webviews/extension-side/dataviewer/dataViewer.node.ts#L208](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/dataviewer/dataViewer.node.ts#L208)
+[src/webviews/extension-side/dataviewer/dataViewer.node.ts#L204](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/dataviewer/dataViewer.node.ts#L204)
```typescript
break;
@@ -241,7 +241,7 @@ No properties for event
## Locations Used
-[src/webviews/extension-side/dataviewer/dataViewer.node.ts#L269](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/dataviewer/dataViewer.node.ts#L269)
+[src/webviews/extension-side/dataviewer/dataViewer.node.ts#L265](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/dataviewer/dataViewer.node.ts#L265)
```typescript
if (payload.shape?.length) {
this.maybeSendSliceDataDimensionalityTelemetry(payload.shape.length);
@@ -421,7 +421,7 @@ No properties for event
## Locations Used
-[src/platform/debugger/jupyter/notebook/debuggingManager.ts#L481](https://github.com/microsoft/vscode-jupyter/tree/main/src/platform/debugger/jupyter/notebook/debuggingManager.ts#L481)
+[src/kernels/debugger/debuggingManagerBase.ts#L198](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/debugger/debuggingManagerBase.ts#L198)
```typescript
);
@@ -449,7 +449,7 @@ No properties for event
## Locations Used
-[src/platform/debugger/jupyter/notebook/debuggingManager.ts#L161](https://github.com/microsoft/vscode-jupyter/tree/main/src/platform/debugger/jupyter/notebook/debuggingManager.ts#L161)
+[src/notebooks/debugger/debuggingManager.ts#L144](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/debugger/debuggingManager.ts#L144)
```typescript
}),
@@ -477,7 +477,7 @@ No properties for event
## Locations Used
-[src/platform/debugger/jupyter/notebook/debuggingManager.ts#L108](https://github.com/microsoft/vscode-jupyter/tree/main/src/platform/debugger/jupyter/notebook/debuggingManager.ts#L108)
+[src/notebooks/debugger/debuggingManager.ts#L91](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/debugger/debuggingManager.ts#L91)
```typescript
}),
@@ -505,7 +505,7 @@ No properties for event
## Locations Used
-[src/platform/debugger/jupyter/notebook/debuggingManager.ts#L486](https://github.com/microsoft/vscode-jupyter/tree/main/src/platform/debugger/jupyter/notebook/debuggingManager.ts#L486)
+[src/kernels/debugger/debuggingManagerBase.ts#L203](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/debugger/debuggingManagerBase.ts#L203)
```typescript
'https://github.com/microsoft/vscode-jupyter/wiki/Setting-Up-Run-by-Line-and-Debugging-for-Notebooks'
);
@@ -532,7 +532,7 @@ No description provided
## Locations Used
-[src/platform/debugger/jupyter/kernelDebugAdapter.ts#L94](https://github.com/microsoft/vscode-jupyter/tree/main/src/platform/debugger/jupyter/kernelDebugAdapter.ts#L94)
+[src/kernels/debugger/kernelDebugAdapterBase.ts#L104](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/debugger/kernelDebugAdapterBase.ts#L104)
```typescript
this.kernel.onDisposed(() => {
void debug.stopDebugging(this.session);
@@ -544,7 +544,7 @@ No description provided
```
-[src/platform/debugger/jupyter/kernelDebugAdapter.ts#L108](https://github.com/microsoft/vscode-jupyter/tree/main/src/platform/debugger/jupyter/kernelDebugAdapter.ts#L108)
+[src/kernels/debugger/kernelDebugAdapterBase.ts#L118](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/debugger/kernelDebugAdapterBase.ts#L118)
```typescript
cellStateChange.state === NotebookCellExecutionState.Idle &&
!this.disconnected
@@ -556,7 +556,7 @@ No description provided
```
-[src/platform/debugger/jupyter/notebook/debuggingManager.ts#L152](https://github.com/microsoft/vscode-jupyter/tree/main/src/platform/debugger/jupyter/notebook/debuggingManager.ts#L152)
+[src/notebooks/debugger/debuggingManager.ts#L135](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/debugger/debuggingManager.ts#L135)
```typescript
if (editor) {
const controller = this.notebookToRunByLineController.get(editor.notebook);
@@ -583,7 +583,7 @@ No description provided
## Locations Used
-[src/platform/debugger/jupyter/notebook/debuggingManager.ts#L463](https://github.com/microsoft/vscode-jupyter/tree/main/src/platform/debugger/jupyter/notebook/debuggingManager.ts#L463)
+[src/kernels/debugger/debuggingManagerBase.ts#L180](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/debugger/debuggingManagerBase.ts#L180)
```typescript
}
@@ -594,6 +594,27 @@ No description provided
return result;
```
+
+
+ DATASCIENCE.DEBUGGING.SUCCESSFULLY_STARTED_IW_JUPYTER
+
+## Description
+
+
+
+
+ Telemetry sent when we have managed to successfully start the Interactive Window debugger using the Jupyter protocol.
+
+## Properties
+
+
+No properties for event
+
+
+## Locations Used
+
+Event can be removed. Not referenced anywhere
+
DATASCIENCE.DEBUGGING.SUCCESSFULLY_STARTED_RUN_AND_DEBUG_CELL
@@ -611,7 +632,7 @@ No properties for event
## Locations Used
-[src/platform/debugger/jupyter/notebook/debugCellControllers.ts#L20](https://github.com/microsoft/vscode-jupyter/tree/main/src/platform/debugger/jupyter/notebook/debugCellControllers.ts#L20)
+[src/notebooks/debugger/debugCellControllers.ts#L20](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/debugger/debugCellControllers.ts#L20)
```typescript
private readonly kernel: IKernel,
private readonly commandManager: ICommandManager
@@ -622,6 +643,18 @@ No properties for event
public async willSendEvent(_msg: DebugProtocolMessage): Promise {
```
+
+[src/interactive-window/debugger/jupyter/debugCellControllers.ts#L23](https://github.com/microsoft/vscode-jupyter/tree/main/src/interactive-window/debugger/jupyter/debugCellControllers.ts#L23)
+```typescript
+ public readonly debugCell: NotebookCell,
+ private readonly kernel: IKernel
+ ) {
+ sendTelemetryEvent(DebuggingTelemetry.successfullyStartedRunAndDebugCell);
+ }
+
+ public async willSendEvent(_msg: DebugProtocolMessage): Promise {
+```
+
DATASCIENCE.DEBUGGING.SUCCESSFULLY_STARTED_RUNBYLINE
@@ -639,7 +672,7 @@ No properties for event
## Locations Used
-[src/platform/debugger/jupyter/notebook/runByLineController.ts#L29](https://github.com/microsoft/vscode-jupyter/tree/main/src/platform/debugger/jupyter/notebook/runByLineController.ts#L29)
+[src/notebooks/debugger/runByLineController.ts#L29](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/debugger/runByLineController.ts#L29)
```typescript
private readonly kernel: IKernel,
private readonly settings: IConfigurationService
@@ -916,7 +949,7 @@ No properties for event
```
-[src/notebooks/controllers/vscodeNotebookController.ts#L257](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/controllers/vscodeNotebookController.ts#L257)
+[src/notebooks/controllers/vscodeNotebookController.ts#L256](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/controllers/vscodeNotebookController.ts#L256)
```typescript
return;
}
@@ -928,7 +961,7 @@ No properties for event
```
-[src/kernels/kernel.base.ts#L191](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/kernel.base.ts#L191)
+[src/kernels/kernel.base.ts#L197](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/kernel.base.ts#L197)
```typescript
}
public async executeCell(cell: NotebookCell): Promise {
@@ -1050,7 +1083,7 @@ No description provided
```
-[src/platform/export/fileConverter.ts#L64](https://github.com/microsoft/vscode-jupyter/tree/main/src/platform/export/fileConverter.ts#L64)
+[src/platform/export/fileConverter.ts#L65](https://github.com/microsoft/vscode-jupyter/tree/main/src/platform/export/fileConverter.ts#L65)
```typescript
}
@@ -1102,7 +1135,7 @@ No description provided
## Locations Used
-[src/platform/export/fileConverter.ts#L84](https://github.com/microsoft/vscode-jupyter/tree/main/src/platform/export/fileConverter.ts#L84)
+[src/platform/export/fileConverter.ts#L85](https://github.com/microsoft/vscode-jupyter/tree/main/src/platform/export/fileConverter.ts#L85)
```typescript
await this.performExport(format, sourceDocument, target, token, candidateInterpreter);
} catch (e) {
@@ -1130,7 +1163,7 @@ No properties for event
## Locations Used
-[src/interactive-window/interactiveWindowCommandListener.ts#L198](https://github.com/microsoft/vscode-jupyter/tree/main/src/interactive-window/interactiveWindowCommandListener.ts#L198)
+[src/interactive-window/interactiveWindowCommandListener.ts#L199](https://github.com/microsoft/vscode-jupyter/tree/main/src/interactive-window/interactiveWindowCommandListener.ts#L199)
```typescript
return result;
}
@@ -1158,7 +1191,7 @@ No properties for event
## Locations Used
-[src/interactive-window/interactiveWindowCommandListener.ts#L247](https://github.com/microsoft/vscode-jupyter/tree/main/src/interactive-window/interactiveWindowCommandListener.ts#L247)
+[src/interactive-window/interactiveWindowCommandListener.ts#L248](https://github.com/microsoft/vscode-jupyter/tree/main/src/interactive-window/interactiveWindowCommandListener.ts#L248)
```typescript
}
}
@@ -1186,7 +1219,7 @@ No properties for event
## Locations Used
-[src/webviews/extension-side/variablesView/variableView.node.ts#L174](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/variablesView/variableView.node.ts#L174)
+[src/webviews/extension-side/variablesView/variableView.node.ts#L170](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/variablesView/variableView.node.ts#L170)
```typescript
}
} catch (e) {
@@ -1215,9 +1248,9 @@ No properties for event
## Locations Used
-[src/notebooks/controllers/notebookControllerManager.ts#L899](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/controllers/notebookControllerManager.ts#L899)
+[src/notebooks/controllers/notebookControllerManager.ts#L918](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/controllers/notebookControllerManager.ts#L918)
```typescript
- } catch (ex) {
+ }
// We know that this fails when we have xeus kernels installed (untill that's resolved thats one instance when we can have duplicates).
sendTelemetryEvent(
Telemetry.FailedToCreateNotebookController,
@@ -1266,7 +1299,7 @@ No properties for event
## Locations Used
-[src/kernels/kernelFinder.base.ts#L236](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/kernelFinder.base.ts#L236)
+[src/kernels/kernelFinder.base.ts#L242](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/kernelFinder.base.ts#L242)
```typescript
const key = `${kind}:${useCache}`;
if (this.startTimeForFetching && !this.fetchingTelemetrySent.has(key)) {
@@ -1294,10 +1327,10 @@ No properties for event
## Locations Used
-[src/kernels/jupyter/launcher/jupyterPasswordConnect.ts#L33](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/launcher/jupyterPasswordConnect.ts#L33)
+[src/kernels/jupyter/launcher/jupyterPasswordConnect.ts#L39](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/launcher/jupyterPasswordConnect.ts#L39)
```typescript
- @inject(IJupyterRequestCreator) private readonly requestCreator: IJupyterRequestCreator
- ) {}
+ this.serverUriStorage.onDidRemoveUris(this.onDidRemoveUris, this, this.disposables);
+ }
@captureTelemetry(Telemetry.GetPasswordAttempt)
public getPasswordConnectionInfo(url: string): Promise {
@@ -1395,7 +1428,7 @@ No description provided
## Locations Used
-[src/interactive-window/interactiveWindowCommandListener.ts#L372](https://github.com/microsoft/vscode-jupyter/tree/main/src/interactive-window/interactiveWindowCommandListener.ts#L372)
+[src/interactive-window/interactiveWindowCommandListener.ts#L373](https://github.com/microsoft/vscode-jupyter/tree/main/src/interactive-window/interactiveWindowCommandListener.ts#L373)
```typescript
return this.statusProvider.waitWithStatus(promise, message, undefined, canceled);
}
@@ -1407,7 +1440,7 @@ No description provided
```
-[src/interactive-window/interactiveWindowCommandListener.ts#L395](https://github.com/microsoft/vscode-jupyter/tree/main/src/interactive-window/interactiveWindowCommandListener.ts#L395)
+[src/interactive-window/interactiveWindowCommandListener.ts#L396](https://github.com/microsoft/vscode-jupyter/tree/main/src/interactive-window/interactiveWindowCommandListener.ts#L396)
```typescript
}
}
@@ -1436,7 +1469,7 @@ No description provided
## Locations Used
-[src/kernels/debugging/interactiveWindowDebugger.node.ts#L112](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/debugging/interactiveWindowDebugger.node.ts#L112)
+[src/interactive-window/debugger/interactiveWindowDebugger.node.ts#L111](https://github.com/microsoft/vscode-jupyter/tree/main/src/interactive-window/debugger/interactiveWindowDebugger.node.ts#L111)
```typescript
executeSilently(kernel.session, this.tracingEnableCode, {
traceErrors: true,
@@ -1448,7 +1481,7 @@ No description provided
```
-[src/kernels/debugging/interactiveWindowDebugger.node.ts#L123](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/debugging/interactiveWindowDebugger.node.ts#L123)
+[src/interactive-window/debugger/interactiveWindowDebugger.node.ts#L122](https://github.com/microsoft/vscode-jupyter/tree/main/src/interactive-window/debugger/interactiveWindowDebugger.node.ts#L122)
```typescript
executeSilently(kernel.session, this.tracingDisableCode, {
traceErrors: true,
@@ -1460,7 +1493,7 @@ No description provided
```
-[src/kernels/debugging/interactiveWindowDebugger.node.ts#L152](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/debugging/interactiveWindowDebugger.node.ts#L152)
+[src/interactive-window/debugger/interactiveWindowDebugger.node.ts#L151](https://github.com/microsoft/vscode-jupyter/tree/main/src/interactive-window/debugger/interactiveWindowDebugger.node.ts#L151)
```typescript
const importResults = await executeSilently(kernel.session, this.waitForDebugClientCode, {
traceErrors: true,
@@ -1472,7 +1505,7 @@ No description provided
```
-[src/kernels/debugging/interactiveWindowDebugger.node.ts#L275](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/debugging/interactiveWindowDebugger.node.ts#L275)
+[src/interactive-window/debugger/interactiveWindowDebugger.node.ts#L268](https://github.com/microsoft/vscode-jupyter/tree/main/src/interactive-window/debugger/interactiveWindowDebugger.node.ts#L268)
```typescript
{
traceErrors: true,
@@ -1484,7 +1517,7 @@ No description provided
```
-[src/kernels/debugging/interactiveWindowDebugger.node.ts#L304](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/debugging/interactiveWindowDebugger.node.ts#L304)
+[src/interactive-window/debugger/interactiveWindowDebugger.node.ts#L297](https://github.com/microsoft/vscode-jupyter/tree/main/src/interactive-window/debugger/interactiveWindowDebugger.node.ts#L297)
```typescript
? await executeSilently(kernel.session, this.enableDebuggerCode, {
traceErrors: true,
@@ -1512,7 +1545,7 @@ No properties for event
## Locations Used
-[src/notebooks/execution/kernelExecution.ts#L207](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/execution/kernelExecution.ts#L207)
+[src/notebooks/execution/kernelExecution.ts#L199](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/execution/kernelExecution.ts#L199)
```typescript
this.documentExecutions.set(document, newCellExecutionQueue);
return newCellExecutionQueue;
@@ -1856,7 +1889,7 @@ No description provided
## Locations Used
-[src/kernels/kernel.base.ts#L527](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/kernel.base.ts#L527)
+[src/kernels/kernel.base.ts#L545](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/kernel.base.ts#L545)
```typescript
await this.executeSilently(session, startupCode, {
traceErrors: true,
@@ -2656,7 +2689,7 @@ function resetData(resource: Resource, eventName: string, properties: any) {
```
-[src/notebooks/execution/kernelExecution.ts#L263](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/execution/kernelExecution.ts#L263)
+[src/notebooks/execution/kernelExecution.ts#L255](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/execution/kernelExecution.ts#L255)
```typescript
// Otherwise a real error occurred.
sendKernelTelemetryEvent(
@@ -2668,7 +2701,7 @@ function resetData(resource: Resource, eventName: string, properties: any) {
```
-[src/notebooks/execution/kernelExecution.ts#L275](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/execution/kernelExecution.ts#L275)
+[src/notebooks/execution/kernelExecution.ts#L267](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/execution/kernelExecution.ts#L267)
```typescript
})();
@@ -2765,7 +2798,7 @@ No properties for event
```
-[src/kernels/kernel.base.ts#L282](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/kernel.base.ts#L282)
+[src/kernels/kernel.base.ts#L291](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/kernel.base.ts#L291)
```typescript
await (this._jupyterSessionPromise
? this.kernelExecution.restart(this._jupyterSessionPromise)
@@ -2777,7 +2810,7 @@ No properties for event
```
-[src/kernels/kernel.base.ts#L293](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/kernel.base.ts#L293)
+[src/kernels/kernel.base.ts#L302](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/kernel.base.ts#L302)
```typescript
this.restarting = undefined;
// If we get a kernel promise failure, then restarting timed out. Just shutdown and restart the entire server.
@@ -3114,7 +3147,7 @@ No properties for event
## Locations Used
-[src/webviews/extension-side/dataviewer/dataViewer.node.ts#L204](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/dataviewer/dataViewer.node.ts#L204)
+[src/webviews/extension-side/dataviewer/dataViewer.node.ts#L200](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/dataviewer/dataViewer.node.ts#L200)
```typescript
case DataViewerMessages.RefreshDataViewer:
@@ -3307,7 +3340,7 @@ No properties for event
## Locations Used
-[src/kernels/variables/debuggerVariables.node.ts#L121](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/variables/debuggerVariables.node.ts#L121)
+[src/kernels/variables/debuggerVariables.node.ts#L120](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/variables/debuggerVariables.node.ts#L120)
```typescript
// Note, full variable results isn't necessary for this call. It only really needs the variable value.
const result = this.lastKnownVariables.find((v) => v.name === name);
@@ -4119,7 +4152,7 @@ No properties for event
```
-[src/platform/errors/errorHandler.ts#L302](https://github.com/microsoft/vscode-jupyter/tree/main/src/platform/errors/errorHandler.ts#L302)
+[src/platform/errors/errorHandler.ts#L301](https://github.com/microsoft/vscode-jupyter/tree/main/src/platform/errors/errorHandler.ts#L301)
```typescript
ConfigurationTarget.Workspace
);
@@ -4131,7 +4164,7 @@ No properties for event
```
-[src/kernels/jupyter/launcher/jupyterPasswordConnect.ts#L394](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/launcher/jupyterPasswordConnect.ts#L394)
+[src/kernels/jupyter/launcher/jupyterPasswordConnect.ts#L395](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/launcher/jupyterPasswordConnect.ts#L395)
```typescript
);
return this.requestCreator.getFetchMethod()(url, this.addAllowUnauthorized(url, true, options));
@@ -4183,7 +4216,7 @@ No properties for event
```
-[src/platform/errors/errorHandler.ts#L294](https://github.com/microsoft/vscode-jupyter/tree/main/src/platform/errors/errorHandler.ts#L294)
+[src/platform/errors/errorHandler.ts#L293](https://github.com/microsoft/vscode-jupyter/tree/main/src/platform/errors/errorHandler.ts#L293)
```typescript
.showErrorMessage(DataScience.jupyterSelfCertFail().format(err.message), enableOption, closeOption)
.then((value) => {
@@ -4195,7 +4228,7 @@ No properties for event
```
-[src/kernels/jupyter/launcher/jupyterPasswordConnect.ts#L385](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/launcher/jupyterPasswordConnect.ts#L385)
+[src/kernels/jupyter/launcher/jupyterPasswordConnect.ts#L386](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/launcher/jupyterPasswordConnect.ts#L386)
```typescript
closeOption
);
@@ -4307,7 +4340,7 @@ No description provided
## Locations Used
-[src/webviews/extension-side/dataviewer/dataViewer.node.ts#L237](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/dataviewer/dataViewer.node.ts#L237)
+[src/webviews/extension-side/dataviewer/dataViewer.node.ts#L233](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/dataviewer/dataViewer.node.ts#L233)
```typescript
// Log telemetry about number of rows
@@ -4319,7 +4352,7 @@ No description provided
```
-[src/webviews/extension-side/dataviewer/dataViewer.node.ts#L320](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/dataviewer/dataViewer.node.ts#L320)
+[src/webviews/extension-side/dataviewer/dataViewer.node.ts#L316](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/dataviewer/dataViewer.node.ts#L316)
```typescript
private sendElapsedTimeTelemetry() {
@@ -4574,7 +4607,7 @@ No description provided
## Locations Used
-[src/kernels/kernel.base.ts#L534](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/kernel.base.ts#L534)
+[src/kernels/kernel.base.ts#L552](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/kernel.base.ts#L552)
```typescript
await this.executeSilently(session, this.getUserStartupCommands(), {
traceErrors: true,
@@ -5205,7 +5238,7 @@ No properties for event
## Locations Used
-[src/notebooks/execution/cellExecution.ts#L463](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/execution/cellExecution.ts#L463)
+[src/notebooks/execution/cellExecution.ts#L449](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/execution/cellExecution.ts#L449)
```typescript
const props = { notebook: true };
if (!CellExecution.sentExecuteCellTelemetry) {
@@ -5248,7 +5281,7 @@ No properties for event
## Locations Used
-[src/notebooks/execution/cellExecution.ts#L465](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/execution/cellExecution.ts#L465)
+[src/notebooks/execution/cellExecution.ts#L451](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/execution/cellExecution.ts#L451)
```typescript
CellExecution.sentExecuteCellTelemetry = true;
sendTelemetryEvent(Telemetry.ExecuteCellPerceivedCold, this.stopWatchForTelemetry.elapsedTime, props);
@@ -5300,7 +5333,7 @@ No properties for event
## Locations Used
-[src/kernels/jupyter/jupyterKernelService.node.ts#L216](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/jupyterKernelService.node.ts#L216)
+[src/kernels/jupyter/jupyterKernelService.node.ts#L217](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/jupyterKernelService.node.ts#L217)
```typescript
await this.fs.writeLocalFile(kernelSpecFilePath.fsPath, JSON.stringify(contents, undefined, 4));
} catch (ex) {
@@ -5312,7 +5345,7 @@ No properties for event
```
-[src/kernels/jupyter/jupyterKernelService.node.ts#L356](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/jupyterKernelService.node.ts#L356)
+[src/kernels/jupyter/jupyterKernelService.node.ts#L349](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/jupyterKernelService.node.ts#L349)
```typescript
await this.fs.writeLocalFile(kernelSpecFilePath, JSON.stringify(specModel, undefined, 2));
} catch (ex) {
@@ -5506,7 +5539,7 @@ No properties for event
## Locations Used
-[src/kernels/jupyter/launcher/jupyterPasswordConnect.ts#L258](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/launcher/jupyterPasswordConnect.ts#L258)
+[src/kernels/jupyter/launcher/jupyterPasswordConnect.ts#L259](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/launcher/jupyterPasswordConnect.ts#L259)
```typescript
const requestHeaders = { Cookie: cookieString, 'X-XSRFToken': xsrfCookie };
return { requestHeaders };
@@ -5534,7 +5567,7 @@ No properties for event
## Locations Used
-[src/kernels/jupyter/launcher/jupyterPasswordConnect.ts#L253](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/launcher/jupyterPasswordConnect.ts#L253)
+[src/kernels/jupyter/launcher/jupyterPasswordConnect.ts#L254](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/launcher/jupyterPasswordConnect.ts#L254)
```typescript
// If we found everything return it all back if not, undefined as partial is useless
@@ -5766,7 +5799,7 @@ No properties for event
## Locations Used
-[src/notebooks/execution/kernelExecution.ts#L208](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/execution/kernelExecution.ts#L208)
+[src/notebooks/execution/kernelExecution.ts#L200](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/execution/kernelExecution.ts#L200)
```typescript
return newCellExecutionQueue;
}
@@ -6378,7 +6411,7 @@ No properties for event
## Locations Used
-[src/kernels/jupyter/jupyterKernelService.node.ts#L159](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/jupyterKernelService.node.ts#L159)
+[src/kernels/jupyter/jupyterKernelService.node.ts#L160](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/jupyterKernelService.node.ts#L160)
```typescript
*/
// eslint-disable-next-line
@@ -6512,7 +6545,7 @@ No properties for event
## Locations Used
-[src/kernels/raw/launcher/kernelLauncher.node.ts#L116](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/launcher/kernelLauncher.node.ts#L116)
+[src/kernels/raw/launcher/kernelLauncher.node.ts#L117](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/launcher/kernelLauncher.node.ts#L117)
```typescript
// Should be available now, wait with a timeout
return await this.launchProcess(kernelConnectionMetadata, resource, workingDirectory, timeout, cancelToken);
@@ -6737,14 +6770,14 @@ No properties for event
## Locations Used
-[src/webviews/extension-side/variablesView/variableView.node.ts#L84](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/variablesView/variableView.node.ts#L84)
+[src/webviews/extension-side/variablesView/variableView.node.ts#L80](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/variablesView/variableView.node.ts#L80)
```typescript
console.log(`Done initing variables`);
}
@captureTelemetry(Telemetry.NativeVariableViewLoaded)
public async load(codeWebview: vscodeWebviewView) {
- await super.loadWebview(process.cwd(), codeWebview).catch(traceError);
+ await super.loadWebview(Uri.file(process.cwd()), codeWebview).catch(traceError);
```
@@ -6765,7 +6798,7 @@ No properties for event
## Locations Used
-[src/webviews/extension-side/variablesView/variableView.node.ts#L143](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/variablesView/variableView.node.ts#L143)
+[src/webviews/extension-side/variablesView/variableView.node.ts#L139](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/variablesView/variableView.node.ts#L139)
```typescript
// I've we've been made visible, make sure that we are updated
@@ -6939,7 +6972,7 @@ No properties for event
## Locations Used
-[src/kernels/kernel.base.ts#L323](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/kernel.base.ts#L323)
+[src/kernels/kernel.base.ts#L332](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/kernel.base.ts#L332)
```typescript
// Setup telemetry
if (!this.perceivedJupyterStartupTelemetryCaptured) {
@@ -6951,7 +6984,7 @@ No properties for event
```
-[src/kernels/kernel.base.ts#L406](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/kernel.base.ts#L406)
+[src/kernels/kernel.base.ts#L424](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/kernel.base.ts#L424)
```typescript
sendKernelTelemetryEvent(
@@ -6981,7 +7014,7 @@ No properties for event
## Locations Used
-[src/notebooks/controllers/notebookControllerManager.ts#L768](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/controllers/notebookControllerManager.ts#L768)
+[src/notebooks/controllers/notebookControllerManager.ts#L774](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/controllers/notebookControllerManager.ts#L774)
```typescript
? PYTHON_LANGUAGE
: getTelemetrySafeLanguage(getLanguageInNotebookMetadata(notebookMetadata) || '');
@@ -7008,7 +7041,7 @@ No description provided
## Locations Used
-[src/notebooks/controllers/notebookControllerManager.ts#L748](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/controllers/notebookControllerManager.ts#L748)
+[src/notebooks/controllers/notebookControllerManager.ts#L754](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/controllers/notebookControllerManager.ts#L754)
```typescript
onlyConnection && (matchReason |= PreferredKernelExactMatchReason.OnlyKernel);
topMatchIsPreferredInterpreter && (matchReason |= PreferredKernelExactMatchReason.WasPreferredInterpreter);
@@ -7479,7 +7512,7 @@ No properties for event
## Locations Used
-[src/kernels/raw/session/rawJupyterSession.node.ts#L347](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L347)
+[src/kernels/raw/session/rawJupyterSession.node.ts#L350](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L350)
```typescript
} else {
traceWarning(`Didn't get response for requestKernelInfo after ${stopWatch.elapsedTime}ms.`);
@@ -7507,7 +7540,7 @@ No properties for event
## Locations Used
-[src/kernels/raw/launcher/kernelProcess.node.ts#L131](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/launcher/kernelProcess.node.ts#L131)
+[src/kernels/raw/launcher/kernelProcess.node.ts#L135](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/launcher/kernelProcess.node.ts#L135)
```typescript
}
}
@@ -7536,7 +7569,7 @@ No properties for event
## Locations Used
-[src/kernels/raw/session/rawJupyterSession.node.ts#L140](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L140)
+[src/kernels/raw/session/rawJupyterSession.node.ts#L142](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L142)
```typescript
throw error;
}
@@ -7597,7 +7630,7 @@ No properties for event
## Locations Used
-[src/kernels/raw/launcher/kernelLauncher.node.ts#L219](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/launcher/kernelLauncher.node.ts#L219)
+[src/kernels/raw/launcher/kernelLauncher.node.ts#L224](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/launcher/kernelLauncher.node.ts#L224)
```typescript
const disposable = kernelProcess.exited(
@@ -7621,7 +7654,7 @@ No properties for event
```
-[src/kernels/raw/session/rawJupyterSession.node.ts#L184](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L184)
+[src/kernels/raw/session/rawJupyterSession.node.ts#L186](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L186)
```typescript
if (session !== this.session) {
return;
@@ -7649,7 +7682,7 @@ No properties for event
## Locations Used
-[src/kernels/kernelConnector.ts#L143](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/kernelConnector.ts#L143)
+[src/kernels/kernelConnector.ts#L144](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/kernelConnector.ts#L144)
```typescript
const rawNotebookProvider = serviceContainer.tryGet(IRawNotebookProvider);
const rawLocalKernel = rawNotebookProvider?.isSupported && isLocal;
@@ -7680,7 +7713,7 @@ No properties for event
## Locations Used
-[src/kernels/raw/session/rawJupyterSession.node.ts#L158](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L158)
+[src/kernels/raw/session/rawJupyterSession.node.ts#L160](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L160)
```typescript
// We want to know why we got shut down
const stacktrace = new Error().stack;
@@ -7709,7 +7742,7 @@ No properties for event
## Locations Used
-[src/kernels/raw/session/rawJupyterSession.node.ts#L83](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L83)
+[src/kernels/raw/session/rawJupyterSession.node.ts#L85](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L85)
```typescript
Cancellation.throwIfCanceled(options.token);
// Only connect our session if we didn't cancel or timeout
@@ -7721,9 +7754,9 @@ No properties for event
```
-[src/kernels/raw/session/rawJupyterSession.node.ts#L98](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L98)
+[src/kernels/raw/session/rawJupyterSession.node.ts#L100](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L100)
```typescript
- if (error instanceof CancellationError) {
+ if (isCancellationError(error) || options.token.isCancellationRequested) {
sendKernelTelemetryEvent(
this.resource,
Telemetry.RawKernelSessionStart,
@@ -7733,7 +7766,7 @@ No properties for event
```
-[src/kernels/raw/session/rawJupyterSession.node.ts#L109](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L109)
+[src/kernels/raw/session/rawJupyterSession.node.ts#L111](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L111)
```typescript
} else if (error instanceof TimedOutError) {
sendKernelTelemetryEvent(
@@ -7745,7 +7778,7 @@ No properties for event
```
-[src/kernels/raw/session/rawJupyterSession.node.ts#L121](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L121)
+[src/kernels/raw/session/rawJupyterSession.node.ts#L123](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L123)
```typescript
// Send our telemetry event with the error included
sendKernelTelemetryEvent(
@@ -7773,7 +7806,7 @@ No properties for event
## Locations Used
-[src/kernels/raw/session/rawJupyterSession.node.ts#L129](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L129)
+[src/kernels/raw/session/rawJupyterSession.node.ts#L131](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L131)
```typescript
);
sendKernelTelemetryEvent(
@@ -7801,7 +7834,7 @@ No properties for event
## Locations Used
-[src/kernels/raw/session/rawJupyterSession.node.ts#L82](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L82)
+[src/kernels/raw/session/rawJupyterSession.node.ts#L84](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L84)
```typescript
newSession = await this.startRawSession(options);
Cancellation.throwIfCanceled(options.token);
@@ -7829,7 +7862,7 @@ No properties for event
## Locations Used
-[src/kernels/raw/session/rawJupyterSession.node.ts#L114](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L114)
+[src/kernels/raw/session/rawJupyterSession.node.ts#L116](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L116)
```typescript
undefined,
error
@@ -7857,13 +7890,13 @@ No properties for event
## Locations Used
-[src/kernels/raw/session/rawJupyterSession.node.ts#L103](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L103)
+[src/kernels/raw/session/rawJupyterSession.node.ts#L105](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L105)
```typescript
undefined,
error
);
sendKernelTelemetryEvent(this.resource, Telemetry.RawKernelSessionStartUserCancel);
- traceInfo('Starting of raw session cancelled by user');
+ traceVerbose('Starting of raw session cancelled by user');
throw error;
} else if (error instanceof TimedOutError) {
```
@@ -7885,7 +7918,7 @@ No properties for event
## Locations Used
-[src/kernels/raw/session/rawJupyterSession.node.ts#L235](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L235)
+[src/kernels/raw/session/rawJupyterSession.node.ts#L238](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/raw/session/rawJupyterSession.node.ts#L238)
```typescript
return this.startRawSession({ token: cancelToken, ui: new DisplayOptions(disableUI) });
}
@@ -7913,7 +7946,7 @@ No properties for event
## Locations Used
-[src/kernels/jupyter/jupyterKernelService.node.ts#L238](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/jupyterKernelService.node.ts#L238)
+[src/kernels/jupyter/jupyterKernelService.node.ts#L239](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/jupyterKernelService.node.ts#L239)
```typescript
);
}
@@ -7962,7 +7995,7 @@ No properties for event
## Locations Used
-[src/notebooks/execution/kernelExecution.ts#L283](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/execution/kernelExecution.ts#L283)
+[src/notebooks/execution/kernelExecution.ts#L275](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/execution/kernelExecution.ts#L275)
```typescript
}
@@ -7990,7 +8023,7 @@ No properties for event
## Locations Used
-[src/notebooks/execution/kernelExecution.ts#L282](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/execution/kernelExecution.ts#L282)
+[src/notebooks/execution/kernelExecution.ts#L274](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/execution/kernelExecution.ts#L274)
```typescript
});
}
@@ -8278,7 +8311,7 @@ No properties for event
## Locations Used
-[src/kernels/kernel.base.ts#L325](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/kernel.base.ts#L325)
+[src/kernels/kernel.base.ts#L334](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/kernel.base.ts#L334)
```typescript
this.perceivedJupyterStartupTelemetryCaptured = true;
sendTelemetryEvent(Telemetry.PerceivedJupyterStartupNotebook, stopWatch.elapsedTime);
@@ -8306,7 +8339,7 @@ No properties for event
## Locations Used
-[src/kernels/jupyter/launcher/notebookStarter.node.ts#L152](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/launcher/notebookStarter.node.ts#L152)
+[src/kernels/jupyter/launcher/notebookStarter.node.ts#L156](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/launcher/notebookStarter.node.ts#L156)
```typescript
}
@@ -8359,7 +8392,7 @@ No properties for event
## Locations Used
-[src/kernels/common/baseJupyterSession.ts#L69](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/common/baseJupyterSession.ts#L69)
+[src/kernels/common/baseJupyterSession.ts#L70](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/common/baseJupyterSession.ts#L70)
```typescript
export class JupyterSessionStartError extends WrappedError {
constructor(originalException: Error) {
@@ -8611,7 +8644,7 @@ No description provided
## Locations Used
-[src/webviews/extension-side/variablesView/variableView.node.ts#L187](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/variablesView/variableView.node.ts#L187)
+[src/webviews/extension-side/variablesView/variableView.node.ts#L183](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/variablesView/variableView.node.ts#L183)
```typescript
const response = await this.variables.getVariables(args, activeNotebook);
@@ -8638,7 +8671,7 @@ No description provided
## Locations Used
-[src/notebooks/helpers.ts#L749](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/helpers.ts#L749)
+[src/notebooks/helpers.ts#L671](https://github.com/microsoft/vscode-jupyter/tree/main/src/notebooks/helpers.ts#L671)
```typescript
// Unless we already know its an unknown output type.
const outputType: nbformat.OutputType =
@@ -8666,7 +8699,7 @@ No properties for event
## Locations Used
-[src/kernels/jupyter/session/jupyterSession.ts#L74](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/session/jupyterSession.ts#L74)
+[src/kernels/jupyter/session/jupyterSession.ts#L67](https://github.com/microsoft/vscode-jupyter/tree/main/src/kernels/jupyter/session/jupyterSession.ts#L67)
```typescript
return true;
}
@@ -8722,7 +8755,7 @@ No description provided
## Locations Used
-[src/webviews/extension-side/webviewHost.node.ts#L281](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/webviewHost.node.ts#L281)
+[src/webviews/extension-side/webviewHost.ts#L279](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/webviewHost.ts#L279)
```typescript
protected webViewRendered() {
if (this.webviewInit && !this.webviewInit.resolved) {
@@ -8750,15 +8783,15 @@ No properties for event
## Locations Used
-[src/webviews/extension-side/webviewHost.node.ts#L299](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/webviewHost.node.ts#L299)
+[src/webviews/extension-side/webviewHost.ts#L297](https://github.com/microsoft/vscode-jupyter/tree/main/src/webviews/extension-side/webviewHost.ts#L297)
```typescript
this.dispose();
};
@captureTelemetry(Telemetry.WebviewStyleUpdate)
- private async handleCssRequest(request: IGetCssRequest): Promise {
- const settings = await this.generateDataScienceExtraSettings();
- const requestIsDark = settings.ignoreVscodeTheme ? false : request?.isDark;
+ private async handleCssRequest(): Promise {
+ const isDark = await this.isDark();
+ return this.postMessageInternal(CssMessages.GetCssResponse, {
```
diff --git a/src/kernels/common/baseJupyterSession.ts b/src/kernels/common/baseJupyterSession.ts
index 881c210ec715..172ccf3b343c 100644
--- a/src/kernels/common/baseJupyterSession.ts
+++ b/src/kernels/common/baseJupyterSession.ts
@@ -31,6 +31,7 @@ import { ChainingExecuteRequester } from './chainingExecuteRequester';
import { getResourceType } from '../../platform/common/utils';
import { KernelProgressReporter } from '../../platform/progress/kernelProgressReporter';
import { isTestExecution } from '../../platform/common/constants';
+import { KernelConnectionWrapper } from './kernelConnectionWrapper';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function suppressShutdownErrors(realKernel: any) {
@@ -71,6 +72,13 @@ export class JupyterSessionStartError extends WrappedError {
}
export abstract class BaseJupyterSession implements IJupyterSession {
+ /**
+ * Keep a single instance of KernelConnectionWrapper.
+ * This way when sessions change, we still have a single Kernel.IKernelConnection proxy (wrapper),
+ * which will have all of the event handlers bound to it.
+ * This allows consumers to add event handlers hand not worry about internals & can use the lower level Jupyter API.
+ */
+ private _wrappedKernel?: KernelConnectionWrapper;
private _isDisposed?: boolean;
private readonly _disposed = new EventEmitter();
protected readonly disposables: IDisposable[] = [];
@@ -83,28 +91,30 @@ export abstract class BaseJupyterSession implements IJupyterSession {
protected get session(): ISessionWithSocket | undefined {
return this._session;
}
+ public get kernelId(): string {
+ return this.session?.kernel?.id || '';
+ }
public get kernel(): Kernel.IKernelConnection | undefined {
- return this._session?.kernel || undefined;
+ if (this._wrappedKernel) {
+ return this._wrappedKernel;
+ }
+ if (!this._session?.kernel) {
+ return;
+ }
+ this._wrappedKernel = new KernelConnectionWrapper(this._session.kernel, this.disposables);
+ return this._wrappedKernel;
}
+
public get kernelSocket(): Observable {
return this._kernelSocket;
}
public get onSessionStatusChanged(): Event {
return this.onStatusChangedEvent.event;
}
- public get onIOPubMessage(): Event {
- if (!this.ioPubEventEmitter) {
- this.ioPubEventEmitter = new EventEmitter();
- }
- return this.ioPubEventEmitter.event;
- }
-
public get status(): KernelMessage.Status {
return this.getServerStatus();
}
- public abstract get kernelId(): string;
-
public get isConnected(): boolean {
return this.connected;
}
@@ -115,8 +125,6 @@ export abstract class BaseJupyterSession implements IJupyterSession {
protected restartSessionPromise?: { token: CancellationTokenSource; promise: Promise };
private _session: ISessionWithSocket | undefined;
private _kernelSocket = new ReplaySubject();
- private ioPubEventEmitter = new EventEmitter();
- private ioPubHandler: Slot;
private unhandledMessageHandler: Slot;
private chainingExecute = new ChainingExecuteRequester();
@@ -128,7 +136,6 @@ export abstract class BaseJupyterSession implements IJupyterSession {
private readonly interruptTimeout: number
) {
this.statusHandler = this.onStatusChanged.bind(this);
- this.ioPubHandler = (_s, m) => this.ioPubEventEmitter.fire(m);
this.unhandledMessageHandler = (_s, m) => {
traceInfo(`Unhandled message found: ${m.header.msg_type}`);
};
@@ -346,9 +353,6 @@ export abstract class BaseJupyterSession implements IJupyterSession {
protected setSession(session: ISessionWithSocket | undefined, forceUpdateKernelSocketInfo: boolean = false) {
const oldSession = this._session;
if (oldSession) {
- if (this.ioPubHandler) {
- oldSession.iopubMessage.disconnect(this.ioPubHandler);
- }
if (this.unhandledMessageHandler) {
oldSession.unhandledMessage.disconnect(this.unhandledMessageHandler);
}
@@ -358,12 +362,12 @@ export abstract class BaseJupyterSession implements IJupyterSession {
}
this._session = session;
if (session) {
+ if (session.kernel && this._wrappedKernel) {
+ this._wrappedKernel.changeKernel(session.kernel);
+ }
+
// Listen for session status changes
session.statusChanged.connect(this.statusHandler);
-
- if (session.iopubMessage) {
- session.iopubMessage.connect(this.ioPubHandler);
- }
if (session.unhandledMessage) {
session.unhandledMessage.connect(this.unhandledMessageHandler);
}
diff --git a/src/kernels/common/kernelConnectionWrapper.ts b/src/kernels/common/kernelConnectionWrapper.ts
new file mode 100644
index 000000000000..df0b9730a439
--- /dev/null
+++ b/src/kernels/common/kernelConnectionWrapper.ts
@@ -0,0 +1,73 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import type { Kernel } from '@jupyterlab/services';
+import { IDisposable } from '../../platform/common/types';
+import { BaseKernelConnectionWrapper } from '../jupyter/baseKernelConnectionWrapper';
+
+export class KernelConnectionWrapper extends BaseKernelConnectionWrapper {
+ /**
+ * Use `kernelConnection` to access the value as its not a constant (can change over time).
+ * E.g. when restarting kernels or the like.
+ */
+ private _kernelConnection!: Kernel.IKernelConnection;
+ protected get possibleKernelConnection(): undefined | Kernel.IKernelConnection {
+ return this._kernelConnection;
+ }
+ public get kernel() {
+ return this._kernelConnection;
+ }
+
+ constructor(kernel: Kernel.IKernelConnection, disposables: IDisposable[]) {
+ super(kernel, disposables);
+ this._kernelConnection = kernel;
+ }
+ public changeKernel(kernel: Kernel.IKernelConnection) {
+ if (this.kernel === kernel) {
+ return;
+ }
+ this.stopHandlingKernelMessages(this.possibleKernelConnection!);
+ this._kernelConnection = kernel;
+ this.startHandleKernelMessages(kernel);
+ }
+ async shutdown(): Promise {
+ await this._kernelConnection.shutdown();
+ }
+ dispose(): void {
+ this._kernelConnection.dispose();
+ }
+ async interrupt(): Promise {
+ await this._kernelConnection.interrupt();
+ }
+ async restart(): Promise {
+ await this._kernelConnection.restart();
+ }
+ protected override startHandleKernelMessages(kernelConnection: Kernel.IKernelConnection) {
+ super.startHandleKernelMessages(kernelConnection);
+ this._kernelConnection = kernelConnection;
+ kernelConnection.connectionStatusChanged.connect(this.onConnectionStatusChanged, this);
+ kernelConnection.statusChanged.connect(this.onStatusChanged, this);
+ kernelConnection.disposed.connect(this.onDisposed, this);
+ }
+ protected override stopHandlingKernelMessages(kernelConnection: Kernel.IKernelConnection): void {
+ super.stopHandlingKernelMessages(kernelConnection);
+ kernelConnection.connectionStatusChanged.disconnect(this.onConnectionStatusChanged, this);
+ kernelConnection.statusChanged.disconnect(this.onStatusChanged, this);
+ kernelConnection.disposed.disconnect(this.onDisposed, this);
+ }
+ private onDisposed(connection: Kernel.IKernelConnection) {
+ if (connection === this.possibleKernelConnection) {
+ this.disposed.emit();
+ }
+ }
+ private onStatusChanged(connection: Kernel.IKernelConnection, args: Kernel.Status) {
+ if (connection === this.possibleKernelConnection) {
+ this.statusChanged.emit(args);
+ }
+ }
+ private onConnectionStatusChanged(connection: Kernel.IKernelConnection, args: Kernel.ConnectionStatus) {
+ if (connection === this.possibleKernelConnection) {
+ this.connectionStatusChanged.emit(args);
+ }
+ }
+}
diff --git a/src/kernels/debugger/kernelDebugAdapterBase.ts b/src/kernels/debugger/kernelDebugAdapterBase.ts
index d2a616a8e26b..e07cb305dda8 100644
--- a/src/kernels/debugger/kernelDebugAdapterBase.ts
+++ b/src/kernels/debugger/kernelDebugAdapterBase.ts
@@ -10,6 +10,7 @@ import {
DebugAdapter,
DebugProtocolMessage,
DebugSession,
+ Disposable,
Event,
EventEmitter,
NotebookCell,
@@ -33,7 +34,6 @@ import {
IDebugInfoResponse
} from './types';
import { sendTelemetryEvent } from '../../telemetry';
-import { IDisposable } from '../../platform/common/types';
import { traceError, traceInfo, traceInfoIfCI, traceVerbose } from '../../platform/logging';
import {
assertIsDebugConfig,
@@ -42,6 +42,7 @@ import {
getMessageSourceAndHookIt
} from '../../notebooks/debugger/helper';
import { ResourceMap } from '../../platform/vscode-path/map';
+import { IDisposable } from '../../platform/common/types';
/**
* For info on the custom requests implemented by jupyter see:
@@ -89,18 +90,9 @@ export abstract class KernelDebugAdapterBase implements DebugAdapter, IKernelDeb
this.debugCell = notebookDocument.cellAt(configuration.__cellIndex!);
}
+ this.jupyterSession.kernel?.iopubMessage.connect(this.onIOPubMessage, this);
this.disposables.push(
- this.jupyterSession.onIOPubMessage(async (msg: KernelMessage.IIOPubMessage) => {
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- const anyMsg = msg as any;
- traceInfoIfCI(`Debug IO Pub message: ${JSON.stringify(msg)}`);
- if (anyMsg.header.msg_type === 'debug_event') {
- this.trace('event', JSON.stringify(msg));
- if (!(await this.delegate?.willSendEvent(anyMsg))) {
- this.sendMessage.fire(msg.content);
- }
- }
- })
+ new Disposable(() => this.jupyterSession.kernel?.iopubMessage.disconnect(this.onIOPubMessage, this))
);
if (this.kernel) {
@@ -157,6 +149,17 @@ export abstract class KernelDebugAdapterBase implements DebugAdapter, IKernelDeb
traceVerbose(`[Debug] ${tag}: ${msg}`);
}
+ async onIOPubMessage(_: unknown, msg: KernelMessage.IIOPubMessage) {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const anyMsg = msg as any;
+ traceInfoIfCI(`Debug IO Pub message: ${JSON.stringify(msg)}`);
+ if (anyMsg.header.msg_type === 'debug_event') {
+ this.trace('event', JSON.stringify(msg));
+ if (!(await this.delegate?.willSendEvent(anyMsg))) {
+ this.sendMessage.fire(msg.content);
+ }
+ }
+ }
async handleMessage(message: DebugProtocol.ProtocolMessage) {
try {
traceInfoIfCI(`KernelDebugAdapter::handleMessage ${JSON.stringify(message, undefined, ' ')}`);
diff --git a/src/kernels/kernelConnectionWrapper.ts b/src/kernels/jupyter/baseKernelConnectionWrapper.ts
similarity index 72%
rename from src/kernels/kernelConnectionWrapper.ts
rename to src/kernels/jupyter/baseKernelConnectionWrapper.ts
index 8c5c0a766c48..6a828ed19e28 100644
--- a/src/kernels/kernelConnectionWrapper.ts
+++ b/src/kernels/jupyter/baseKernelConnectionWrapper.ts
@@ -34,11 +34,9 @@ import { ISpecModel } from '@jupyterlab/services/lib/kernelspec/restapi';
import { JSONObject } from '@lumino/coreutils';
import { Signal } from '@lumino/signaling';
import { Disposable } from 'vscode';
-import { IDisposable } from '../platform/common/types';
-import { noop } from '../platform/common/utils/misc';
-import { IKernel } from './types';
+import { IDisposable } from '../../platform/common/types';
-export class KernelConnectionWrapper implements Kernel.IKernelConnection {
+export abstract class BaseKernelConnectionWrapper implements Kernel.IKernelConnection {
public readonly statusChanged = new Signal(this);
public readonly connectionStatusChanged = new Signal(this);
public readonly iopubMessage = new Signal>(this);
@@ -48,23 +46,8 @@ export class KernelConnectionWrapper implements Kernel.IKernelConnection {
return (this.possibleKernelConnection || this._previousKernelConnection).serverSettings;
}
public readonly disposed = new Signal(this);
- /**
- * Use `kernelConnection` to access the value as its not a constant (can change over time).
- * E.g. when restarting kernels or the like.
- */
- private _kernelConnection!: Kernel.IKernelConnection;
- private readonly _previousKernelConnection: Kernel.IKernelConnection;
// private _isRestarting?: boolean;
- private get possibleKernelConnection(): undefined | Kernel.IKernelConnection {
- if (this.kernel.session?.kernel === this._kernelConnection) {
- return this._kernelConnection;
- }
- this.stopHandlingKernelMessages(this._kernelConnection);
- if (this.kernel.session?.kernel) {
- this.startHandleKernelMessages(this.kernel.session.kernel);
- return this._kernelConnection;
- }
- }
+ protected abstract get possibleKernelConnection(): undefined | Kernel.IKernelConnection;
private getKernelConnection(): Kernel.IKernelConnection {
if (!this.possibleKernelConnection) {
throw new Error(
@@ -74,27 +57,8 @@ export class KernelConnectionWrapper implements Kernel.IKernelConnection {
return this.possibleKernelConnection;
}
- constructor(readonly kernel: IKernel, disposables: IDisposable[]) {
- const emiStatusChangeEvents = () => {
- this.statusChanged.emit(kernel.status);
- if (kernel.status === 'dead' && !kernel.disposed && !kernel.disposing) {
- this.connectionStatusChanged.emit('disconnected');
- }
- };
- kernel.onDisposed(
- () => {
- // this._isRestarting = false;
- emiStatusChangeEvents();
- this.disposed.emit();
- },
- this,
- disposables
- );
- kernel.onStarted(emiStatusChangeEvents, this, disposables);
- kernel.onRestarted(emiStatusChangeEvents, this, disposables);
- kernel.onStatusChanged(emiStatusChangeEvents, this, disposables);
- this._previousKernelConnection = kernel.session!.kernel!;
- this.startHandleKernelMessages(kernel.session!.kernel!);
+ constructor(private _previousKernelConnection: Kernel.IKernelConnection, disposables: IDisposable[]) {
+ this.startHandleKernelMessages(_previousKernelConnection);
disposables.push(
new Disposable(() => {
if (this.possibleKernelConnection) {
@@ -103,6 +67,11 @@ export class KernelConnectionWrapper implements Kernel.IKernelConnection {
})
);
}
+ abstract shutdown(): Promise;
+ abstract dispose(): void;
+ abstract interrupt(): Promise;
+ abstract restart(): Promise;
+
public get id(): string {
return (this.possibleKernelConnection || this._previousKernelConnection).id;
}
@@ -110,7 +79,7 @@ export class KernelConnectionWrapper implements Kernel.IKernelConnection {
return (this.possibleKernelConnection || this._previousKernelConnection).name;
}
public get isDisposed(): boolean {
- return this.kernel.disposed;
+ return this.possibleKernelConnection ? this.possibleKernelConnection?.isDisposed === true : true;
}
public get model(): Kernel.IModel {
@@ -233,55 +202,18 @@ export class KernelConnectionWrapper implements Kernel.IKernelConnection {
): void {
return this.getKernelConnection().removeMessageHook(msgId, hook);
}
- async shutdown(): Promise {
- if (
- this.kernel.kernelConnectionMetadata.kind === 'startUsingRemoteKernelSpec' ||
- this.kernel.kernelConnectionMetadata.kind === 'connectToLiveRemoteKernel'
- ) {
- await this.kernel.session?.shutdown();
- }
- await this.kernel.dispose();
- }
+
clone(
_options?: Pick
): Kernel.IKernelConnection {
throw new Error('Method not implemented.');
}
- dispose(): void {
- this.kernel.dispose().catch(noop);
- }
- async interrupt(): Promise {
- // Sometimes we end up starting a new session.
- // Hence assume a new session was created, meaning we need to bind to the kernel connection all over again.
- this.stopHandlingKernelMessages(this.possibleKernelConnection!);
-
- await this.kernel.interrupt();
-
- if (!this.kernel.session?.kernel) {
- throw new Error('Restart failed');
- }
- this.startHandleKernelMessages(this.kernel.session?.kernel);
- }
- async restart(): Promise {
- if (this.possibleKernelConnection) {
- this.stopHandlingKernelMessages(this.possibleKernelConnection);
- }
-
- // If this is a remote, then we do something special.
- await this.kernel.restart();
-
- if (!this.kernel.session?.kernel) {
- throw new Error('Restart failed');
- }
- this.startHandleKernelMessages(this.kernel.session?.kernel);
- }
- private startHandleKernelMessages(kernelConnection: Kernel.IKernelConnection) {
- this._kernelConnection = kernelConnection;
+ protected startHandleKernelMessages(kernelConnection: Kernel.IKernelConnection) {
kernelConnection.anyMessage.connect(this.onAnyMessage, this);
kernelConnection.iopubMessage.connect(this.onIOPubMessage, this);
kernelConnection.unhandledMessage.connect(this.onUnhandledMessage, this);
}
- private stopHandlingKernelMessages(kernelConnection: Kernel.IKernelConnection) {
+ protected stopHandlingKernelMessages(kernelConnection: Kernel.IKernelConnection) {
kernelConnection.anyMessage.disconnect(this.onAnyMessage, this);
kernelConnection.iopubMessage.disconnect(this.onIOPubMessage, this);
kernelConnection.unhandledMessage.disconnect(this.onUnhandledMessage, this);
diff --git a/src/kernels/jupyter/session/jupyterSession.ts b/src/kernels/jupyter/session/jupyterSession.ts
index 375a85277d9f..93940918d5ef 100644
--- a/src/kernels/jupyter/session/jupyterSession.ts
+++ b/src/kernels/jupyter/session/jupyterSession.ts
@@ -1,14 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
'use strict';
-import type {
- Contents,
- ContentsManager,
- Kernel,
- KernelSpecManager,
- Session,
- SessionManager
-} from '@jupyterlab/services';
+import type { Contents, ContentsManager, KernelSpecManager, Session, SessionManager } from '@jupyterlab/services';
import * as uuid from 'uuid/v4';
import { CancellationToken, CancellationTokenSource } from 'vscode-jsonrpc';
import { Cancellation } from '../../../platform/common/cancellation';
@@ -76,15 +69,6 @@ export class JupyterSession extends BaseJupyterSession implements IJupyterServer
// Wait for idle on this session
return this.waitForIdleOnSession(this.session, timeout);
}
-
- public override get kernel(): Kernel.IKernelConnection | undefined {
- return this.session?.kernel || undefined;
- }
-
- public get kernelId(): string {
- return this.session?.kernel?.id || '';
- }
-
public async connect(options: { token: CancellationToken; ui: IDisplayOptions }): Promise {
// Start a new session
this.setSession(await this.createNewKernelSession(options));
@@ -158,7 +142,6 @@ export class JupyterSession extends BaseJupyterSession implements IJupyterServer
return newSession;
}
-
protected async createRestartSession(
disableUI: boolean,
session: ISessionWithSocket,
diff --git a/src/kernels/raw/session/rawJupyterSession.node.ts b/src/kernels/raw/session/rawJupyterSession.node.ts
index 5eab7f33b163..4afc7237b31c 100644
--- a/src/kernels/raw/session/rawJupyterSession.node.ts
+++ b/src/kernels/raw/session/rawJupyterSession.node.ts
@@ -51,9 +51,6 @@ export class RawJupyterSession extends BaseJupyterSession {
}
return super.status;
}
- public get kernelId(): string {
- return this.session?.kernel?.id || '';
- }
constructor(
private readonly kernelLauncher: IKernelLauncher,
resource: Resource,
diff --git a/src/kernels/raw/session/rawKernel.node.ts b/src/kernels/raw/session/rawKernel.node.ts
index 4df68ec1e051..67cf1d42532b 100644
--- a/src/kernels/raw/session/rawKernel.node.ts
+++ b/src/kernels/raw/session/rawKernel.node.ts
@@ -276,9 +276,14 @@ export function createRawKernel(kernelProcess: IKernelProcess, clientId: string)
// Dummy websocket we give to the underlying real kernel
let socketInstance: any;
+ let rawKernel: RawKernel;
class RawSocketWrapper extends RawSocket {
constructor() {
- super(kernelProcess.connection, jupyterLabSerialize.serialize, jupyterLabSerialize.deserialize);
+ super(kernelProcess.connection, jupyterLabSerialize.serialize, jupyterLabSerialize.deserialize, (msg) => {
+ if (rawKernel) {
+ rawKernel?.anyMessage.emit({ direction: 'send', msg });
+ }
+ });
socketInstance = this;
}
}
@@ -309,5 +314,6 @@ export function createRawKernel(kernelProcess: IKernelProcess, clientId: string)
});
// Use this real kernel in result.
- return new RawKernel(realKernel, socketInstance, kernelProcess);
+ rawKernel = new RawKernel(realKernel, socketInstance, kernelProcess);
+ return rawKernel;
}
diff --git a/src/kernels/raw/session/rawSocket.node.ts b/src/kernels/raw/session/rawSocket.node.ts
index b5b2d1a424e5..f7d1bdeae4e5 100644
--- a/src/kernels/raw/session/rawSocket.node.ts
+++ b/src/kernels/raw/session/rawSocket.node.ts
@@ -48,7 +48,8 @@ export class RawSocket implements IWebSocketLike, IKernelSocket, IDisposable {
constructor(
private connection: IKernelConnection,
private serialize: (msg: KernelMessage.IMessage) => string | ArrayBuffer,
- private deserialize: (data: ArrayBuffer | string) => KernelMessage.IMessage
+ private deserialize: (data: ArrayBuffer | string) => KernelMessage.IMessage,
+ private readonly onAnyMessage: (msg: KernelMessage.IMessage) => void
) {
// Setup our ZMQ channels now
this.channels = this.generateChannels(connection);
@@ -100,7 +101,7 @@ export class RawSocket implements IWebSocketLike, IKernelSocket, IDisposable {
// If from ipywidgets, this will be serialized already, so turn it back into a message so
// we can add the special hash to it.
const message = this.deserialize(data);
-
+ this.onAnyMessage(message as any);
// Send this directly (don't call back into the hooks)
this.sendMessage(message, true);
}
diff --git a/src/kernels/types.ts b/src/kernels/types.ts
index 2cc1c569c460..63296d00b8fd 100644
--- a/src/kernels/types.ts
+++ b/src/kernels/types.ts
@@ -266,7 +266,6 @@ export interface IJupyterSession extends IAsyncDisposable {
isServerSession(): this is IJupyterServerSession;
onSessionStatusChanged: Event;
onDidDispose: Event;
- onIOPubMessage: Event;
interrupt(): Promise;
restart(): Promise;
waitForIdle(timeout: number): Promise;
diff --git a/src/platform/api/kernelApi.ts b/src/platform/api/kernelApi.ts
index 60be576b92d7..eb8ffa3fbe71 100644
--- a/src/platform/api/kernelApi.ts
+++ b/src/platform/api/kernelApi.ts
@@ -3,7 +3,7 @@
import { injectable, inject } from 'inversify';
import { Disposable, Event, EventEmitter, Uri } from 'vscode';
-import { KernelConnectionWrapper } from '../../kernels/kernelConnectionWrapper';
+import { KernelConnectionWrapper } from './kernelConnectionWrapper';
import {
IKernelProvider,
IKernel,
diff --git a/src/platform/api/kernelConnectionWrapper.ts b/src/platform/api/kernelConnectionWrapper.ts
new file mode 100644
index 000000000000..826351b68b82
--- /dev/null
+++ b/src/platform/api/kernelConnectionWrapper.ts
@@ -0,0 +1,90 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import type { Kernel } from '@jupyterlab/services';
+import { IDisposable } from '../common/types';
+import { noop } from '../common/utils/misc';
+import { BaseKernelConnectionWrapper } from '../../kernels/jupyter/baseKernelConnectionWrapper';
+import { IKernel } from '../../kernels/types';
+
+export class KernelConnectionWrapper extends BaseKernelConnectionWrapper {
+ /**
+ * Use `kernelConnection` to access the value as its not a constant (can change over time).
+ * E.g. when restarting kernels or the like.
+ */
+ private _kernelConnection!: Kernel.IKernelConnection;
+ protected get possibleKernelConnection(): undefined | Kernel.IKernelConnection {
+ if (this.kernel.session?.kernel === this._kernelConnection) {
+ return this._kernelConnection;
+ }
+ this.stopHandlingKernelMessages(this._kernelConnection);
+ if (this.kernel.session?.kernel) {
+ this.startHandleKernelMessages(this.kernel.session.kernel);
+ return this._kernelConnection;
+ }
+ }
+
+ constructor(readonly kernel: IKernel, disposables: IDisposable[]) {
+ super(kernel.session!.kernel!, disposables);
+ const emiStatusChangeEvents = () => {
+ this.statusChanged.emit(kernel.status);
+ if (kernel.status === 'dead' && !kernel.disposed && !kernel.disposing) {
+ this.connectionStatusChanged.emit('disconnected');
+ }
+ };
+ kernel.onDisposed(
+ () => {
+ // this._isRestarting = false;
+ emiStatusChangeEvents();
+ this.disposed.emit();
+ },
+ this,
+ disposables
+ );
+ kernel.onStarted(emiStatusChangeEvents, this, disposables);
+ kernel.onRestarted(emiStatusChangeEvents, this, disposables);
+ kernel.onStatusChanged(emiStatusChangeEvents, this, disposables);
+ this.startHandleKernelMessages(kernel.session!.kernel!);
+ }
+ async shutdown(): Promise {
+ if (
+ this.kernel.kernelConnectionMetadata.kind === 'startUsingRemoteKernelSpec' ||
+ this.kernel.kernelConnectionMetadata.kind === 'connectToLiveRemoteKernel'
+ ) {
+ await this.kernel.session?.shutdown();
+ }
+ await this.kernel.dispose();
+ }
+ dispose(): void {
+ this.kernel.dispose().catch(noop);
+ }
+ async interrupt(): Promise {
+ // Sometimes we end up starting a new session.
+ // Hence assume a new session was created, meaning we need to bind to the kernel connection all over again.
+ this.stopHandlingKernelMessages(this.possibleKernelConnection!);
+
+ await this.kernel.interrupt();
+
+ if (!this.kernel.session?.kernel) {
+ throw new Error('Restart failed');
+ }
+ this.startHandleKernelMessages(this.kernel.session?.kernel);
+ }
+ async restart(): Promise {
+ if (this.possibleKernelConnection) {
+ this.stopHandlingKernelMessages(this.possibleKernelConnection);
+ }
+
+ // If this is a remote, then we do something special.
+ await this.kernel.restart();
+
+ if (!this.kernel.session?.kernel) {
+ throw new Error('Restart failed');
+ }
+ this.startHandleKernelMessages(this.kernel.session?.kernel);
+ }
+ protected override startHandleKernelMessages(kernelConnection: Kernel.IKernelConnection) {
+ this._kernelConnection = kernelConnection;
+ super.startHandleKernelMessages(kernelConnection);
+ }
+}
diff --git a/src/test/common.node.ts b/src/test/common.node.ts
index 6e27e840ee8d..16bf55135b73 100644
--- a/src/test/common.node.ts
+++ b/src/test/common.node.ts
@@ -9,14 +9,14 @@ import * as fs from 'fs-extra';
import * as path from '../platform/vscode-path/path';
import * as uuid from 'uuid/v4';
import { coerce, SemVer } from 'semver';
-import type { ConfigurationTarget, Event, TextDocument, Uri } from 'vscode';
+import type { ConfigurationTarget, TextDocument, Uri } from 'vscode';
import { IProcessService } from '../platform/common/process/types.node';
-import { IDisposable } from '../platform/common/types';
import { EXTENSION_ROOT_DIR_FOR_TESTS, IS_MULTI_ROOT_TEST, IS_PERF_TEST, IS_SMOKE_TEST } from './constants.node';
import { noop } from './core';
import { isCI } from '../platform/common/constants';
import { IWorkspaceService } from '../platform/common/application/types';
-import { waitForCondition } from './common';
+
+export { createEventHandler } from './common';
const StreamZip = require('node-stream-zip');
@@ -302,87 +302,6 @@ export async function openFile(file: string): Promise {
assert(vscode.window.activeTextEditor, 'No active editor');
return textDocument;
}
-
-/**
- * Helper class to test events.
- *
- * Usage: Assume xyz.onDidSave is the event we want to test.
- * const handler = new TestEventHandler(xyz.onDidSave);
- * // Do something that would trigger the event.
- * assert.ok(handler.fired)
- * assert.equal(handler.first, 'Args Passed to first onDidSave')
- * assert.equal(handler.count, 1)// Only one should have been fired.
- */
-export class TestEventHandler implements IDisposable {
- public get fired() {
- return this.handledEvents.length > 0;
- }
- public get first(): T {
- return this.handledEvents[0];
- }
- public get second(): T {
- return this.handledEvents[1];
- }
- public get last(): T {
- return this.handledEvents[this.handledEvents.length - 1];
- }
- public get count(): number {
- return this.handledEvents.length;
- }
- public get all(): T[] {
- return this.handledEvents;
- }
- private readonly handler: IDisposable;
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- private readonly handledEvents: any[] = [];
- constructor(event: Event, private readonly eventNameForErrorMessages: string, disposables: IDisposable[] = []) {
- disposables.push(this);
- this.handler = event(this.listener, this);
- }
- public reset() {
- while (this.handledEvents.length) {
- this.handledEvents.pop();
- }
- }
- public async assertFired(waitPeriod: number = 100): Promise {
- await waitForCondition(async () => this.fired, waitPeriod, `${this.eventNameForErrorMessages} event not fired`);
- }
- public async assertFiredExactly(numberOfTimesFired: number, waitPeriod: number = 2_000): Promise {
- await waitForCondition(
- async () => this.count === numberOfTimesFired,
- waitPeriod,
- `${this.eventNameForErrorMessages} event fired ${this.count}, expected ${numberOfTimesFired}`
- );
- }
- public async assertFiredAtLeast(numberOfTimesFired: number, waitPeriod: number = 2_000): Promise {
- await waitForCondition(
- async () => this.count >= numberOfTimesFired,
- waitPeriod,
- `${this.eventNameForErrorMessages} event fired ${this.count}, expected at least ${numberOfTimesFired}.`
- );
- }
- public atIndex(index: number): T {
- return this.handledEvents[index];
- }
-
- public dispose() {
- this.handler.dispose();
- }
-
- private listener(e: T) {
- this.handledEvents.push(e);
- }
-}
-
-export function createEventHandler(
- obj: T,
- eventName: K,
- disposables: IDisposable[] = []
-): T[K] extends Event ? TestEventHandler : TestEventHandler {
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- return new TestEventHandler(obj[eventName] as any, eventName as string, disposables) as any;
-}
-
/**
* Captures screenshots (png format) & dumpts into root directory (only on CI).
* If there's a failure, it will be logged (errors are swallowed).
diff --git a/src/test/common.ts b/src/test/common.ts
index 7d829232a1a0..6ad2b82f2dde 100644
--- a/src/test/common.ts
+++ b/src/test/common.ts
@@ -3,7 +3,9 @@
// Licensed under the MIT License.
'use strict';
+import { Event } from 'vscode';
import { IExtensionApi } from '../platform/api';
+import { IDisposable } from '../platform/common/types';
import { IServiceContainer, IServiceManager } from '../platform/ioc/types';
export interface IExtensionTestApi extends IExtensionApi {
@@ -80,3 +82,83 @@ export async function waitForCondition(
pendingTimers.push(timeout);
});
}
+
+/**
+ * Helper class to test events.
+ *
+ * Usage: Assume xyz.onDidSave is the event we want to test.
+ * const handler = new TestEventHandler(xyz.onDidSave);
+ * // Do something that would trigger the event.
+ * assert.ok(handler.fired)
+ * assert.equal(handler.first, 'Args Passed to first onDidSave')
+ * assert.equal(handler.count, 1)// Only one should have been fired.
+ */
+export class TestEventHandler implements IDisposable {
+ public get fired() {
+ return this.handledEvents.length > 0;
+ }
+ public get first(): T {
+ return this.handledEvents[0];
+ }
+ public get second(): T {
+ return this.handledEvents[1];
+ }
+ public get last(): T {
+ return this.handledEvents[this.handledEvents.length - 1];
+ }
+ public get count(): number {
+ return this.handledEvents.length;
+ }
+ public get all(): T[] {
+ return this.handledEvents;
+ }
+ private readonly handler: IDisposable;
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ private readonly handledEvents: any[] = [];
+ constructor(event: Event, private readonly eventNameForErrorMessages: string, disposables: IDisposable[] = []) {
+ disposables.push(this);
+ this.handler = event(this.listener, this);
+ }
+ public reset() {
+ while (this.handledEvents.length) {
+ this.handledEvents.pop();
+ }
+ }
+ public async assertFired(waitPeriod: number = 100): Promise {
+ await waitForCondition(async () => this.fired, waitPeriod, `${this.eventNameForErrorMessages} event not fired`);
+ }
+ public async assertFiredExactly(numberOfTimesFired: number, waitPeriod: number = 2_000): Promise {
+ await waitForCondition(
+ async () => this.count === numberOfTimesFired,
+ waitPeriod,
+ `${this.eventNameForErrorMessages} event fired ${this.count}, expected ${numberOfTimesFired}`
+ );
+ }
+ public async assertFiredAtLeast(numberOfTimesFired: number, waitPeriod: number = 2_000): Promise {
+ await waitForCondition(
+ async () => this.count >= numberOfTimesFired,
+ waitPeriod,
+ `${this.eventNameForErrorMessages} event fired ${this.count}, expected at least ${numberOfTimesFired}.`
+ );
+ }
+ public atIndex(index: number): T {
+ return this.handledEvents[index];
+ }
+
+ public dispose() {
+ this.handler.dispose();
+ }
+
+ private listener(e: T) {
+ this.handledEvents.push(e);
+ }
+}
+
+export function createEventHandler(
+ obj: T,
+ eventName: K,
+ disposables: IDisposable[] = []
+): T[K] extends Event ? TestEventHandler : TestEventHandler {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ return new TestEventHandler(obj[eventName] as any, eventName as string, disposables) as any;
+}
diff --git a/src/test/datascience/notebook/helper.ts b/src/test/datascience/notebook/helper.ts
index b271585210f5..07b1d915a7a5 100644
--- a/src/test/datascience/notebook/helper.ts
+++ b/src/test/datascience/notebook/helper.ts
@@ -239,6 +239,7 @@ export async function createEmptyPythonNotebook(
await waitForKernelToGetAutoSelected();
}
await deleteAllCellsAndWait();
+ return vscodeNotebook.activeNotebookEditor!.notebook;
}
async function shutdownAllNotebooks() {
diff --git a/src/test/datascience/notebook/kernelEvents.vscode.common.ts b/src/test/datascience/notebook/kernelEvents.vscode.common.ts
new file mode 100644
index 000000000000..9f343f4908d1
--- /dev/null
+++ b/src/test/datascience/notebook/kernelEvents.vscode.common.ts
@@ -0,0 +1,172 @@
+/* eslint-disable no-void */
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+'use strict';
+
+/* eslint-disable @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires */
+import { assert } from 'chai';
+import * as sinon from 'sinon';
+import { Disposable, NotebookDocument } from 'vscode';
+import { traceInfo } from '../../../platform/logging';
+import {
+ IConfigurationService,
+ IDisposable,
+ IWatchableJupyterSettings,
+ ReadWrite
+} from '../../../platform/common/types';
+import { IExtensionTestApi, waitForCondition } from '../../common';
+import { initialize } from '../../initialize';
+import {
+ runCell,
+ insertCodeCell,
+ waitForTextOutput,
+ closeNotebooksAndCleanUpAfterTests,
+ createEmptyPythonNotebook
+} from './helper';
+import { createEventHandler } from '../../common';
+import { IKernelProvider } from '../../../kernels/types';
+
+/* eslint-disable @typescript-eslint/no-explicit-any, no-invalid-this */
+export function sharedKernelEventTests(
+ this: Mocha.Suite,
+ options: {
+ startJupyterServer: (notebook?: NotebookDocument) => Promise;
+ }
+) {
+ let api: IExtensionTestApi;
+ const disposables: IDisposable[] = [];
+ let configSettings: ReadWrite;
+ let kernelProvider: IKernelProvider;
+ let previousDisableJupyterAutoStartValue: boolean;
+ this.timeout(120_000);
+ suiteSetup(async function () {
+ traceInfo(`Suite Setup ${this.currentTest?.title}`);
+ this.timeout(120_000);
+ try {
+ api = await initialize();
+ sinon.restore();
+ kernelProvider = api.serviceContainer.get(IKernelProvider);
+ const configService = api.serviceContainer.get(IConfigurationService);
+ configSettings = configService.getSettings(undefined) as any;
+ previousDisableJupyterAutoStartValue = configSettings.disableJupyterAutoStart;
+ configSettings.disableJupyterAutoStart = true;
+ traceInfo('Suite Setup (completed)');
+ } catch (e) {
+ traceInfo('Suite Setup (failed)');
+ throw e;
+ }
+ });
+ // Use same notebook without starting kernel in every single test (use one for whole suite).
+ setup(async function () {
+ try {
+ traceInfo(`Start Test ${this.currentTest?.title}`);
+ sinon.restore();
+ const configService = api.serviceContainer.get(IConfigurationService);
+ configSettings = configService.getSettings(undefined) as any;
+ configSettings.disableJupyterAutoStart = true;
+ await options.startJupyterServer();
+ traceInfo(`Start Test (completed) ${this.currentTest?.title}`);
+ } catch (e) {
+ throw e;
+ }
+ });
+ teardown(async function () {
+ traceInfo(`Ended Test ${this.currentTest?.title}`);
+ await closeNotebooksAndCleanUpAfterTests(disposables);
+ configSettings.disableJupyterAutoStart = previousDisableJupyterAutoStartValue;
+ traceInfo(`Ended Test (completed) ${this.currentTest?.title}`);
+ });
+ suiteTeardown(() => closeNotebooksAndCleanUpAfterTests(disposables));
+ test('Kernel Events', async () => {
+ const kernelCreated = createEventHandler(kernelProvider, 'onDidCreateKernel', disposables);
+ const kernelStarted = createEventHandler(kernelProvider, 'onDidStartKernel', disposables);
+ const kernelDisposed = createEventHandler(kernelProvider, 'onDidDisposeKernel', disposables);
+ const kernelRestarted = createEventHandler(kernelProvider, 'onDidRestartKernel', disposables);
+ const kernelStatusChanged = createEventHandler(kernelProvider, 'onKernelStatusChanged', disposables);
+
+ const nb = await createEmptyPythonNotebook(disposables);
+ await waitForCondition(async () => !!kernelProvider.get(nb.uri), 5_000, 'Kernel not created');
+ const kernel = kernelProvider.get(nb.uri)!;
+ const startedEvent = createEventHandler(kernel, 'onStarted', disposables);
+ const onPreExecuteEvent = createEventHandler(kernel, 'onPreExecute', disposables);
+ const onStatusChangeEvent = createEventHandler(kernel, 'onStatusChanged', disposables);
+ const onDisposed = createEventHandler(kernel, 'onDisposed', disposables);
+ const restartEvent = createEventHandler(kernel, 'onRestarted', disposables);
+
+ const cell = await insertCodeCell('print("cell1")', { index: 0 });
+ await Promise.all([runCell(cell), waitForTextOutput(cell, 'cell1')]);
+
+ assert.isTrue(kernelCreated.fired, 'IKernelProvider.onDidCreateKernel not fired');
+ assert.isTrue(kernelStarted.fired, 'IKernelProvider.onDidStartKernel not fired');
+ assert.isTrue(kernelStatusChanged.fired, 'IKernelProvider.onKernelStatusChanged not fired');
+ assert.isFalse(kernelRestarted.fired, 'IKernelProvider.onDidRestartKernel should not have fired');
+ assert.isFalse(kernelDisposed.fired, 'IKernelProvider.onDidDisposeKernel should not have fired');
+
+ assert.equal(onPreExecuteEvent.first, cell, 'Incorrect cell');
+ assert.isTrue(startedEvent.fired, 'IKernel.onStarted not fired');
+ assert.isTrue(onPreExecuteEvent.fired, 'IKernel.onPreExecute not fired');
+ assert.isTrue(onStatusChangeEvent.fired, 'IKernel.onStatusChanged not fired');
+ assert.isFalse(restartEvent.fired, 'IKernel.onRestarted event should not have fired');
+ assert.isFalse(onDisposed.fired, 'IKernel.onDisposed event should not have fired');
+
+ await kernel.restart();
+ assert.isTrue(restartEvent.fired, 'IKernel.onRestarted event not fired');
+ assert.isFalse(onDisposed.fired, 'IKernel.onDisposed event should not have fired');
+ assert.isTrue(kernelRestarted.fired, 'IKernelProvider.onDidRestartKernel not fired');
+ assert.isFalse(kernelDisposed.fired, 'IKernelProvider.onDidDisposeKernel should not have fired');
+
+ await kernel.dispose();
+ assert.isTrue(onDisposed.fired, 'Disposed event not fired');
+ assert.isTrue(kernelDisposed.fired, 'IKernelProvider.onDidDisposeKernel not fired');
+ });
+ test('Kernel.IKernelConnection Events', async () => {
+ const nb = await createEmptyPythonNotebook(disposables);
+ await waitForCondition(async () => !!kernelProvider.get(nb.uri), 5_000, 'Kernel not created');
+ const kernel = kernelProvider.get(nb.uri)!;
+ const onPreExecuteEvent = createEventHandler(kernel, 'onPreExecute', disposables);
+
+ const cell = await insertCodeCell('print("cell1")', { index: 0 });
+ await Promise.all([runCell(cell), waitForTextOutput(cell, 'cell1')]);
+
+ const kernelConnection = kernelProvider.get(nb.uri)!.session!.kernel!;
+ assert.strictEqual(onPreExecuteEvent.count, 1, 'Pre-execute should be fired once');
+ assert.equal(onPreExecuteEvent.first, cell, 'Incorrect cell');
+
+ let gotAnyMessage = false;
+ let gotIOPubMessage = false;
+ let statusChanged = false;
+ const onAnyMessage = () => (gotAnyMessage = true);
+ const onIOPubMessage = () => (gotIOPubMessage = true);
+ const onStatusChanged = () => (statusChanged = true);
+ kernelConnection.anyMessage.connect(onAnyMessage);
+ kernelConnection.iopubMessage.connect(onIOPubMessage);
+ kernelConnection.statusChanged.connect(onStatusChanged);
+ disposables.push(new Disposable(() => void kernelConnection.anyMessage.disconnect(onAnyMessage)));
+ disposables.push(new Disposable(() => void kernelConnection.iopubMessage.disconnect(onIOPubMessage)));
+ disposables.push(new Disposable(() => void kernelConnection.statusChanged.disconnect(onStatusChanged)));
+
+ const cell2 = await insertCodeCell('print("cell2")', { index: 0 });
+ await Promise.all([runCell(cell2), waitForTextOutput(cell2, 'cell2')]);
+
+ assert.strictEqual(onPreExecuteEvent.count, 2, 'Pre-execute should be fired twice');
+ assert.equal(onPreExecuteEvent.second, cell2, 'Incorrect cell');
+
+ assert.isTrue(gotAnyMessage, 'AnyMessage event not fired');
+ assert.isTrue(gotIOPubMessage, 'IOPubMessage event fired');
+ assert.isTrue(statusChanged, 'StatusChange event fired');
+
+ // Restart the kernel & verify we still get the events fired.
+ gotAnyMessage = false;
+ gotIOPubMessage = false;
+ statusChanged = false;
+ await kernel.restart();
+
+ const cell3 = await insertCodeCell('print("cell3")', { index: 0 });
+ await Promise.all([runCell(cell3), waitForTextOutput(cell3, 'cell3')]);
+
+ assert.isTrue(gotAnyMessage, 'AnyMessage event not fired after restarting the kernel');
+ assert.isTrue(gotIOPubMessage, 'IOPubMessage event fired after restarting the kernel');
+ assert.isTrue(statusChanged, 'StatusChange event fired after restarting the kernel');
+ });
+}
diff --git a/src/test/datascience/notebook/kernelEvents.vscode.test.ts b/src/test/datascience/notebook/kernelEvents.vscode.test.ts
new file mode 100644
index 000000000000..40c5a4dfb1c4
--- /dev/null
+++ b/src/test/datascience/notebook/kernelEvents.vscode.test.ts
@@ -0,0 +1,10 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import { startJupyterServer } from './helper.node';
+import { sharedKernelEventTests } from './kernelEvents.vscode.common';
+
+/* eslint-disable @typescript-eslint/no-explicit-any, no-invalid-this */
+suite('Kernel Events', function () {
+ sharedKernelEventTests.bind(this)({ startJupyterServer });
+});
diff --git a/src/test/datascience/notebook/kernelEvents.vscode.web.test.ts b/src/test/datascience/notebook/kernelEvents.vscode.web.test.ts
new file mode 100644
index 000000000000..e727cd21b328
--- /dev/null
+++ b/src/test/datascience/notebook/kernelEvents.vscode.web.test.ts
@@ -0,0 +1,10 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+import { startJupyterServer } from './helper.web';
+import { sharedKernelEventTests } from './kernelEvents.vscode.common';
+
+/* eslint-disable @typescript-eslint/no-explicit-any, no-invalid-this */
+suite('Kernel Events', function () {
+ sharedKernelEventTests.bind(this)({ startJupyterServer });
+});