Create cell execution beforehand (#150410)

This commit is contained in:
Peng Lyu 2022-05-25 17:30:39 -07:00 committed by GitHub
parent 5fca335f5b
commit 12cb993238
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 42 additions and 29 deletions

View file

@ -18,6 +18,7 @@ import { INotebookCellExecution, INotebookExecutionStateService } from 'vs/workb
import { INotebookKernel, INotebookKernelChangeEvent, INotebookKernelService } from 'vs/workbench/contrib/notebook/common/notebookKernelService';
import { SerializableObjectWithBuffers } from 'vs/workbench/services/extensions/common/proxyIdentifier';
import { ExtHostContext, ExtHostNotebookKernelsShape, ICellExecuteUpdateDto, ICellExecutionCompleteDto, INotebookKernelDto2, MainContext, MainThreadNotebookKernelsShape } from '../common/extHost.protocol';
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
abstract class MainThreadKernel implements INotebookKernel {
private readonly _onDidChange = new Emitter<INotebookKernelChangeEvent>();
@ -112,6 +113,7 @@ export class MainThreadNotebookKernels implements MainThreadNotebookKernelsShape
@ILanguageService private readonly _languageService: ILanguageService,
@INotebookKernelService private readonly _notebookKernelService: INotebookKernelService,
@INotebookExecutionStateService private readonly _notebookExecutionStateService: INotebookExecutionStateService,
@INotebookService private readonly _notebookService: INotebookService,
@INotebookEditorService notebookEditorService: INotebookEditorService
) {
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostNotebookKernels);
@ -246,7 +248,16 @@ export class MainThreadNotebookKernels implements MainThreadNotebookKernelsShape
$createExecution(handle: number, controllerId: string, rawUri: UriComponents, cellHandle: number): void {
const uri = URI.revive(rawUri);
const execution = this._notebookExecutionStateService.createCellExecution(controllerId, uri, cellHandle);
const notebook = this._notebookService.getNotebookTextModel(uri);
if (!notebook) {
throw new Error(`Notebook not found: ${uri.toString()}`);
}
const kernel = this._notebookKernelService.getMatchingKernel(notebook);
if (!kernel.selected || kernel.selected.id !== controllerId) {
throw new Error(`Kernel is not selected: ${kernel.selected?.id} !== ${controllerId}`);
}
const execution = this._notebookExecutionStateService.createCellExecution(uri, cellHandle);
execution.confirm();
this._executions.set(handle, execution);
}

View file

@ -13,7 +13,7 @@ import { SELECT_KERNEL_ID } from 'vs/workbench/contrib/notebook/browser/controll
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
import { CellKind, INotebookTextModel, NotebookCellExecutionState } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { INotebookExecutionService } from 'vs/workbench/contrib/notebook/common/notebookExecutionService';
import { INotebookExecutionStateService } from 'vs/workbench/contrib/notebook/common/notebookExecutionStateService';
import { INotebookCellExecution, INotebookExecutionStateService } from 'vs/workbench/contrib/notebook/common/notebookExecutionStateService';
import { INotebookKernel, INotebookKernelService } from 'vs/workbench/contrib/notebook/common/notebookKernelService';
export class NotebookExecutionService implements INotebookExecutionService, IDisposable {
@ -38,6 +38,16 @@ export class NotebookExecutionService implements INotebookExecutionService, IDis
return;
}
// create cell executions
const cellExecutions: [NotebookCellTextModel, INotebookCellExecution][] = [];
for (const cell of cellsArr) {
const cellExe = this._notebookExecutionStateService.getCellExecution(cell.uri);
if (cell.cellKind !== CellKind.Code || !!cellExe) {
continue;
}
cellExecutions.push([cell, this._notebookExecutionStateService.createCellExecution(notebook.uri, cell.handle)]);
}
let kernel = this._notebookKernelService.getSelectedOrSuggestedKernel(notebook);
if (!kernel) {
kernel = await this.resolveSourceActions(notebook);
@ -49,28 +59,27 @@ export class NotebookExecutionService implements INotebookExecutionService, IDis
}
if (!kernel) {
// clear all pending cell executions
cellExecutions.forEach(cellExe => cellExe[1].complete({}));
return;
}
const executeCells: NotebookCellTextModel[] = [];
for (const cell of cellsArr) {
const cellExe = this._notebookExecutionStateService.getCellExecution(cell.uri);
if (cell.cellKind !== CellKind.Code || !!cellExe) {
continue;
}
// filter cell executions based on selected kernel
const validCellExecutions: INotebookCellExecution[] = [];
for (const [cell, cellExecution] of cellExecutions) {
if (!kernel.supportedLanguages.includes(cell.language)) {
continue;
cellExecution.complete({});
} else {
validCellExecutions.push(cellExecution);
}
executeCells.push(cell);
}
if (executeCells.length > 0) {
// request execution
if (validCellExecutions.length > 0) {
this._notebookKernelService.selectKernelForNotebook(kernel, notebook);
const exes = executeCells.map(c => this._notebookExecutionStateService.createCellExecution(kernel!.id, notebook.uri, c.handle));
await kernel.executeNotebookCellsRequest(notebook.uri, executeCells.map(c => c.handle));
await kernel.executeNotebookCellsRequest(notebook.uri, validCellExecutions.map(c => c.cellHandle));
// the connecting state can change before the kernel resolves executeNotebookCellsRequest
const unconfirmed = exes.filter(exe => exe.state === NotebookCellExecutionState.Unconfirmed);
const unconfirmed = validCellExecutions.filter(exe => exe.state === NotebookCellExecutionState.Unconfirmed);
if (unconfirmed.length) {
this._logService.debug(`NotebookExecutionService#executeNotebookCells completing unconfirmed executions ${JSON.stringify(unconfirmed.map(exe => exe.cellHandle))}`);
unconfirmed.forEach(exe => exe.complete({}));

View file

@ -14,7 +14,6 @@ import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/no
import { CellEditType, CellUri, ICellEditOperation, NotebookCellExecutionState, NotebookCellInternalMetadata, NotebookTextModelWillAddRemoveEvent } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellExecutionUpdateType, INotebookExecutionService } from 'vs/workbench/contrib/notebook/common/notebookExecutionService';
import { ICellExecuteUpdate, ICellExecutionComplete, ICellExecutionStateChangedEvent, ICellExecutionStateUpdate, INotebookCellExecution, INotebookExecutionStateService } from 'vs/workbench/contrib/notebook/common/notebookExecutionStateService';
import { INotebookKernelService } from 'vs/workbench/contrib/notebook/common/notebookKernelService';
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
export class NotebookExecutionStateService extends Disposable implements INotebookExecutionStateService {
@ -28,7 +27,6 @@ export class NotebookExecutionStateService extends Disposable implements INotebo
onDidChangeCellExecution = this._onDidChangeCellExecution.event;
constructor(
@INotebookKernelService private readonly _notebookKernelService: INotebookKernelService,
@IInstantiationService private readonly _instantiationService: IInstantiationService,
@ILogService private readonly _logService: ILogService,
@INotebookService private readonly _notebookService: INotebookService,
@ -91,17 +89,12 @@ export class NotebookExecutionStateService extends Disposable implements INotebo
this._onDidChangeCellExecution.fire(new NotebookExecutionEvent(notebookUri, cellHandle));
}
createCellExecution(controllerId: string, notebookUri: URI, cellHandle: number): INotebookCellExecution {
createCellExecution(notebookUri: URI, cellHandle: number): INotebookCellExecution {
const notebook = this._notebookService.getNotebookTextModel(notebookUri);
if (!notebook) {
throw new Error(`Notebook not found: ${notebookUri.toString()}`);
}
const kernel = this._notebookKernelService.getMatchingKernel(notebook);
if (!kernel.selected || kernel.selected.id !== controllerId) {
throw new Error(`Kernel is not selected: ${kernel.selected?.id} !== ${controllerId}`);
}
let notebookExecutionMap = this._executions.get(notebookUri);
if (!notebookExecutionMap) {
const listeners = this._instantiationService.createInstance(NotebookExecutionListeners, notebookUri);

View file

@ -50,7 +50,7 @@ export interface INotebookExecutionStateService {
forceCancelNotebookExecutions(notebookUri: URI): void;
getCellExecutionStatesForNotebook(notebook: URI): INotebookCellExecution[];
getCellExecution(cellUri: URI): INotebookCellExecution | undefined;
createCellExecution(controllerId: string, notebook: URI, cellHandle: number): INotebookCellExecution;
createCellExecution(notebook: URI, cellHandle: number): INotebookCellExecution;
}
export interface INotebookCellExecution {

View file

@ -94,7 +94,7 @@ suite('NotebookExecutionStateService', () => {
const executionStateService: INotebookExecutionStateService = instantiationService.get(INotebookExecutionStateService);
const cell = insertCellAtIndex(viewModel, 0, 'var c = 3', 'javascript', CellKind.Code, {}, [], true, true);
executionStateService.createCellExecution(kernel.id, viewModel.uri, cell.handle);
executionStateService.createCellExecution(viewModel.uri, cell.handle);
assert.strictEqual(didCancel, false);
viewModel.notebookDocument.applyEdits([{
editType: CellEditType.Replace, index: 0, count: 1, cells: []
@ -113,7 +113,7 @@ suite('NotebookExecutionStateService', () => {
const executionStateService: INotebookExecutionStateService = instantiationService.get(INotebookExecutionStateService);
const cell = insertCellAtIndex(viewModel, 0, 'var c = 3', 'javascript', CellKind.Code, {}, [], true, true);
const exe = executionStateService.createCellExecution(kernel.id, viewModel.uri, cell.handle);
const exe = executionStateService.createCellExecution(viewModel.uri, cell.handle);
let didFire = false;
disposables.add(executionStateService.onDidChangeCellExecution(e => {
@ -154,7 +154,7 @@ suite('NotebookExecutionStateService', () => {
deferred.complete();
}));
executionStateService.createCellExecution(kernel.id, viewModel.uri, cell.handle);
executionStateService.createCellExecution(viewModel.uri, cell.handle);
return deferred.p;
});
@ -170,7 +170,7 @@ suite('NotebookExecutionStateService', () => {
const executionStateService: INotebookExecutionStateService = instantiationService.get(INotebookExecutionStateService);
const cell = insertCellAtIndex(viewModel, 0, 'var c = 3', 'javascript', CellKind.Code, {}, [], true, true);
executionStateService.createCellExecution(kernel.id, viewModel.uri, cell.handle);
executionStateService.createCellExecution(viewModel.uri, cell.handle);
const exe = executionStateService.getCellExecution(cell.uri);
assert.ok(exe);

View file

@ -422,7 +422,7 @@ class TestNotebookExecutionStateService implements INotebookExecutionStateServic
return this._executions.get(cellUri);
}
createCellExecution(controllerId: string, notebook: URI, cellHandle: number): INotebookCellExecution {
createCellExecution(notebook: URI, cellHandle: number): INotebookCellExecution {
const onComplete = () => this._executions.delete(CellUri.generate(notebook, cellHandle));
const exe = new TestCellExecution(notebook, cellHandle, onComplete);
this._executions.set(CellUri.generate(notebook, cellHandle), exe);