Path: blob/main/src/vs/workbench/contrib/notebook/browser/services/notebookExecutionServiceImpl.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { CancellationTokenSource } from '../../../../../base/common/cancellation.js';6import { IDisposable, toDisposable } from '../../../../../base/common/lifecycle.js';7import * as nls from '../../../../../nls.js';8import { ICommandService } from '../../../../../platform/commands/common/commands.js';9import { IContextKeyService } from '../../../../../platform/contextkey/common/contextkey.js';10import { IWorkspaceTrustRequestService } from '../../../../../platform/workspace/common/workspaceTrust.js';11import { KernelPickerMRUStrategy } from '../viewParts/notebookKernelQuickPickStrategy.js';12import { NotebookCellTextModel } from '../../common/model/notebookCellTextModel.js';13import { CellKind, INotebookTextModel, NotebookCellExecutionState } from '../../common/notebookCommon.js';14import { INotebookExecutionService, ICellExecutionParticipant } from '../../common/notebookExecutionService.js';15import { INotebookCellExecution, INotebookExecutionStateService } from '../../common/notebookExecutionStateService.js';16import { INotebookKernelHistoryService, INotebookKernelService } from '../../common/notebookKernelService.js';17import { INotebookLoggingService } from '../../common/notebookLoggingService.js';181920export class NotebookExecutionService implements INotebookExecutionService, IDisposable {21declare _serviceBrand: undefined;22private _activeProxyKernelExecutionToken: CancellationTokenSource | undefined;2324constructor(25@ICommandService private readonly _commandService: ICommandService,26@INotebookKernelService private readonly _notebookKernelService: INotebookKernelService,27@INotebookKernelHistoryService private readonly _notebookKernelHistoryService: INotebookKernelHistoryService,28@IWorkspaceTrustRequestService private readonly _workspaceTrustRequestService: IWorkspaceTrustRequestService,29@INotebookLoggingService private readonly _logService: INotebookLoggingService,30@INotebookExecutionStateService private readonly _notebookExecutionStateService: INotebookExecutionStateService,31) {32}3334async executeNotebookCells(notebook: INotebookTextModel, cells: Iterable<NotebookCellTextModel>, contextKeyService: IContextKeyService): Promise<void> {35const cellsArr = Array.from(cells)36.filter(c => c.cellKind === CellKind.Code);37if (!cellsArr.length) {38return;39}4041this._logService.debug(`Execution`, `${JSON.stringify(cellsArr.map(c => c.handle))}`);42const message = nls.localize('notebookRunTrust', "Executing a notebook cell will run code from this workspace.");43const trust = await this._workspaceTrustRequestService.requestWorkspaceTrust({ message });44if (!trust) {45return;46}4748// create cell executions49const cellExecutions: [NotebookCellTextModel, INotebookCellExecution][] = [];50for (const cell of cellsArr) {51const cellExe = this._notebookExecutionStateService.getCellExecution(cell.uri);52if (!!cellExe) {53continue;54}55cellExecutions.push([cell, this._notebookExecutionStateService.createCellExecution(notebook.uri, cell.handle)]);56}5758const kernel = await KernelPickerMRUStrategy.resolveKernel(notebook, this._notebookKernelService, this._notebookKernelHistoryService, this._commandService);5960if (!kernel) {61// clear all pending cell executions62cellExecutions.forEach(cellExe => cellExe[1].complete({}));63return;64}6566this._notebookKernelHistoryService.addMostRecentKernel(kernel);6768// filter cell executions based on selected kernel69const validCellExecutions: INotebookCellExecution[] = [];70for (const [cell, cellExecution] of cellExecutions) {71if (!kernel.supportedLanguages.includes(cell.language)) {72cellExecution.complete({});73} else {74validCellExecutions.push(cellExecution);75}76}7778// request execution79if (validCellExecutions.length > 0) {80await this.runExecutionParticipants(validCellExecutions);8182this._notebookKernelService.selectKernelForNotebook(kernel, notebook);83await kernel.executeNotebookCellsRequest(notebook.uri, validCellExecutions.map(c => c.cellHandle));84// the connecting state can change before the kernel resolves executeNotebookCellsRequest85const unconfirmed = validCellExecutions.filter(exe => exe.state === NotebookCellExecutionState.Unconfirmed);86if (unconfirmed.length) {87this._logService.debug(`Execution`, `Completing unconfirmed executions ${JSON.stringify(unconfirmed.map(exe => exe.cellHandle))}`);88unconfirmed.forEach(exe => exe.complete({}));89}90this._logService.debug(`Execution`, `Completed executions ${JSON.stringify(validCellExecutions.map(exe => exe.cellHandle))}`);91}92}9394async cancelNotebookCellHandles(notebook: INotebookTextModel, cells: Iterable<number>): Promise<void> {95const cellsArr = Array.from(cells);96this._logService.debug(`Execution`, `CancelNotebookCellHandles ${JSON.stringify(cellsArr)}`);97const kernel = this._notebookKernelService.getSelectedOrSuggestedKernel(notebook);98if (kernel) {99await kernel.cancelNotebookCellExecution(notebook.uri, cellsArr);100101}102}103104async cancelNotebookCells(notebook: INotebookTextModel, cells: Iterable<NotebookCellTextModel>): Promise<void> {105this.cancelNotebookCellHandles(notebook, Array.from(cells, cell => cell.handle));106}107108private readonly cellExecutionParticipants = new Set<ICellExecutionParticipant>;109110registerExecutionParticipant(participant: ICellExecutionParticipant) {111this.cellExecutionParticipants.add(participant);112return toDisposable(() => this.cellExecutionParticipants.delete(participant));113}114115private async runExecutionParticipants(executions: INotebookCellExecution[]): Promise<void> {116for (const participant of this.cellExecutionParticipants) {117await participant.onWillExecuteCell(executions);118}119return;120}121122dispose() {123this._activeProxyKernelExecutionToken?.dispose(true);124}125}126127128