Skip to content

Commit

Permalink
clean up interactive window creation
Browse files Browse the repository at this point in the history
  • Loading branch information
amunger committed Oct 6, 2022
1 parent 48fa7d5 commit 77afeda
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 17 deletions.
3 changes: 0 additions & 3 deletions src/interactive-window/editor-integration/codewatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import {

import { IDocumentManager } from '../../platform/common/application/types';
import { ICellRange, IConfigurationService, IDisposable, Resource } from '../../platform/common/types';
import { chainable } from '../../platform/common/utils/decorators';
import { isUri, noop } from '../../platform/common/utils/misc';
import { capturePerfTelemetry, captureUsageTelemetry } from '../../telemetry';
import { ICodeExecutionHelper } from '../../platform/terminals/types';
Expand Down Expand Up @@ -984,9 +983,7 @@ export class CodeWatcher implements ICodeWatcher {
}
}

@chainable()
private getActiveInteractiveWindow() {
// This should be chained so that a queue forms when getting the interactive window
return this.interactiveWindowProvider.getOrCreate(this.document?.uri);
}
private async addCode(
Expand Down
9 changes: 7 additions & 2 deletions src/interactive-window/interactiveWindow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export class InteractiveWindow implements IInteractiveWindowLoadable {
public get kernelConnectionMetadata(): KernelConnectionMetadata | undefined {
return this.currentKernelInfo.metadata;
}
private initialized = false;
private _onDidChangeViewState = new EventEmitter<void>();
private closedEvent = new EventEmitter<void>();
private _submitters: Uri[] = [];
Expand Down Expand Up @@ -180,7 +181,11 @@ export class InteractiveWindow implements IInteractiveWindowLoadable {
}
}

public start() {
public initialize() {
if (this.initialized) {
return;
}
this.initialized = true;
window.onDidChangeActiveNotebookEditor((e) => {
if (e === this.notebookEditor) {
this._onDidChangeViewState.fire();
Expand Down Expand Up @@ -228,7 +233,7 @@ export class InteractiveWindow implements IInteractiveWindowLoadable {
}
}

this.start();
this.initialize();
}

/**
Expand Down
14 changes: 3 additions & 11 deletions src/interactive-window/interactiveWindowProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import {
Resource,
WORKSPACE_MEMENTO
} from '../platform/common/types';
import { chainable } from '../platform/common/utils/decorators';
import * as localize from '../platform/common/utils/localize';
import { noop } from '../platform/common/utils/misc';
import { IServiceContainer } from '../platform/ioc/types';
Expand Down Expand Up @@ -139,7 +138,6 @@ export class InteractiveWindowProvider
this._updateWindowCache();
}

@chainable()
public async getOrCreate(resource: Resource, connection?: KernelConnectionMetadata): Promise<IInteractiveWindow> {
if (!this.workspaceService.isTrusted) {
// This should not happen, but if it does, then just throw an error.
Expand All @@ -160,8 +158,8 @@ export class InteractiveWindowProvider
if (!result) {
// No match. Create a new item.
result = await this.create(resource, mode, connection);
// start the kernel
result.start();
// ensure events are wired up and kernel is started.
result.initialize();
} else {
const preferredController = connection
? this.controllerRegistration.get(connection, InteractiveWindowView)
Expand All @@ -186,17 +184,11 @@ export class InteractiveWindowProvider
return noop();
}

// Note to future devs: this function must be synchronous. Do not await on anything before calling
// the interactive window ctor and adding the interactive window to the provider's list of known windows.
// Otherwise we risk a race condition where e.g. multiple run cell requests come in quick and we end up
// instantiating multiples.
private async create(resource: Resource, mode: InteractiveWindowMode, connection?: KernelConnectionMetadata) {
// track when a creation is pending, so consumers can wait before checking for an existing one.
const creationInProgress = createDeferred<void>();
// Ensure we don't end up calling this method multiple times when creating an IW for the same resource.
this.pendingCreations.push(creationInProgress.promise);
try {
// Set it as soon as we create it. The .ctor for the interactive window
// may cause a subclass to talk to the IInteractiveWindowProvider to get the active interactive window.
// Find our preferred controller
const preferredController = connection
? this.controllerRegistration.get(connection, InteractiveWindowView)
Expand Down
2 changes: 1 addition & 1 deletion src/interactive-window/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export interface IInteractiveWindow extends IInteractiveBase {
readonly inputUri?: Uri;
readonly notebookDocument?: NotebookDocument;
closed: Event<void>;
start(): void;
initialize(): void;
restore(preferredController: IVSCodeNotebookController | undefined): Promise<void>;
addCode(code: string, file: Uri, line: number): Promise<boolean>;
addErrorMessage(message: string, cell: NotebookCell): Promise<void>;
Expand Down

0 comments on commit 77afeda

Please sign in to comment.