-
Notifications
You must be signed in to change notification settings - Fork 92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve runtime session service stability #5380
Conversation
b736859
to
4dc4cbb
Compare
…untime is already starting
…untime is already running
…tart queuing tests
…ame ID in the case of restores
36827f0
to
586b7e1
Compare
|
||
// Avoid unhandled rejections being logged to the console. | ||
// The actual error-handling is in the catch block above. | ||
currentMessagePromise.catch(() => { }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cleaning up some log noise.
|
||
// The Positron preview view icon. | ||
const positronPreviewViewIcon = registerIcon('positron-preview-view-icon', Codicon.positronPreviewView, nls.localize('positronPreviewViewIcon', 'View icon of the Positron preview view.')); | ||
|
||
export const POSITRON_PREVIEW_PLOTS_IN_VIEWER = 'positron.viewer.interactivePlotsInViewer'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needed to move this from browser
to common
to fix failing tests as well as a linting error that must've snuck through a while ago.
session.session.runtimeMetadata.runtimeId === runtimeId && | ||
session.session.metadata.sessionMode === LanguageRuntimeSessionMode.Console && | ||
session.state !== RuntimeState.Exited); | ||
// It's possible that there are multiple consoles for the same runtime, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixes a bug where the old console is returned after a failed restore attempt.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a repo case for that / is that filed? This mitigation is fine but I think we should also ensure we only create one console in that case.
@@ -367,22 +371,29 @@ export class RuntimeSessionService extends Disposable implements IRuntimeSession | |||
session: ILanguageRuntimeSession, exitReason: RuntimeExitReason): Promise<void> { | |||
// We wait for `onDidEndSession()` rather than `RuntimeState.Exited`, because the former | |||
// generates some Console output that must finish before starting up a new runtime: | |||
let disposable: IDisposable | undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixes a leaked disposable if shutting down errors and the session never exits.
`for the ${metadata.languageName} language.`); | ||
} | ||
} | ||
const runningSessionId = this.validateRuntimeSessionStart(sessionMode, languageRuntime, notebookUri, source); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We now also validate that only one runtime is ever running per notebook URI and returning an existing session if it matches.
|
||
// Create a promise that resolves when the runtime is ready to use. | ||
const startPromise = new DeferredPromise<string>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The start promise was previously always created here but now might be created by the caller, and we don't want to overwrite that.
@@ -814,8 +855,7 @@ export class RuntimeSessionService extends Disposable implements IRuntimeSession | |||
`Creating session for language runtime ` + | |||
`${formatLanguageRuntimeMetadata(runtimeMetadata)} failed. Reason: ${err}`); | |||
startPromise.error(err); | |||
this._startingSessionsBySessionMapKey.delete(sessionMapKey); | |||
this._startingConsolesByLanguageId.delete(runtimeMetadata.languageId); | |||
this.clearStartingSessionMaps(sessionMode, runtimeMetadata, notebookUri); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixes a bug where notebooks weren't cleared from the map, and where a starting notebook could affect a starting console.
// Remove the runtime from the starting runtimes. | ||
this._startingConsolesByLanguageId.delete(session.runtimeMetadata.languageId); | ||
this._startingSessionsBySessionMapKey.delete(sessionMapKey); | ||
this.clearStartingSessionMaps( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixes a bug where notebooks weren't cleared from the map, and where a starting notebook could affect a starting console.
if (session.metadata.sessionMode === LanguageRuntimeSessionMode.Console && | ||
!this._consoleSessionsByLanguageId.has(session.runtimeMetadata.languageId)) { | ||
this._consoleSessionsByLanguageId.set(session.runtimeMetadata.languageId, | ||
session); | ||
} else if (session.metadata.sessionMode === LanguageRuntimeSessionMode.Notebook && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixes a bug where notebooks weren't added to the maps after a restart.
@@ -1079,6 +1240,8 @@ export class RuntimeSessionService extends Disposable implements IRuntimeSession | |||
state === RuntimeState.Ready) { | |||
// The runtime looks like it could handle a restart request, so send | |||
// one over. | |||
this.setStartingSessionMaps( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixes a bug where a second console/notebook could be created if done so while the runtime was in the exited state during a restart.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Compiled locally and confirmed tests passing, also spun out a few sessions in a built copy and confirmed that things looked stable.
This LGTM. Thanks so much for improving this and adding some tests.
Before you merge, please run the Full Test Suite on this branch; this code is pretty sensitive due to the amount of async state propagating around.
session.session.runtimeMetadata.runtimeId === runtimeId && | ||
session.session.metadata.sessionMode === LanguageRuntimeSessionMode.Console && | ||
session.state !== RuntimeState.Exited); | ||
// It's possible that there are multiple consoles for the same runtime, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a repo case for that / is that filed? This mitigation is fine but I think we should also ensure we only create one console in that case.
src/vs/workbench/services/runtimeSession/common/runtimeSession.ts
Outdated
Show resolved
Hide resolved
E2E tests passed thrice. Unit tests failed in the first two attempts, fixed in 811cc2f and 25cea7f. All green on the third attempt, so we should be good to merge! Attempt 1: https://github.com/posit-dev/positron/actions/runs/12067290897/attempts/1 Attempt 2: https://github.com/posit-dev/positron/actions/runs/12068410989/attempts/1 Attempt 3: https://github.com/posit-dev/positron/actions/runs/12069245433/attempts/1 |
The aim of this PR is to improve the stability of the runtime session service, with a slight focus on notebooks.
This is another step toward #2671.
I've also added an extensive suite of unit tests for the runtime session service, for two reasons:
Since there are a bunch of changes to some core code, I've annotated them with comments.