Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/notebook/browser/services/notebookExecutionServiceImpl.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { CancellationTokenSource } from '../../../../../base/common/cancellation.js';
7
import { IDisposable, toDisposable } from '../../../../../base/common/lifecycle.js';
8
import * as nls from '../../../../../nls.js';
9
import { ICommandService } from '../../../../../platform/commands/common/commands.js';
10
import { IContextKeyService } from '../../../../../platform/contextkey/common/contextkey.js';
11
import { IWorkspaceTrustRequestService } from '../../../../../platform/workspace/common/workspaceTrust.js';
12
import { KernelPickerMRUStrategy } from '../viewParts/notebookKernelQuickPickStrategy.js';
13
import { NotebookCellTextModel } from '../../common/model/notebookCellTextModel.js';
14
import { CellKind, INotebookTextModel, NotebookCellExecutionState } from '../../common/notebookCommon.js';
15
import { INotebookExecutionService, ICellExecutionParticipant } from '../../common/notebookExecutionService.js';
16
import { INotebookCellExecution, INotebookExecutionStateService } from '../../common/notebookExecutionStateService.js';
17
import { INotebookKernelHistoryService, INotebookKernelService } from '../../common/notebookKernelService.js';
18
import { INotebookLoggingService } from '../../common/notebookLoggingService.js';
19
20
21
export class NotebookExecutionService implements INotebookExecutionService, IDisposable {
22
declare _serviceBrand: undefined;
23
private _activeProxyKernelExecutionToken: CancellationTokenSource | undefined;
24
25
constructor(
26
@ICommandService private readonly _commandService: ICommandService,
27
@INotebookKernelService private readonly _notebookKernelService: INotebookKernelService,
28
@INotebookKernelHistoryService private readonly _notebookKernelHistoryService: INotebookKernelHistoryService,
29
@IWorkspaceTrustRequestService private readonly _workspaceTrustRequestService: IWorkspaceTrustRequestService,
30
@INotebookLoggingService private readonly _logService: INotebookLoggingService,
31
@INotebookExecutionStateService private readonly _notebookExecutionStateService: INotebookExecutionStateService,
32
) {
33
}
34
35
async executeNotebookCells(notebook: INotebookTextModel, cells: Iterable<NotebookCellTextModel>, contextKeyService: IContextKeyService): Promise<void> {
36
const cellsArr = Array.from(cells)
37
.filter(c => c.cellKind === CellKind.Code);
38
if (!cellsArr.length) {
39
return;
40
}
41
42
this._logService.debug(`Execution`, `${JSON.stringify(cellsArr.map(c => c.handle))}`);
43
const message = nls.localize('notebookRunTrust', "Executing a notebook cell will run code from this workspace.");
44
const trust = await this._workspaceTrustRequestService.requestWorkspaceTrust({ message });
45
if (!trust) {
46
return;
47
}
48
49
// create cell executions
50
const cellExecutions: [NotebookCellTextModel, INotebookCellExecution][] = [];
51
for (const cell of cellsArr) {
52
const cellExe = this._notebookExecutionStateService.getCellExecution(cell.uri);
53
if (!!cellExe) {
54
continue;
55
}
56
cellExecutions.push([cell, this._notebookExecutionStateService.createCellExecution(notebook.uri, cell.handle)]);
57
}
58
59
const kernel = await KernelPickerMRUStrategy.resolveKernel(notebook, this._notebookKernelService, this._notebookKernelHistoryService, this._commandService);
60
61
if (!kernel) {
62
// clear all pending cell executions
63
cellExecutions.forEach(cellExe => cellExe[1].complete({}));
64
return;
65
}
66
67
this._notebookKernelHistoryService.addMostRecentKernel(kernel);
68
69
// filter cell executions based on selected kernel
70
const validCellExecutions: INotebookCellExecution[] = [];
71
for (const [cell, cellExecution] of cellExecutions) {
72
if (!kernel.supportedLanguages.includes(cell.language)) {
73
cellExecution.complete({});
74
} else {
75
validCellExecutions.push(cellExecution);
76
}
77
}
78
79
// request execution
80
if (validCellExecutions.length > 0) {
81
await this.runExecutionParticipants(validCellExecutions);
82
83
this._notebookKernelService.selectKernelForNotebook(kernel, notebook);
84
await kernel.executeNotebookCellsRequest(notebook.uri, validCellExecutions.map(c => c.cellHandle));
85
// the connecting state can change before the kernel resolves executeNotebookCellsRequest
86
const unconfirmed = validCellExecutions.filter(exe => exe.state === NotebookCellExecutionState.Unconfirmed);
87
if (unconfirmed.length) {
88
this._logService.debug(`Execution`, `Completing unconfirmed executions ${JSON.stringify(unconfirmed.map(exe => exe.cellHandle))}`);
89
unconfirmed.forEach(exe => exe.complete({}));
90
}
91
this._logService.debug(`Execution`, `Completed executions ${JSON.stringify(validCellExecutions.map(exe => exe.cellHandle))}`);
92
}
93
}
94
95
async cancelNotebookCellHandles(notebook: INotebookTextModel, cells: Iterable<number>): Promise<void> {
96
const cellsArr = Array.from(cells);
97
this._logService.debug(`Execution`, `CancelNotebookCellHandles ${JSON.stringify(cellsArr)}`);
98
const kernel = this._notebookKernelService.getSelectedOrSuggestedKernel(notebook);
99
if (kernel) {
100
await kernel.cancelNotebookCellExecution(notebook.uri, cellsArr);
101
102
}
103
}
104
105
async cancelNotebookCells(notebook: INotebookTextModel, cells: Iterable<NotebookCellTextModel>): Promise<void> {
106
this.cancelNotebookCellHandles(notebook, Array.from(cells, cell => cell.handle));
107
}
108
109
private readonly cellExecutionParticipants = new Set<ICellExecutionParticipant>;
110
111
registerExecutionParticipant(participant: ICellExecutionParticipant) {
112
this.cellExecutionParticipants.add(participant);
113
return toDisposable(() => this.cellExecutionParticipants.delete(participant));
114
}
115
116
private async runExecutionParticipants(executions: INotebookCellExecution[]): Promise<void> {
117
for (const participant of this.cellExecutionParticipants) {
118
await participant.onWillExecuteCell(executions);
119
}
120
return;
121
}
122
123
dispose() {
124
this._activeProxyKernelExecutionToken?.dispose(true);
125
}
126
}
127
128